我想出了两个解决方案,都包含 bash 脚本和 stdin 中的 tarball。
1. 将 base64 编码的 tarball 嵌入到定界文档中
在这种情况下,服务器收到一个 bash 脚本,其中 tarball 嵌入到 Heredoc 中:
base64 -d <<'EOF_TAR' | tar -zx
<base64_tarball>
EOF_TAR
这是完整的示例:
ssh $HOST bash -s < <(
# Feed script header
cat <<'EOF'
cd /tmp
base64 -d <<'EOF_TAR' | tar -zx
EOF
# Create local tarball, and pipe base64-encoded version
tar -cz ./archive | base64
# Feed rest of script
cat <<'EOF'
EOF_TAR
./archive/some_script.sh
rm -r archive
EOF
)
然而,在这种方法中,tar
在 tarball 通过网络完全传输之前,不会开始提取 tarball。
2. 在脚本后面输入 tar 二进制数据
在这种情况下,bash 脚本通过管道传输到标准输入,然后是原始 tarball 数据。bash
将控制权传递给tar
它处理标准输入的 tar 部分:
ssh $HOST bash -s < <(
# Feed script.
cat <<'EOF'
function main() {
cd /tmp
tar -zx
./archive/some_script.sh
rm -r archive
}
main
EOF
# Create local tarball and pipe it
tar -cz ./archive
)
与第一种方法不同,此方法允许tar
当 tarball 通过网络传输时,开始提取 tarball。
边注
为什么我们需要main
你问功能吗?为什么首先输入整个 bash 脚本,然后输入二进制 tar 数据?好吧,如果将二进制数据放在 bash 脚本中间,就会出现错误,因为tar
消耗超过 tar 文件末尾的内容,在这种情况下会消耗一些 bash 脚本。所以main
函数用于强制整个 bash 脚本位于 tar 数据之前。