我运行下面的脚本来对函数中的文件路径运行一些检查 一些路径包含单引号,临时文件包含" $" 如果我将变量括在单引号(下面的名称变量)中,那么如果有一个'则将字符串截断。在文件路径中。如果我在文件路径周围使用双引号,那么如果有" $"则会截断。在路上。 这个循环难题有什么办法吗?
File=/root/fed/~$reader.txt
回显就好像文件路径中有$
/root/fed/eager.txt
如果有'在文件路径中,我附上单引号(以阻止上述发生)然后
File='/root/fed/reader's'
(this wont echo)
代码是:
find / -type f -print0 | xargs -0 -I name bash -c "fnchash 'name'"
fnchash () {
echo "$1"
}
答案 0 :(得分:6)
单引号字符串可能不包含单引号。甚至没有逃脱它们。不带引号或双引号和未转义的$
引入了一个变量引用,它扩展为引用的shell变量的值,如果没有定义这样的变量,则引入任何内容。
一种解决方案涉及双引号和转义字符。例如:
File=/root/fed/~\$reader.txt
File=/root/fed/reader\'s
File="/root/fed/\$reader's.txt"
另请注意,引号不一定是 string 分隔符 - 它们是 sub 字符串分隔符。因此,这些工作也是如此:
File=/root/fed/~'$'reader.txt
File=/root/fed/reader"'"s
如果您需要在运行时自动引用读取的数据,那么您还应该了解bash
的内置printf
命令(这比命令更有用)一个独立的命令)。请特别注意,%q
字段描述符对其参数执行所有必需的引用,以使它们可以作为shell输入重用。
printf '%q' $File
答案 1 :(得分:2)
摆脱这个难题的方法是停止尝试将数据视为代码。此代码段将文件名作为数据(参数)传递,而不是尝试将它们注入代码字符串,从而完全防止这些问题:
$ cat myscript
fnchash () {
for arg
do
printf "Now processing: %s\n" "$arg"
done
}
export -f fnchash
find . -type f -exec bash -c 'fnchash "$@"' _ {} +
$ ls -1
File with space and '.txt
myscript
some file.txt
$ bash myscript
Now processing: ./some file.txt
Now processing: ./myscript
Now processing: ./File with space and '.txt
这使用以下事实:您可以使用位置参数bash -c 'command' argv0 argv1 argv2..
,'command'
,$0
调用$1
来运行$2
。设置为传递的参数打击并处理它们就好像它们是脚本的参数(-c
下的man bash)。
-exec bash -c 'command' _ {} +
运行command
,$0
设置为虚拟值_
,其余参数设置为find
找到的文件名(-exec
下的man find)。
bash命令可以像任何脚本一样处理这些参数。
同样的技术也可以与xargs
一起使用,这里以5个方式并行处理20个文件的块:
find . -type f -print0 | xargs -0 -P 5 -n 20 bash -c 'fnchash "$@"' _
答案 2 :(得分:0)
您可以使用单引号并将所有单引号替换为转义符号来解决此问题, 要么 使用双引号并将所有$替换为已转义的。