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

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

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

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に似ていると仮定されます。)

おすすめ記事