我有一个供客户使用的备份服务器同步通过 SSH。服务器配置为运行自定义 shell 脚本,该脚本包装 rsync 服务器端的调用。客户端不知道这一点,并且可以发出任何有效的 rsync 命令行。
我想将一些参数从客户端传递到该 shell 脚本中。就像是
$ rsync -av -customarg1 value1 -customarg2 value2 file1 file2 user@server
客户端rsync
拒绝任何它不知道的参数,就像ssh
(通过rsync -e
)一样。我想出的最好办法是将参数作为假服务器端文件规范传递,该脚本在执行脚本以启动 rsync 服务器之前从服务器端命令行中提取该规范。即像这样的命令
$ rsync -av file1 file2 user@server:some/path\;customarg1=value1\;customarg2=value2
将提供两个参数,然后表现得就像命令一样
$ rsync -av file1 file2 user@server:some/path
(这利用了 SSH 设置了许多环境变量,其中$SSH_ORIGINAL_COMMAND
包含 ssh 客户端发出的命令(即 rsync 客户端启动的 rsync 服务器命令),无论 ssh 服务器配置为执行什么(即自定义 shell脚本))
答案1
也许您可以使用-M
选项(长版本--remote-option
),客户端 rsync 似乎不会检查该选项。-M-xxxx
被传递到遥控器,并被-M
剥离为-xxxx
。您可以轻松地使用此功能-M-M-xxxx
,客户端和远程会忽略它:
rsync -av -M-M-myvar=val /tmp/test/ remote:test/
如果您的服务器前端在调用 rsync 之前识别并删除结果标志,您就可以获得所需的内容。
您可以进一步使用--rsync-path
它来运行任何脚本。它将连接远程参数。例如
rsync -a -M-myvar=val --rsync-path='echo hello >/tmp/out; ./mysync' /tmp/test/ remote:test/
将在远程运行类似
echo hello >/tmp/out
./mysync --server -logDtpre.iLsfx -myvar=val . test/
答案2
这并不完全漂亮,但它可以全部隐藏在脚本中:
SSH可以通过隧道发送任意环境变量;客户端和服务器都需要配置为允许它。客户可以轻松完成该-o
选项;您必须在sshd_config
文件中执行的服务器。接受任意的不是一个好主意,但是这样的事情应该有效:
BACKUP_PROVIDER_VAR1=val1 rsync -e 'ssh -o SendEnv=BACKUP_PROVIDER_*' …
然后,您需要AcceptEnv LANG LC_* BACKUP_PROVIDER_*
在您的中添加一个sshd_config
(据我所知,这可能仅限于带有Match
块的特定用户/组)。实际上,您可能不需要备份客户端LANG
或LC_*
来自备份客户端,因此您只需要自己的自定义环境变量。
答案3
从 rsync 版本 3.1.0 开始,可以使用--remote-option
参数(或其缩写形式-M
)将参数传递到服务器。例如,向客户端发出命令:
$ rsync -av -M --customarg1=value1 -M --customarg2=value2 file1 file2 user@server:some/path
将导致服务器命令接收变量中前缀为 的参数-M
,但不包含, 。像这样:-M
SSH_ORIGINAL_COMMAND
rsync --server -vnlogDtpre.iLsfxC --customarg1=value1 --customarg2=value1 . some/path
在调用服务器端 rsync 之前,需要处理自定义参数并将其从命令行中删除(否则它将因错误而终止,因为它无法识别它们)。一种方法是使用正则表达式匹配:
rsync_cmd="$SSH_ORIGINAL_COMMAND"
[[ "$rsync_cmd" =~ --customarg1=([a-zA-Z0-9]+) ]] && customarg1=${BASH_REMATCH[1]}
[[ "$rsync_cmd" =~ --customarg2=([a-zA-Z0-9]+) ]] && customarg2=${BASH_REMATCH[1]}
rsync_cmd=$(sed -re 's/--(customarg1|customarg2)=[a-zA-Z0-9]+//g' <<< $rsync_cmd)
(示例正则表达式匹配允许参数为字母数字)
-s
对此需要注意的是,如果为 rsync 客户端提供(或) 选项,则它不起作用,--protect-args
因为这会导致参数在 rsync 客户端和服务器之间内部传递 - 它们不会暴露给 shell,也不包含在$SSH_ORIGINAL_COMMAND
,因此不能被操纵。
另一种方法是使用--rsync-path
传递自定义参数。此方法适用于缺少以下选项的旧版本-M
rsync --protect-args
:
$ rsync --rsync-path='rsync --customarg1=value1 --customarg2=value2' -av file1 file2 user@server:some/path