引用

引用

我有一个脚本调用这个

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 {} \;

相关内容