shell脚本中的三重嵌套引号

时间:2014-01-16 17:33:01

标签: linux string bash shell nested

我正在尝试编写一个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中的文字计算的。

如何实现这三个级别的嵌套引用?

这些是我刚才看到的一些问题(我之前也尝试过其他资料)

我没有成功地将解决方案应用到我的问题中。

2 个答案:

答案 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''' "