Claude Code 在 Git Bash 用使用 rsync 报错 1029

$ rsync -avhnP --delete ./Caddyfile.d/ 'docker:/opt/data/caddy/Caddyfile.d/' -vvv
cmd=<NULL> machine=docker user=<NULL> path=/opt/data/caddy/Caddyfile.d/
cmd[0]=ssh cmd[1]=docker cmd[2]=rsync cmd[3]=--server cmd[4]=-vvvvnlogDtpre.iLsfxCIvu cmd[5]=--delete cmd[6]=--partial cmd[7]=. cmd[8]=/opt/data/caddy/Caddyfile.d/ 
opening connection using: ssh docker rsync --server -vvvvnlogDtpre.iLsfxCIvu --delete --partial . /opt/data/caddy/Caddyfile.d/  (9 args)
msg checking charset: UTF-8
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
[Receiver] _exit_cleanup(code=12, file=io.c, line=232): entered
rsync error: error in rsync protocol data stream (code 12) at io.c(232) [Receiver=3.2.7]
[Receiver] _exit_cleanup(code=12, file=io.c, line=232): about to call exit(12) (DRY RUN)
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
[sender] _exit_cleanup(code=12, file=io.c, line=232): entered
      0 [sig] rsync 1869! sigpacket::process: Suppressing signal 30 to win32 process (pid 40600)
rsync error: error in rsync protocol data stream (code 12) at io.c(232) [sender=3.4.1]
[sender] _exit_cleanup(code=12, file=io.c, line=232): about to call exit(12) (DRY RUN)

之前 MSYS2 的 rsync 上传到 Synology 报错 出现过相似的报错信息,不过那次是无权限,因为 Synology 的 rsync 没有启用。这次的错误是 SSH 运行错误。

实际上原因是这里的 ssh 解析到 Windows 的版本

$ which ssh
C:/Program Files/OpenSSH/ssh.exe

而 MSYS2 的 rsync 期望 /usr/bin/ssh / C:/msys64/usr/bin/ssh.exe 的。所以解决思路就是添加 -e /usr/bin/ssh

还有个一劳永逸但别扭的办法 $env:PATH = "/usr/bin/;" + $env:PATH
或者把 C:\msys64\usr\bin 加到系统环境变量 PATH 中。

破坏性都有点大,我还是 -e

管理私密环境变量的方法

  1. OpenRC
/etc/conf.d/service
export DB_HOST=127.0.0.1
  1. SystemD
/etc/systemd/system/myservice.service.d/override.conf
[Service]
Environment="DB_HOST=127.0.0.1"
EnvironmentFile=-/etc/sysconfig/httpd
  1. Taskfile
dotenv: ['.env']
tasks:
  default:
    cmds:
      - echo $DB_HOST
  1. Docker Compose

与 docker-compose.yaml 同目录的 .env 文件

services:
  webapp:
    environment:
      DB_HOST: "${DB_HOST}"

Taskfile 中执行多行 SSH 命令

heredoc
前有 在 Taskfile 中写多行文本 经验可以写多行 SSH ,但还不够完美。

会产生类似直接 SSH 登录会输出的 MOTD,以及一行 Pseudo-terminal will not be allocated because stdin is not a terminal.

$ task test
task: [test] ssh docker << 'EOF'
  ls
EOF
 
Pseudo-terminal will not be allocated because stdin is not a terminal.
Linux docker 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
 
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
 
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
chisel_1.11.3_linux_amd64.deb

我不喜欢,其实正确的方法是 ssh docker /bin/sh <<'EOF'