如何在保留现有SSH配置下解决rsync over ssh的命令执行冲突报错
我想要通过SSH使用rsync复制文件,但触发了“Cannot execute command-line and remote command”错误,而scp可以正常工作。
执行的命令:
rsync -ravh folder XXX:folder
我的SSH配置如下:
Host XXX Hostname YY User user RequestTTY yes RemoteCommand bash --init-file ~/.bashrc
我发现移除RemoteCommand选项后,rsync就能正常工作。请问如何在保留当前SSH主机配置的前提下让rsync正常运行?
问题出在SSH配置里的RemoteCommand和rsync的工作逻辑冲突:rsync通过SSH连接时会自动向远程主机发送自身的执行命令,而配置里的RemoteCommand已经指定了固定的远程执行命令,两者无法同时生效,因此触发错误。以下是几种可行的解决方法:
方法1:临时覆盖SSH配置执行rsync
执行rsync时,通过-e参数指定自定义的SSH命令,跳过配置中的RemoteCommand:
rsync -ravh -e "ssh XXX -o RemoteCommand=''" folder XXX:folder
或者直接指定远程主机的完整连接参数,绕开本地配置:
rsync -ravh -e "ssh -l user YY" folder YY:folder
方法2:在SSH配置中添加rsync专属规则
在SSH配置文件里新增一个专门用于rsync的主机别名,去掉RemoteCommand和RequestTTY(rsync不需要TTY):
Host XXX Hostname YY User user RequestTTY yes RemoteCommand bash --init-file ~/.bashrc Host XXX-rsync Hostname YY User user
之后用这个别名执行rsync:
rsync -ravh folder XXX-rsync:folder
如果你使用的是OpenSSH 7.6及以上版本,可以用Match指令实现更智能的条件匹配,让rsync连接自动跳过RemoteCommand:
Host XXX Hostname YY User user RequestTTY yes Match exec "[[ $SSH_ORIGINAL_COMMAND != *rsync* ]]" RemoteCommand bash --init-file ~/.bashrc
当rsync发起连接时,SSH_ORIGINAL_COMMAND环境变量会包含rsync相关内容,匹配规则会跳过RemoteCommand的执行,而日常登录仍会加载.bashrc。
方法3:修改RemoteCommand兼容rsync
调整RemoteCommand的写法,让它能接收并执行rsync发送的远程命令,同时保留加载.bashrc的逻辑:
Host XXX Hostname YY User user RequestTTY yes RemoteCommand bash --init-file ~/.bashrc -c '%n'
这里的%n是SSH的内置占位符,代表原本要执行的远程命令。这样当rsync发送命令时,会被bash接收并执行,日常登录时也会正常加载.bashrc进入交互式shell。
内容的提问来源于stack exchange,提问作者infrahinium

