shell脚本中的三重嵌套引号

Deg*_*ran 4 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'\''' "
Run Code Online (Sandbox Code Playgroud)

在此命令中Backup.sh运行

rsync $5 "$path"
Run Code Online (Sandbox Code Playgroud)

其中目的地$path是根据 中的文本计算的Stamp

如何实现这三层嵌套引用?

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

我未能成功地将解决方案应用于我的问题。

Sir*_*hos 5

这是一个例子。caller.sh使用gnome-terminalexecute foo.sh,它依次打印所有参数,然后rsync使用第一个参数进行调用。

来电者.sh

#!/bin/bash
gnome-terminal -t "TEST" -e "./foo.sh 'long path' arg2 arg3"
Run Code Online (Sandbox Code Playgroud)

foo.sh

#!/bin/bash
echo $# arguments
for i; do    # same as: for i in "$@"; do
    echo "$i"
done
rsync "$1" "some other path"
Run Code Online (Sandbox Code Playgroud)

编辑:如果$1包含 rsync 的多个参数,其中一些是长路径,则上述内容将不起作用,因为 bash 要么"$1"作为一个参数传递,要么$1作为多个参数传递,将其拆分而不考虑包含的引号。

有(至少)一种解决方法,您可以按如下方式欺骗 bash:

来电者2.sh

#!/bin/bash
gnome-terminal -t "TEST" -e "./foo.sh '--option1 --option2 \"long path\"' arg2 arg3"
Run Code Online (Sandbox Code Playgroud)

foo2.sh

#!/bin/bash
rsync_command="rsync $1"
eval "$rsync_command"
Run Code Online (Sandbox Code Playgroud)

这相当于rsync --option1 --option2 "long path"在命令行上输入。

警告:此 hack 引入了一个安全漏洞,$1如果用户对字符串内容有任何影响(例如'--option1 --option2 \"long path\"; echo YOU HAVE BEEN OWNED'将运行rsync然后执行命令echo),则可以设计为执行多个命令。

  • 只需将其删除即可。`for foo` 将循环遍历 `"$@"`,无需任何额外的语法。语法糖。 (2认同)