You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash中能否通过管道将文件传入SSH的here-document并支持变量展开?

问题:用Here-Document实现SSH传输并解压文件

我原本用这条命令完成文件压缩、上传到服务器并解压到指定目录:

tar -pzcf - example.txt | ssh user@198.123.45.678 'cd /some-path/ && tar -zxf -'

但我想用here-document(heredoc)实现相同功能,尝试了下面的写法却无法正常工作:

tar -pzcf - example.txt | ssh user@198.123.45.678 /bin/bash <<EOF
    cd /some-path/
    tar -zxf -
EOF

需求背景

我有多段通过SSH在两台服务器上运行的本地脚本,这两台服务器对引号的处理方式不一致,heredoc能解决引号转义的问题。另外部分脚本需要用pipe viewer(pv)监控传输进度,但我还没找到把本地文件内容通过pv传入heredoc、让服务器处理的方法。

补充需求:支持变量展开

我需要从配置文件读取值,这也是引号问题的根源。比如下面的写法支持变量展开,但用heredoc时却无法正常接收管道内容:

先获取变量:

root_path=$(jq -r '.config.path.remote' config.json)

原来的变量展开写法:

tar -pzcf - example.txt | ssh user@198.123.45.678 "cd '$root_path' && tar -zxf -"

尝试的heredoc写法(无法接收管道内容):

root_path=$(jq -r '.config.path.remote' config.json)
tar -pzcf - example.txt | ssh user@198.123.45.678 /bin/bash <<EOF
    cd "$root_path"
    tar -zxf -
EOF
解决方案

问题核心是heredoc会占用远程bash的标准输入,导致本地tar输出的管道内容无法被远程的tar -zxf -读取。以下是两种可行的解决方法:

方法1:重定向管道到额外文件描述符

把本地管道的内容映射到远程bash的文件描述符3,让heredoc用标准输入,tar从fd3读取压缩包内容:

root_path=$(jq -r '.config.path.remote' config.json)
tar -pzcf - example.txt | ssh user@198.123.45.678 /bin/bash 3<&0 <<EOF
    cd "$root_path"
    tar -zxf /dev/fd/3
EOF

方法2:用进程替换传递heredoc命令

通过进程替换将heredoc作为远程bash的命令源,保留标准输入给管道内容:

root_path=$(jq -r '.config.path.remote' config.json)
tar -pzcf - example.txt | ssh user@198.123.45.678 bash <(cat <<EOF
    cd "$root_path"
    tar -zxf -
EOF
)

结合pv监控进度的写法

如果需要用pv显示传输进度,直接把它插入管道中间即可,两种方法都适用:
比如方法1结合pv:

root_path=$(jq -r '.config.path.remote' config.json)
tar -pzcf - example.txt | pv | ssh user@198.123.45.678 /bin/bash 3<&0 <<EOF
    cd "$root_path"
    tar -zxf /dev/fd/3
EOF

内容的提问来源于stack exchange,提问作者Tomas Mulder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:43:22