我在远程主机上有一个程序,我需要自动化其执行。在同一台机器上执行该程序的命令如下所示:
/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/配置/权限(您尚未提供)可以允许更智能的解决方案。