通过STDIN发送脚本和文件内容

时间:2020-04-30 08:01:38

标签: bash

我生成(动态)连接以下文件的脚本:

testscript1

echo Writing File
cat > /tmp/test_file <<EOF

测试内容

line1
second line

testscript2

EOF
echo File is written

然后我打电话给

$ cat testscript1 testcontent testscript2 | ssh remote_host bash -s --

结果是文件/tmp/test_file充满了所需的内容。

还有一种可以想到的变体,其中可以以类似的方式提供 binary 文件吗?当然可以使用dd或其他工具代替猫,但是我看到的问题是“告诉”他们STDIN现在结束了(我可以通过该流发送^ D吗?)

我无法解决这个问题,但是可能没有可比的解决方案。但是,我可能错了,所以很高兴收到您的来信。

此致

马兹

2 个答案:

答案 0 :(得分:2)

我可以通过该流发送^ D

是的,但是您不想这么做。

Control + D,通常表示为^ D,只是一个字符-或简陋(我经常这样),是我们通常视为的字符代码(ASCII或UTF-8之类的超集)中的代码点一个人物。您可以通过多种方法发送该字符/字节,最简单的方法是printf '\004',但是接收系统不会将其视为文件末尾。而是像其他任何数据字节一样,将其存储在目标文件中,然后是您打算作为新命令和文件的后续数据,等等。

^ D仅在从终端输入(更确切地说是“ tty”设备)时导致文件结束-然后仅在“煮熟”模式下(这就是程序之类的原因viless所执行的操作与键入^ D时结束文件有很大不同。您使用的ssh形式不会使输入成为'tty'设备。 ssh 可以将输入(和输出)设置为“ tty”(更确切地说,是“ tty”的子类,称为伪tty或“ pty”,但这在这里并不重要)如果您添加了-t选项(在某些情况下,您可能需要将其重复为-t -t-tt)。但是然后,如果您的二进制文件包含任何具有值\004的字节-或其他几个特殊值-很有可能,那么您的数据将被破坏并且垃圾命令将被执行(有时),这肯定不会做您想做的事,可能会损坏您的系统。

1980年代和1990年代,您尝试做的传统方法是'shar'(shell存档),而处理二进制数据的常用解决方案是'uuencode',该方法将二进制数据转换为仅可打印的字符可以安全地通过这样的链接,并由匹配的“ uudecode”将其转换回去。参见this surviving example from GNU。 uuencode和uudecode本身是通信协议'uucp'的一部分,该通信协议主要用于电子邮件和Usenet,它们(都)已过时并且被遗忘了。

但是,当今几乎所有系统都包含一个“ base64”程序,该程序提供了等效(尽管不完全相同)的功能。在单个系统中,您可以执行以下操作:

 base64 <infile | base64 -d >outfile

以获得与cp infile outfile相同的效果。在您的情况下,您可以执行以下操作:

 { echo "base64 -d <<END@ >outfile"; base64 <infile; echo "END@"; otherstuff; } | ssh remote bash

答案 1 :(得分:0)

您也可以尝试:

cat testscript1 testcontent testscript2 | base64 | ssh <options> "base64 --decode | bash"

不用担心^D,因为当您的输入用尽时,管道的下一个进程将注意到它们已经到达输入文件的末尾。