パーzancoの答え、あなたは、リモートコマンドを提供していないsshシェルはコマンドラインを解析する方法与えられ、。この問題を解決するには、sshコマンド呼び出しの構文を変更して、リモートコマンドが構文的に正しい複数行の文字列で構成されるようにします。
使用できるさまざまな構文があります。コマンドはにパイプすることができますので、例えば、bashそしてshあまりにも、そしておそらく他のシェル、最も簡単な解決策は、単に組み合わせることであるsshヒアドキュメントとシェル呼び出しを:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
上記を実行せず /bin/bashに警告が発生することに注意してくださいPseudo-terminal will not be allocated because stdin is not a terminal。また、EOTは単一引用符で囲まれているためbash、ヒアドキュメントをnowdocとして認識し、ローカル変数の補間をオフにして、コマンドテキストがそのまま渡されるようにします。sshます。
パイプのファンなら、上記を次のように書き換えることができます。
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
上記と同じ警告が/bin/bash適用されます。
別の有効なアプローチはbash、次のように変数補間の複数のレイヤーを使用して、複数行のリモートコマンドを単一の文字列として渡すことです。
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
上記のソリューションは、この問題を次のように修正します。
ssh user@serverバッシュによって解析され、そしてあると解釈されるsshコマンド、引数が続くuser@serverに渡されるsshコマンド
"補間された文字列を開始します。これは、完了すると、sshコマンドに渡される引数を構成します。この場合、引数は、によってssh実行されるリモートコマンドであると解釈されます。user@server
$( 実行されるコマンドを開始し、出力は周囲の補間された文字列によってキャプチャされます
cat後に続くファイルの内容を出力するコマンドです。の出力はcat、キャプチャされた補間文字列に戻されます。
<<bashのヒアドキュメントを始める
'EOT'ヒアドキュメントの名前がEOTであることを指定します。'EOTを囲む単一引用符は、ヒアドキュメントをnowdocとして解析する必要があることを指定します。これは、内容がbashによって補間されず、リテラル形式で渡される、ヒアドキュメントの特別な形式です。
間<<'EOT'で遭遇<newline>EOT<newline>し、nowdoc出力に追加されるコンテンツ
EOTnowdocを終了します。その結果、nowdoc一時ファイルが作成され、呼び出しcatコマンドに渡されます。catnowdocを出力し、出力をキャプチャーされた補間文字列に渡します
) 実行するコマンドを終了します
"キャプチャされた補間文字列を終了します。補間された文字列の内容は、ssh単一のコマンドライン引数として渡されます。これsshは、次のように実行されるリモートコマンドとして解釈されます。user@server
のような外部ツールの使用を回避する必要がありcat、1つではなく2つのステートメントを使用してもかまわない場合は、read組み込みのheredocを使用してSSHコマンドを生成します。
IFS='' read -r -d '' SSH_COMMAND <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
ssh user@server "${SSH_COMMAND}"
ssh user@server /bin/bash <<EOT…