在使用引号操作位置参数后,我的 shell 脚本中出现错误?

Bug in my shell script after manipulating positional parameters with quotes?

在脚本中的这一点之前,我使用 set -- "$@"shift 将调用的位置参数转换为 find

这是我所做的操作示例:

set -- "$@" -iname "\"*\"" -print

下面,我重复我认为我将要执行的内容。但是当我将结果传递给 while 循环时,它不会报告任何文件(与我手动 运行 相比)。

set -x
echo find "$@"
find "$@" 2>/dev/null | while read -r f; do
                            echo found "$f"
                        done                   

这是脚本的输出。 (注意下面的双引号 "。另请注意下面关于我的环境 (BusyBox v1.18.4) set -x 如何不正确显示引号的评论。)

+ echo find /images/dir -follow -maxdepth 1 -type f -iname "*.png" -print -o -iname "*.jpg" -print
find /images/dir -follow -maxdepth 1 -type f -iname "*.png" -print -o -iname "*.jpg" -print
+ read -r f
+ find /images/dir -follow -maxdepth 1 -type f -iname "*.png" -print -o -iname "*.jpg" -print

(一个没有错误的 set -x 打印出 '"*.png"' 而不是 "*.png"。)

如您所见,它没有打印出任何文件名。当我在提示符下检查(我认为是)同样的事情时会发生以下情况:

$ find /images/dir -follow -maxdepth 1 -type f -iname "*.png" -print -o -iname "*.jpg" -print  2>/dev/null | while read -r f; do
> echo found "$f"
> done
found /images/dir/foo.jpg
found /images/dir/bar.png

造成差异的原因是什么?这是在 BusyBox v1.18.4

您的脚本正在查找其中包含文字 " 个字符的文件名。

这意味着您正在做类似的事情:

set -- "$@" -iname '"*.png"'

...而不是正确的选择...

set -- "$@" -iname '*.png'

有关通常导致此错误的一系列误解的详细信息和背景,请参阅 BashFAQ #50。 :)