リモート ホスト上にプログラムがあり、その実行を自動化する必要があります。同じマシン上でそのプログラムを実行するコマンドは次のようになります。
/path/to/program -a file1.txt -b file2.txt
この場合、file1.txt
と はfile2.txt
プログラム内でまったく異なる目的で使用されているため、cat
これらを一緒に使用することはできません。ただし、私の場合、プログラムに渡したいfile1.txt
と はfile2.txt
デバイス上にのみ存在し、プログラムを実行する必要があるホスト上には存在しません。 を渡すことで、少なくとも 1 つのファイルを SSH 経由で送ることができることはわかっていますstdin
。
cat file1.txt | ssh host.name /path/to/program -a /dev/stdin -b file2.txt
しかし、ホストにファイルを保存することは許可されていないため、ホストにファイルを保存する方法も必要です。環境変数を悪用し、とを組み合わせfile2.txt
て創造的に使用することで可能になるのではないかと考えていますが、ツールを十分に理解していないため、これをどのように使用すれば良いのか理解できません。実行可能でしょうか。また、どのように実行すればよいでしょうか。cat
sed
答え1
プログラムに引数として渡されるファイルがテキスト ファイルであり、その内容を制御できる場合 (ファイル内に出現しない行がわかっている場合)、複数の here-document を使用できます。
{
echo "cat /dev/fd/3 3<<'EOT' /dev/fd/4 4<<'EOT' /dev/fd/5 5<<'EOT'"
cat file1
echo EOT
cat file2
echo EOT
cat file3
echo EOT
} | ssh user@host sh
以下はcat
ファイル名を引数として受け取るサンプルコマンドです。代わりに次のようになります:
echo "/path/to/prog -a /dev/fd/3 3<<'EOT' -b /dev/fd/4 4<<'EOT'
それぞれEOT
を、各ファイルに存在しないものに置き換えます。
答え2
おそらく、まさにあなたが望んでいることではないかもしれません...しかし、ssh によって開かれたパイプを介して tarball を送信することを検討してみてはいかがでしょうか?
あなたが言った:
ホストにファイルを保存することは許可されていません。
書き込み可能なホーム ディレクトリや、ファイルを長期的に保存するための他の便利な場所がない可能性もありますが、tmpfs
特定の接続でのみ使用できる一時的な場所であっても、書き込み可能な場所がないということはまずないと思います。
多くのプログラム (さらには libc ルーチン) では書き込み可能な が必要な/tmp
ので、書き込み可能な が利用できる可能性が非常に高くなります。
次に、tarball を一時ディレクトリに解凍し、プログラムを実行して、ssh 接続を介してクリーンアップするスクリプトを使用できます。
何かのようなもの:
$ tar cf - file1.txt file2.txt |
ssh host.name '
set -e
tmpdir=$(mktemp -d -t tmp.XXXXXXXXXX)
cleanup () { rm -rf "$tmpdir"; }
trap cleanup EXIT
cd "$tmpdir"
tar xf -
/path/to/program -a file1.txt -b file2.txt
'
ファイル パスについては特別な注意が必要になる可能性があり、考慮すべき特殊なケース (テスト) がいくつかありますが、一般的なアプローチは機能するはずです。
書き込み可能なディレクトリが利用できない場合は、tarball を単一の入力として受け取り、その内容をメモリに解凍するように変更するという方法がありますprogram
。たとえば、がprogram
Python スクリプトである場合、組み込みtarfile
モジュールを使用すると、そのようなことが簡単に実現できます。
答え3
TCP リスナー (より高いポートでも可) を設定できる場合は、2 番目の SSH セッションを使用して 2 番目の入力ソースを確立できますnc
。
例:
サーバー上にこのスクリプトがあります ( ~/script.bash
)。
#!/usr/bin/env bash
cat "$1" | tr a 1
nc localhost "$2" | tr '[:lower:]' '[:upper:]'
ローカルには次の 2 つのファイルがあります。
$ cat a
aaa
aaa
aaa
$ cat b
bbb
bbb
bbb
まず、2 番目のソース ($serv
サーバー) を起動します。
ssh "$serv" nc -l -p 2222 -q1 <b &
そして、適切なコマンドを実行します:
$ ssh "$serv" ./script.bash - 2222 <a
111
111
111
BBB
BBB
BBB
[1]+ Done ssh "$serv" nc -l -p 2222 -q1 < b
答え4
経由でポートを転送する権限があり、リモート マシンの とローカル マシンのssh
にアクセスできる場合は、次のように実行できます。wget
busybox
mkdir /tmp/test; cd /tmp/test
echo 1st_file > 1st_file
echo 2nd_file > 2nd_file
busybox httpd -f -p 127.0.0.1:11080 &
ssh USER@HOST -R 10080:127.0.0.1:11080 '
cat <(wget -q -O- http://localhost:10080/1st_file) \
<(wget -q -O- http://localhost:10080/2nd_file)
'
kill $!
( cat
2 つのファイル引数を取るサンプル プログラムとして使用します)。
経由でポートを転送する機能のみが-R
必須です。http を実行する代わりに、他の方法を使用できます。たとえば、 が およびオプションnetcat
をサポートしている場合:-d
-N
nc -Nl localhost 11001 < 1st_file &
nc -Nl localhost 11002 < 2nd_file &
ssh USER@HOST -R 10001:localhost:11001 -R 10002:localhost:11002 '
cat <(nc -d localhost 10001) <(nc -d localhost 10002)
<(...)
リモート マシンのログイン シェルが ksh や bash に似ていない場合は、プロセス置換を置き換える方法がある可能性があります。
全体的に見て、これはあまり良いことではありません。正確なシステム/シェル/構成/権限 (提供されていない) に関する知識が深まれば、よりスマートなソリューションが可能になります。