tmux 传输文件方法
本方法适用于向堡垒机之后的机器(无法使用 scp)传输文件。所有方法基于 tmux send-keys/capture-pane/paste-buffer/pipe-pane,无需额外端口或 SSH 隧道。
本地到远程
-
本地 base64 编码
base64 -w0 /path/to/local_file > /tmp/file_b64.txt -
在远程 pane 启动 here-document 接收
tmux send-keys -t <session>:<window>.<pane> "cat > /path/to/remote_b64.txt << 'EOFB64'" Enter sleep 1 -
本地分块发送 base64(每块 2000 字符 + Enter)
python3 << 'PYEOF' import subprocess, time b64 = open('/tmp/file_b64.txt').read().strip() chunk_size = 2000 chunks = [b64[i:i+chunk_size] for i in range(0, len(b64), chunk_size)] for i, chunk in enumerate(chunks): subprocess.run(['tmux', 'send-keys', '-t', '<session>:<window>.<pane>', chunk, 'Enter']) time.sleep(0.2) # 防止终端缓冲区溢出 if i % 200 == 199: time.sleep(0.5) # 4. 发送结束标记 time.sleep(1) subprocess.run(['tmux', 'send-keys', '-t', '<session>:<window>.<pane>', 'EOFB64', 'Enter']) print(f"Sent {len(chunks)} chunks") PYEOF -
在远程 pane 解码
tmux send-keys -t <session>:<window>.<pane> 'base64 -d /path/to/remote_b64.txt > /path/to/remote_file && rm /path/to/remote_b64.txt' Enter
远程到本地
-
开始管道捕获 pane 输出到本地文件
tmux pipe-pane -t <session>:<window>.<pane> -O 'cat >> /tmp/captured.txt' -
在远程 pane 输出 base64 编码内容(用 marker 标记起止)
tmux send-keys -t <session>:<window>.<pane> 'echo PIPSTART && base64 /path/to/remote_file && echo PIPEND' Enter sleep 10 # 等待输出完成,大文件需更久 -
停止管道
tmux pipe-pane -t <session>:<window>.<pane> -
从捕获文件中提取并解码
python3 -c " import base64, re, json content = open('/tmp/captured.txt').read() start = content.find('PIPSTART\n') + len('PIPSTART\n') end = content.find('\nPIPEND') b64 = re.sub(r'[^A-Za-z0-9+/=\n]', '', content[start:end]).replace('\n', '') if len(b64) % 4: b64 += '=' * (4 - len(b64) % 4) data = base64.b64decode(b64) open('/tmp/local_file', 'wb').write(data) print(f'Decoded {len(data)} bytes') "
注意事项
tmux capture-pane不可靠(历史缓冲区有限,大文件会截断),不要用 capture-pane 传输大文件tmux paste-buffer对大文件不可靠(终端缓冲区溢出),不要用 paste-buffer 传输大文件tmux pipe-pane -O是可靠的输出捕获方法,适合下载tmux send-keys+ here-document 分块发送是可靠的上传方法- 传输前先用
base64 -w0编码(单行无换行),避免终端换行导致的数据损坏 pipe-pane捕获的内容包含终端转义序列,需用正则过滤后解码- 大文件(>2MB)建议先
split分块再逐块传输 - 分块大小 2000 字符 + 0.2s 延迟是经验值,太大或太快会丢数据
- 超过 120s 的传输需要用 timeout 参数延长
- 2.8MB base64(1398 块)需 ~280s,bash 工具 timeout 需设为 600000ms
- 传输中断后可续传:计算已传输字符数,用 offset 截取剩余部分继续发送
pipe-pane -O捕获的 base64 需用正则[^A-Za-z0-9+/=\n]过滤终端转义序列

浙公网安备 33010602011771号