我正在尝试编写一个shell脚本,该脚本调用另一个脚本然后执行rsync命令。
第二个脚本应该在自己的终端中运行,所以我使用gnome-terminal -e "..."
命令。此脚本的一个参数是一个字符串,其中包含应该为rsync提供的参数。我把它们放在单引号中。
直到这里,一切正常,直到其中一个rsync参数是包含空格的目录路径。我尝试了很多',',\“,\'的组合,但脚本要么根本不运行,要么只采用路径的第一部分。
这是我正在使用的代码的略微修改版本
gnome-terminal -t 'Rsync scheduled backup' -e "nice -10 /Scripts/BackupScript/Backup.sh 0 0 '/Scripts/BackupScript/Stamp' '/Scripts/BackupScript/test' '--dry-run -g -o -p -t -R -u --inplace --delete -r -l '\''/media/MyAndroid/Internal storage'\''' "
在Backup.sh
内执行此命令
rsync $5 "$path"
目标$path
是根据Stamp
中的文字计算的。
如何实现这三个级别的嵌套引用?
这些是我刚才看到的一些问题(我之前也尝试过其他资料)
我没有成功地将解决方案应用到我的问题中。
答案 0 :(得分:4)
这是一个例子。 caller.sh
使用gnome-terminal
执行foo.sh
,然后打印所有参数,然后使用第一个参数调用rsync
。
caller.sh :
#!/bin/bash
gnome-terminal -t "TEST" -e "./foo.sh 'long path' arg2 arg3"
foo.sh :
#!/bin/bash
echo $# arguments
for i; do # same as: for i in "$@"; do
echo "$i"
done
rsync "$1" "some other path"
编辑:如果$1
包含rsync的几个参数,其中一些是长路径,则上述操作无效,因为bash要么将"$1"
作为一个参数传递或$1
作为多个参数,将其拆分而不考虑包含的引号。
有(至少)一种解决方法,你可以按如下方式欺骗bash:
caller2.sh :
#!/bin/bash
gnome-terminal -t "TEST" -e "./foo.sh '--option1 --option2 \"long path\"' arg2 arg3"
foo2.sh :
#!/bin/bash
rsync_command="rsync $1"
eval "$rsync_command"
这相当于在命令行上输入rsync --option1 --option2 "long path"
。
警告:此黑客引入了一个安全漏洞,如果用户对字符串内容有任何影响,$1
可以制作成执行多个命令(例如'--option1 --option2 \"long path\"; echo YOU HAVE BEEN OWNED'
将运行rsync
然后执行 echo
命令。
答案 1 :(得分:0)
您是否尝试使用“\”(无引号)转义路径中的空格?
gnome-terminal -t 'Rsync scheduled backup' -e "nice -10 /Scripts/BackupScript/Backup.sh 0 0 '/Scripts/BackupScript/Stamp' '/Scripts/BackupScript/test' '--dry-run -g -o -p -t -R -u --inplace --delete -r -l ''/media/MyAndroid/Internal\ storage''' "