ローカル入力ファイルを使用してリモートホストでローカルスクリプトを実行する

ローカル入力ファイルを使用してリモートホストでローカルスクリプトを実行する

複数のリモートサーバーで実行したいローカルスクリプトがあります。私が使用するコマンド構文は次のとおりです。

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_*SendEnvin ssh_configsshd、サーバーがそれを受け入れるとします(AcceptEnvin sshd_config))

または、local_script.shリモートユーザーのログインシェルがこのスクリプト構文の正しい選択であると仮定し、その内容をリモートシェルコードに渡すだけです。

ssh host "$(cat local_script.sh)" < input

または、次のようにコードと入力をsshstdinに接続します。

{
  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であり、$2willの内容はですlocal_file_2.txtbash -sstdinからコマンドを読みます< local_script.sh

関連情報