sshシェルで変数をエクスポートすると、エクスポートされた変数のリストが表示されるのはなぜですか?


17

このことを考慮:

$ 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"

bash -cセッション内の変数をssh経由で実行すると、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マシンから別のUbuntuマシン(bash 4.3.11を実行している両方)に、またArchマシンで、上記のように自分自身にスッシング(bashバージョン4.4.5)します。

何が起きてる?bash -c呼び出し内で変数をエクスポートすると、なぜこの出力が生成されるのですか?


これは質問に答えませんが、出力は実行の結果ですexport。Zshも同じことをします。
スティーブンキット

@StephenKittはい、私はそれが知っています、私はexport何が起こっているのか理解しようとしています。これは、エクスポート時にのみ発生することを明確にするために編集します。
テルドン

ああ、私は「私が知る限り、現在エクスポートされている変数のリスト」を読んだでしょう。これは、出力がどこから来たのかわからなかったことを意味します。
スティーブンキット

@StephenKitt エクスポートされたすべての変数なのか、特定のサブセットなのか、それとも何なのかはわかりません。ああ!それはexportrun alone の出力だということですか?私が理解していなかったこと。
テルドン

foo=barリストに表示されないことに注意してください。
デルタブ

回答:


31

を介してコマンドを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'"

9

ssh 引数をスペースで連結し、リモートユーザーのログインシェルにそれを解釈させます。

ssh localhost bash -c 'export foo=bar'

ssh リモートシェルに解釈するように依頼しています

bash -c export foo=bar

コマンド(実質的に、リモートホストがUnixライクの場合、引数としてthe-shell-cおよびbash -c export foo=barを使用してリモートシェルを実行します)。

ほとんどのシェルは実行されているように、そのコマンドラインを解釈するbashと、コマンドをbash-cexportfoo=barの引数として(これを実行exportしながら、$0含まれていfoo=barますが、それはでそれを実行したいと思いながら)bash-cおよびexport foo=bar引数として。

そのためには、次のようなコマンドラインを使用する必要があります。

ssh localhost "bash -c 'export foo=bar'"

(または:

ssh localhost bash -c \'export foo=bar\'

そのため)):

bash -c 'export foo=bar'

コマンドラインはリモートシェルに渡されます。そのコマンドラインは、ほとんどのシェルで、bashコマンドをbash-cおよびexport foo=bar引数として実行していると解釈されます。使用することに注意してください

ssh localhost 'bash -c "export foo=bar"'

リモートユーザーのログインシェルが、rcまたは特別な引用演算子es"はない場合は機能しません。単一引用符は、最も移植性の高い引用演算子です(シェル間での解釈方法には多少の違いがありますが、詳細については、リモートユーザーのログインシェルを知らずにsshで任意の単純なコマンドを実行する方法を参照してください)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.