【问题标题】:for loop executes wrongly when no file found [duplicate]找不到文件时,for循环执行错误[重复]
【发布时间】:2013-04-20 07:35:54
【问题描述】:

我有这个 bash "for in" 循环,它在目录中查找 pdf 文件并提示它们(为示例而简化)

#!/bin/bash
for pic in "$INPUT"/*.pdf
do
    echo "found: ${pic}"
done

当 $INPUT 目录中有 pdf 文件时,此脚本运行良好,但是,当目录中没有 pdf 文件时,我得到:

找到:/home/.../input-folder/*.pdf

这是预期的行为吗? 如何使用 for in 循环处理它? 我需要使用 ls 还是 find ?

我试过在“$INPUT”周围加引号和不加引号。文件名和目录名中不能有空格。

【问题讨论】:

标签: bash file-extension for-in-loop


【解决方案1】:

这是预期的行为。根据bash man page,在路径名扩展部分:

分词后,除非设置了 -f 选项,否则 bash 会在每个单词中扫描字符 *、? 和 [。如果出现这些字符之一,则该词被视为一种模式,并替换为按字母顺序排列的与该模式匹配的文件名列表。 如果没有找到匹配的文件名,并且 shell 选项 nullglob 未启用,则单词保持不变。

因此,如果没有找到 "$INPUT"/*.pdf 的匹配项,则循环将在模式本身上执行。但是在手册页的下一句中:

如果设置了 nullglob 选项,但没有找到匹配项,则删除该单词。

这就是你想要的!所以就这样做吧:

#!/bin/bash
shopt -s nullglob
for pic in "$INPUT"/*.pdf
do
    echo "found: ${pic}"
done

(但请注意,这可能会以意想不到的方式改变其他事物的行为。例如,尝试运行 shopt -s nullglob; ls *.unmatchedextension 看看会发生什么。)

【讨论】:

    【解决方案2】:

    我会像这样添加一个文件存在测试:

    #!/bin/bash
    if test -e `echo "$INPUT"/*.pdf | cut -d' ' -f1`
    then
        for pic in "$INPUT"/*.pdf
        do
            echo "found: ${pic}"
        done
    fi
    

    【讨论】:

    • 如果"$INPUT"/*.pdf 匹配多个文件(参数太多),test 命令可能会失败。
    • 你是对的 - 答案已更正
    • 更接近,但如果生成的第一个文件名包含空格,test 仍然可能失败; cut 将输出部分路径,而不是整个路径。
    猜你喜欢
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多