複数のリモートサーバーで実行したいローカルスクリプトがあります。私が使用するコマンド構文は次のとおりです。
ssh <remote_server> "bash -s" < ./local_script.sh
これはうまく機能し、引数を渡すこともできます。ローカルscript.sh。しかし、私は次のように入力ファイルを渡したいと思います。
local_script.sh < local_file.txt
これら2つの文を組み合わせると、次のような結果が得られます。
ssh <remote_server> "bash -s" < ./local_script.sh < local_file.txt
私がこれを実行すると、私は得ます。
bash: line 1: FOO: command not found
bash: line 2: BAR: command not found
bash: line 3: BAZ: command not found
...
ここで、FOO、BAR、BAZなどは各行の最初の単語です。ローカルファイル.txt:
FOO FOO_PARAM1
BAR BAR_PARAM1
BAZ BAZ_PARAM2
...
だから"bash -s"
リモートサーバーが解釈しているようです。ローカルファイル.txt入力ファイルではなくスクリプトファイルとしてローカルscript.sh。この問題を解決する方法はありますか(ラッパースクリプトを作成することに加えて)?
答え1
2つの独立した出力ストリーム(stdoutとstderr用)が提供されますが、ssh
入力ストリーム(stdin)は1つのみを提供します。したがって、他のメカニズムを介してスクリプトコンテンツと入力ファイルを渡す必要があります。
たとえば、1つは変数を介して、もう1つはstdinを介して:
LC_CODE=$(cat local_script.sh) ssh host 'eval "$LC_CODE"' < input
(ssh
クライアントが変数を渡しLC_*
(SendEnv
in ssh_config
)sshd
、サーバーがそれを受け入れるとします(AcceptEnv
in sshd_config
))
または、local_script.sh
リモートユーザーのログインシェルがこのスクリプト構文の正しい選択であると仮定し、その内容をリモートシェルコードに渡すだけです。
ssh host "$(cat local_script.sh)" < input
または、次のようにコードと入力をssh
stdinに接続します。
{
echo '{'; cat local_script.sh; echo '}; exit'
cat input
} | ssh host 'bash -s some arguments'
ここで使用するbash
と、入力は一度に1バイトずつ読み取られ、他のすべてのシェルはそうでない行bash
よりも読みにくくなります。}; exit
または、sed
リモートホストがGNUの場合sed
:
echo '#END-OF-SCRIPT' | cat local_script.sh - input |
ssh host 'set some arguments; eval "$(sed -u "/^#END-OF-SCRIPT/q")"'
(ここでコードはリモートユーザーのログインシェルによって評価され、Bourneに似ていると仮定されます。)
答え2
BASH 'here-strings'演算子( '<<<')を使用するよりエレガントなソリューションは次のとおりです。
ssh -t host "/bin/bash <(base64 --decode <<<'$(base64 < script)' )"
IT はスクリプトをインポートし、Base64 文字列に変換し、SSH コマンドに戻し、パイプファイル名として bash に渡します。
対話型シェルを構築するスクリプトの場合は、「パイプファイル名」の前に「--rcfile」を追加します。
ssh -t host "/bin/bash --rcfile <(base64 --decode <<<'$(base64 < script)' )"
詳しくは... https://antofthy.gitlab.io/info/apps/ssh_remote_commands.txt
答え3
これはうまく機能し、複数のファイルの内容をスクリプトに渡すこともできます。
ssh host "bash -s -- '$(cat local_file_1.txt)' '$(cat local_file_2.txt)'" < local_script.sh
説明はログイン時にssh
実行され、bash -s
スクリプトパラメータ以降のすべてのエントリは--
。したがって$1
、willの内容はlocal_file_1.txt
であり、$2
willの内容はですlocal_file_2.txt
。bash -s
stdinからコマンドを読みます< local_script.sh
。