从 shell 脚本执行命令失败
execute command from shell script fails
当我 运行 我的脚本失败时:
# sh -x ./rsync.sh
...
+ rsync --safe-links --password-file=/etc/rsync.secret -rtvun --include='*.log*.gz' --filter='-! */' --prune-empty-dirs /some/path foo@hostname::foo
Unknown filter rule: `'-!'
rsync error: syntax or usage error (code 1) at exclude.c(904) [client=3.1.1]
但是当我复制并粘贴 rsync --safe-links ....
行并执行它时它工作正常。
rsync.sh:
#!/bin/bash
rsync_opts="--safe-links --password-file=/etc/rsync.secret -rtvu"
while read path hostname volume extra_opts; do
rsync ${rsync_opts} ${extra_opts} ${path} ${volume}@${hostname}::${volume}
done < /etc/rsync.paths
rsync.paths:
/some/path/ hostname foo --include='*.log*.gz' --filter='-! */' --prune-empty-dirs
有谁知道为什么脚本会失败,而当我手动 运行 命令时却能正常工作?我该如何解决?
更新:
当我使用 eval "rsync ..."
时它工作正常,但我仍然不知道为什么没有它就不能工作:/
您的问题是您的脚本将文本 --filter='-! */' --prune-empty-dirs
读取到变量 $extra_opts
中,该变量按字面意思传递给命令,包括撇号。所以它被分成以下参数:--filter='-!
、*/'
和 --prune-empty-dirs
。但是,当你 eval
它时,整行都会传递给 shell 解释器,它会按照你想要的方式解释撇号,这就是它起作用的原因。
此外,由于您的脚本使用 bash
,因此您应该使用 bash -x
而不是 sh -x
来调试它。
当我 运行 我的脚本失败时:
# sh -x ./rsync.sh
...
+ rsync --safe-links --password-file=/etc/rsync.secret -rtvun --include='*.log*.gz' --filter='-! */' --prune-empty-dirs /some/path foo@hostname::foo
Unknown filter rule: `'-!'
rsync error: syntax or usage error (code 1) at exclude.c(904) [client=3.1.1]
但是当我复制并粘贴 rsync --safe-links ....
行并执行它时它工作正常。
rsync.sh:
#!/bin/bash
rsync_opts="--safe-links --password-file=/etc/rsync.secret -rtvu"
while read path hostname volume extra_opts; do
rsync ${rsync_opts} ${extra_opts} ${path} ${volume}@${hostname}::${volume}
done < /etc/rsync.paths
rsync.paths:
/some/path/ hostname foo --include='*.log*.gz' --filter='-! */' --prune-empty-dirs
有谁知道为什么脚本会失败,而当我手动 运行 命令时却能正常工作?我该如何解决?
更新:
当我使用 eval "rsync ..."
时它工作正常,但我仍然不知道为什么没有它就不能工作:/
您的问题是您的脚本将文本 --filter='-! */' --prune-empty-dirs
读取到变量 $extra_opts
中,该变量按字面意思传递给命令,包括撇号。所以它被分成以下参数:--filter='-!
、*/'
和 --prune-empty-dirs
。但是,当你 eval
它时,整行都会传递给 shell 解释器,它会按照你想要的方式解释撇号,这就是它起作用的原因。
此外,由于您的脚本使用 bash
,因此您应该使用 bash -x
而不是 sh -x
来调试它。