我提供了两种解决方案,都包括bash脚本和tarball在stdin中。
1. 在heredoc中嵌入base64编码的tarball
在此情况下,服务器接收到一个包含嵌入在heredoc中的tarball的bash脚本:
base64 -d <<'EOF_TAR' | tar -zx
<base64_tarball>
EOF_TAR
以下是完整的示例:
ssh $HOST bash -s < <(
cat <<'EOF'
cd /tmp
base64 -d <<'EOF_TAR' | tar -zx
EOF
tar -cz ./archive | base64
cat <<'EOF'
EOF_TAR
./archive/some_script.sh
rm -r archive
EOF
)
然而,在这种方法中,tar
不会在网络传输完整个 tar 包之前开始解压缩。
2. 在脚本后输入 tar 二进制数据
在这种情况下,bash 脚本作为 stdin 管道传入,其后是原始的 tar 文件数据。 bash
将控制权传递给 tar
,它将处理 stdin 的 tar 部分:
ssh $HOST bash -s < <(
cat <<'EOF'
function main() {
cd /tmp
tar -zx
./archive/some_script.sh
rm -r archive
}
main
EOF
tar -cz ./archive
)
与第一种方法不同的是,这种方法允许
tar
在网络传输 tarball 的同时开始提取。
顺便说一下,你问为什么我们需要
main
函数?为什么要先输入整个 bash 脚本,然后再输入二进制 tar 数据呢?好吧,如果二进制数据放在 bash 脚本的中间,会出现错误,因为
tar
会消耗 tarfile 结尾之后的内容,在这种情况下,它会吞掉一些 bash 脚本。所以,
main
函数被用来强制整个 bash 脚本在 tar 数据之前出现。