我有一个脚本调用这个
find "/mnt/Data/Shared/$1" -type d -exec bash -c 'fixperm "'${1}'" "fd" "$0"' {} \;
$1 是一个目录,当名称不包含空格时它可以工作,当有空格时它会失败并返回错误。使用“00_Office 测试”进行测试
Test" "fd" "$0": -c: line 0: unexpected EOF while looking for matching `"'
Test" "fd" "$0": -c: line 1: syntax error: unexpected end of file
我认为这可能是因为路径在空格之前缺少 \ ,但这并不能解决问题。我确信我在这里遗漏了一些微不足道的东西。
答案1
这是因为${1}
出现在单引号之外,即它在 shell 看到它之前就被扩展和分词了find
。 StackExchange 上的语法高亮显示清楚地表明了这一点。使用双引号可以防止分词。
另外,通过调用bash -c
,您需要自己处理引号,但如果文件名包含双引号,则可能会中断。不要使用它,直接传递参数:
find "/mnt/Data/Shared/$1" -type d -exec fixperm "$1" fd {} \;
答案2
那是因为您使用的是不带引号的${1}
.
引用
解决报价问题可能会变得相当复杂。
替换'${1}'
为'"${1}"'
可能似乎有帮助。
比较:
$ set -- "ab cd"; bash -c 'printf "<%s> " '${1}' "fd" "$0"'
<ab>
和:
$ set -- "ab cd"; bash -c 'printf "<%s> " '"${1}"' "fd" "$0"'
<ab> <cd> <fd> <bash>
然而,shell“引号删除”仍然应用于变量值。
作为解决方法,您可以使用'"${1@Q}"'
$ set -- 'a"b c"d'; bash -c 'printf "<%s> " '"${1}"' "fd" "$0"'; echo
<ab cd> <fd> <bash> # quotes got lost.
$ set -- 'a"bc"d'; bash -c 'printf "<%s> " '"${1@Q}"' "fd" "$0"'; echo
<a"b c"d> <fd> <bash> # correct quotes.
但是,这仍然不适用于您的命令所具有的两个 shell 暴露循环(首先是命令find
,然后是bash -c
命令):
$ mkdir 'a"bc"d' 'a"b c"d' 'a"bcd'
$ set -- 'a"bc"d'; find "./$1" -type d -exec bash -c 'printf "<%s> " fixperm "'"${1}"'" "fd" "$0"' {} >
<fixperm> <abcd> <fd> <./a"b c"d>
$ set -- 'a"b c"d'; find "./$1" -type d -exec bash -c 'printf "<%s> " fixperm "'"${1}"'" "fd" "$0"' {} >
<fixperm> <ab> <cd> <fd> <./a"b c"d>
$ set -- 'a"bcd'; find "./$1" -type d -exec bash -c 'printf "<%s> " fixperm "'"${1}"'" "fd" "$0"' {} \;
./a"bcd: -c: line 0: unexpected EOF while looking for matching `"'
./a"bcd: -c: line 1: syntax error: unexpected end of file
正确的
$1
然而,真正发生的情况是,您调用的脚本的参数与$1
调用的 shell 的含义之间似乎存在混淆。bash -c
该行:
find "/mnt/Data/Shared/$1" -type d -exec bash -c '
fixperm "'"${1}"'" "fd" "$0"' {} \;
应该读:
find "/mnt/Data/Shared/$1" -type d -exec bash -c '
fixperm "$1" "fd" "$2"' bash-shell "$1" {} \;
这使得引用更加直接且更加稳健。
简单的
如果脚本内没有循环或其他复杂函数要运行bash -c
,则几乎所有引用都可以删除并写入:
dir="/mnt/Data/Shared"
find "$dir/$1" -type d -exec fixperm "$1" fd {} \;