我在遠端主機上有一個程序,我需要自動化其執行。在同一台機器上執行該程式的命令如下所示:
/path/to/program -a file1.txt -b file2.txt
在這種情況下,file1.txt
和file2.txt
分別用於程序中完全不同的事物,所以我不能將cat
它們放在一起。但是,就我而言,我想要傳遞到程式中的file1.txt
和只存在於我的裝置上,而不存在於我需要執行程式的主機上。file2.txt
我知道我可以透過 SSH 傳遞至少一個檔案stdin
:
cat file1.txt | ssh host.name /path/to/program -a /dev/stdin -b file2.txt
但是,由於我不允許在主機上儲存文件,所以我file2.txt
也需要一種方法來到達那裡。我認為透過濫用環境變數和創造性地使用cat
和sed
在一起可能是可能的,但我對這些工具還不夠了解,無法理解如何使用它們來實現這一點。可行嗎?
答案1
如果作為程式參數給出的文件是文字文件,並且您能夠控制它們的內容(您知道其中沒有出現的行),則可以使用多個此處文件:
{
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
'
這可能需要額外注意檔案路徑,並且需要考慮一些極端情況(對其進行測試),但一般方法應該可行。
如果沒有可用的可寫入目錄,可能的方法是修改program
為將 tarball 作為單一輸入並將其內容解壓縮到記憶體中。例如,如果program
是Python腳本,那麼使用內建tarfile
模組可以輕鬆完成類似的事情。
答案3
如果您可以設定 TCP 監聽器(可以是更高的連接埠),那麼您可以使用第二個 SSH 會話來建立第二個輸入來源nc
。
例子:
伺服器上有這個腳本(~/script.bash
):
#!/usr/bin/env bash
cat "$1" | tr a 1
nc localhost "$2" | tr '[:lower:]' '[:upper:]'
且本地有這兩個檔案:
$ cat a
aaa
aaa
aaa
$ cat b
bbb
bbb
bbb
現在先啟動第二個來源($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
作為帶有兩個文件參數的範例程式)。
只有透過轉送連接埠的能力才是-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)
<(...)
如果遠端電腦上的登入 shell 不是類似 ksh 或 bash 的,則可能有一些方法可以替換進程替換。
總而言之,這並不是太好——更好地了解確切的系統/shell/配置/權限(您尚未提供)可以允許更聰明的解決方案。