これは期待どおりに機能します。
$ sudo -u romain bash -c 'a="b" ; echo $a'
b
$
しかし、-i
変数はエコーされません。なぜですか?
$ sudo -iu romain bash -c 'a="b" ; echo $a'
$
どの程度bash間接参照または変数補間が追加されたのか疑問に思います-i
。それでは、これはどのように機能しますか?
$ sudo -iu romain bash -c 'a="b" ; echo ${a}'
b
$
ベストアンサー1
-i
with を使用すると、sudo
ユーザーのログインシェルが使用され、$SHELL
ログインシェルとして呼び出されます。
次のように実行するコマンドとともにコマンドを追加で提供する場合
sudo -u user -i 'some-command'
...をsudo
使用してコマンドを実行します$SHELL -c
。つまり、引数リストを単一のコマンドライン文字列に変換する必要があり、これはシェルで再評価されます。これを行うには、some-command
英数字、アンダースコア、ハイフン、ドル記号を除くすべての文字をエスケープする必要があります。
これは意味する
sudo -u user -i bash -c 'a="b" ; echo ${a}'
user として実行され、user
次のようにエスケープされます。
$SHELL -c bash\ -c\ \'a\=\"b\"\ \;\ echo\ $\{a\}\'
...使用すると、$a
コマンドは次のようになります。
$SHELL -c bash\ -c\ \'a\=\"b\"\ \;\ echo\ $a\'
最後のコマンドでは、$a
始める前にユーザーのログインシェルが展開されますbash -c
。前のコマンドで${a}
使用されていた場所は$\{a\}
有効な拡張ではないため、ユーザーシェルはそれを拡張しませんが、インラインbash -c
シェルはそれを表示して${a}
拡張できます。
sudo
これについては、オプションを説明するマニュアルセクションに記載されています-i
。
-i, --login
Run the shell specified by the target user's password
database entry as a login shell. This means that login-
specific resource files such as .profile, .bash_profile, or
.login will be read by the shell. If a command is specified,
it is passed to the shell as a simple command using the -c
option. The command and any arguments are concatenated,
separated by spaces, after escaping each character (including
white space) with a backslash (‘\’) except for alphanumerics,
underscores, hyphens, and dollar signs. If no command is
specified, an interactive shell is executed. [...]