これの何が悪いのか分かりません。端末で実行してパスワードを入力しても何も起こりませんが、端末ですべてのコマンドを個別に実行すると機能します。ありがとうございました!
#!/bin/bash
Sudo su;
mkdir /opt/D3GO/;
cp `pwd`/D3GO /opt/D3GO/;
cp `pwd`/D3GO.png /opt/D3GO/;
cp `pwd`/D3GO.desktop /usr/share/applications/;
chmod +x /opt/D3GO/D3GO
コマンドSudo su
は対話型のルートシェルを起動しますが、現在のシェルをルートシェルに変換しません。
あなたが望むことをするためのイディオムはこれに沿ったものです(特に注意を払って@CharlesDuffyに感謝します):
#check for root
UID=$(id -u)
if [ x$UID != x0 ]
then
#Beware of how you compose the command
printf -v cmd_str '%q ' "$0" "$@"
exec Sudo su -c "$cmd_str"
fi
#I am root
mkdir /opt/D3GO/
#and the rest of your commands
アイデアは、現在のユーザーがrootであるかどうかを確認し、そうでない場合は、su
を使用して同じコマンドを再実行することです
Here Documents を使用して、対話型シェルスクリプトに入力をリダイレクトできます。オペレーター <<
は、指定された区切り文字を含む行がEOF
(ファイルの終わり)として見つかるまで入力を読み取る命令です。
Sudo su <<EOF
echo "code"
EOF
例えば.
#!/bin/bash
Sudo su <<EOF
mkdir /opt/D3GO/
cp `pwd`/D3GO /opt/D3GO/
cp `pwd`/D3GO.png /opt/D3GO/
cp `pwd`/D3GO.desktop /usr/share/applications/
chmod +x /opt/D3GO/D3GO
EOF
Sudo su
はシェル内で実行されるコマンドではありません新しいシェルを開始します。
新しいシェルはスクリプトを実行しなくなり、スクリプトを実行している古いシェルisは、新しいシェルが終了するのを待ってから続行します。
受け入れられた答え はうまく機能しますが、[オンデマンドでSudo
を使用して自身を再起動するスクリプトのイディオムはsimplifiedおよび作成済みよりポータブル:
[[ $(id -u) -eq 0 ]] || exec Sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
[[ ... ]]
の代わりに[ ... ]
を使用すると、オペランドの前にx
を追加する(またはLHSを二重引用符で囲む)必要がなくなります。
bash -c
の代わりにsu -c
を使用して、再構築されたコマンドラインを解釈すると、すべてのプラットフォームがsu -c
をサポートするわけではないため(たとえば、macOSはサポートしないため)、コマンドの移植性が高まります。
bash
では、通常、$BASH_SOURCE
が実行中のスクリプトを参照するためのより信頼できる方法です。
上記のアプローチでは、引数内の変数参照またはコマンド/算術置換は、常に呼び出しシェルによって展開されます。
代わりにdelay expanded--root user-のコンテキストでSudo
シェルが実行されるまで変数参照が展開されないようにする場合これを使って:
(( __reinvoked )) || exec Sudo -s __reinvoked=1 "$BASH_SOURCE" "$@"
変数参照またはコマンド置換を含む引数を遅延拡張するためには、単一-引用符で囲む必要があることに注意してください。例:'$USER'
。
アドホック環境変数__reinvoked
を使用して、正確に1回だけ再呼び出しできるように注意してください(最初にすでにrootユーザーとして呼び出されている場合でも)。
最初のテクニックを示すサンプルスクリプトは次のとおりです。
Rootとして呼び出されない場合、スクリプトはSudo -s
で自分自身を再度呼び出し、すべての引数をそのまま渡します。
以前に認証されていなくても、タイムアウト期間内であれば、Sudo
は管理者パスワードの入力を求めます。
#!/bin/bash
[[ $(id -u) -eq 0 ]] || exec Sudo /bin/bash -c "$(printf '%q ' "$BASH_SOURCE" "$@")"
# Print the username and all arguments.
echo "Running as: $(id -un)"
echo "Arguments:"
for arg; do echo " $((++i)): [$arg]"; done
acfreitasの役立つ回答"script-inside-a-script"テクニックのデモンストレーションhere-documentは、stdinを介してシェルコードを提供するために使用されますSudo su
。
繰り返しになりますが、Sudo -s
で十分ですおよび引用が重要:
Sudo -s -H <<'EOF'
echo "$HOME"
EOF
文書の内容が先行現在で解釈されないようにするために、ここで開始するヒアドキュメントの区切り文字(この場合はEOF
)がどのように引用符で囲まれていることに注意してください。シェル。EOF
(の一部)を引用しなかった場合、$HOME
はcurrentユーザーのホームディレクトリに展開されます。
ミックス先行展開と遅延展開にする場合は、ここの開始ドキュメントの区切り文字引用符なしを残し、選択的に\
- quote $
インスタンスを残します:
Sudo -s -H <<EOF
echo "Called by: $USER; root's home dir: \$HOME"
EOF
Sudo suはrootとして新しいシェルを起動しようとします。新しいシェルを開くと、新しいシェルを閉じるまで元のスクリプトは続行されません。
修正してみるには:
シェルスクリプトで次を試してください。
su <username> -c "my command"
したがって、ユーザーが「userA」の場合:
su userA -c "mkdir /opt/D3GO/"
ただし、たとえばuserAで、スクリプトの一部をrootとして実行する場合は、パスの入力を求められます。
su root -c "mkdir /opt/D3GO/"
そもそもSudoを使用してスクリプトを実行するだけでも回避できます。
Sudo ./myScript.sh
このようにして、スクリプトはスクリプト内の元のユーザーを保持します。これには、$ {USERNAME}などの標準変数を使用してアクセスできます。 $ {UID}など
何があなたのためにうまくいくかに依存します。
「Sudo su」を実行すると新しいシェルが開き、そのシェルを終了するまでコマンドは返されないためです。おそらく、スクリプトを2つのファイルに分割します。最初のファイルはSudoを実行し、その2番目のスクリプトをSudoの下で実行します。