$ md="-l /tmp/test/my dir"
$ ls "$md"
ls: invalid option -- ' '
Try 'ls --help' for more information.
$ md="-l \"/tmp/test/my dir\""
$ ls "$md"
ls: invalid option -- ' '
Try 'ls --help' for more information.
我想知道为什么两者都不起作用?谢谢。注意变量的值包含
- 一个选项
-l
- 包含空格的路径名参数
- 分隔上述两者的空间。
我的实际问题是:我写了一个脚本myscript.sh
#! /bin/bash
old_dest=""
while getopts ":l:t" opt; do
case $opt in
l)
old_dest="--link-dest \"$OPTARG\""
;;
esac
done
rsync -a --delete "$old_dest" /path/to/source /path/to/dest
我想将脚本作为带有-l
选项的命令调用。
myscript.sh -l "/media/t/my external hdd/backup/old one"
我应该如何编写分配给的脚本部分old_dest
?
由于您使用的是 bash,并且由于 bash 支持数组,我建议将 old_dest 设为数组,而不是:
我将调用 rsync 改为调用 printf 以在单独的行上显示命令和每个参数。执行时:
结果是:
您的命令不起作用的原因是没有递归应用引号删除/分词。
因此
"$old_dest"
扩展到以下 SINGLE 参数:所有这一切都是一个参数,因为变量用双引号引起来。(并且那些双引号被删除了,但是由扩展产生的双引号,即变量值的一部分,没有被删除。)
如果您
$old_dest
改为使用,您将获得多个参数,但不是您想要的方式。你会得到以下五个参数:这是因为您会得到变量扩展,然后是分词,如手册中所述。您不会得到变量扩展,然后解释变量中的引号。并且引号不会被删除,因此最后一个参数将是四个字符:
one"
.如另一个答案所述,正确的方法是使用 Bash 数组。
另外,您可能会喜欢 Tcl 如何处理引号和分词。它可能更直观,尽管我对 shell 分词非常熟悉,但我必须更多地考虑 Tcl 而不是 shell。