考えてみてください:
$ ssh localhost bash -c 'export foo=bar'
terdon@localhost's password:
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
declare -x HOME="/home/terdon"
declare -x LOGNAME="terdon"
declare -x MAIL="/var/spool/mail/terdon"
declare -x OLDPWD
declare -x PATH="/usr/bin:/bin:/usr/sbin:/sbin"
declare -x PWD="/home/terdon"
declare -x SHELL="/bin/bash"
declare -x SHLVL="2"
declare -x SSH_CLIENT="::1 55858 22"
declare -x SSH_CONNECTION="::1 55858 ::1 22"
declare -x USER="terdon"
declare -x XDG_RUNTIME_DIR="/run/user/1000"
declare -x XDG_SESSION_ID="c5"
declare -x _="/usr/bin/bash"
SSHを介して実行されているセッションから変数をエクスポートすると、bash -c
このコマンドのリストdeclare -x
(私が知っている限り、現在エクスポートされた変数のリスト)が生成されるのはなぜですか?
以下なしで同じタスクを実行しますbash -c
。
$ ssh localhost 'export foo=bar'
terdon@localhost's password:
$
私たちがこれをしなければ、それも起こらないでしょうexport
:
$ ssh localhost bash -c 'foo=bar'
terdon@localhost's password:
$
私は1つのUbuntuシステムから別のシステムにsshingを介して(両方ともbash 4.3.11を実行)、Archシステムでは上記のように独自にsshingを介して(bashバージョン4.4.5)これをテストしました。
ここで何が起こっているのでしょうか?呼び出し時に変数をエクスポートすると、bash -c
この出力が生成されるのはなぜですか?
ベストアンサー1
コマンドを実行すると、ssh
次のフラグを使用して呼び出して$SHELL
実行されます-c
。
-c If the -c option is present, then commands are read from
the first non-option argument command_string. If there are
arguments after the command_string, the first argument is
assigned to $0 and any remaining arguments are assigned to
the positional parameters.
したがって、ssh remote_host "bash -c foo"
実際には以下が実行されます。
/bin/your_shell -c 'bash -c foo'
これで、実行中のコマンド(export foo=bar
)にスペースが含まれており、全体を形成するために正しく引用されていないため、export
実行中のコマンドとして処理され、残りは位置引数配列に格納されます。これはexport
実行されてfoo=bar
に渡されたことを意味します$0
。最終結果は実行と同じです。
/bin/your_shell -c 'bash -c export'
正しいコマンドは次のとおりです。
ssh remote_host "bash -c 'export foo=bar'"