为什么 bash while 循环尝试处理 find 不存在的结果?

Why does bash while loop try to process non-existent results of find?

我有一个 bash 脚本,它使用 while 循环来获取从 find 命令返回的每个文件的基本名称。我在这里将它简化为一行:

$ while read myFile; do echo $(basename $myFile) ; done <<< $(find ./*test*  -maxdepth 1 -type f -exec ls {} + 2>/dev/null)
testRelease.sh

在 find 命令没有结果的情况下,我预计 while 语句的条件未满足,“do”部分被忽略。事实并非如此:

$ while read myFile; do echo $(basename $myFile) ; done <<< $(find ./*noMatch*  -maxdepth 1 -type f -exec ls {} + 2>/dev/null)
basename: missing operand
Try `basename --help' for more information.

看起来好像 while 语句添加了条件试图处理的空行:

$ while read myFile; do echo $myFile ; done <<< $(find ./*noMatch*  -maxdepth 1 -type f -exec ls {} + 2>/dev/null)

$

当 运行 独立查找命令时,不会出现此空行。什么添加了这个空行,为什么while语句在没有找到结果的情况下处理它?

请让我将您的命令简化为:

while read line; do
    echo "line read"
done <<< $(find . 1>/dev/null)

find 命令不输出任何内容,上面的代码等同于:

while read line; do
    echo "line read"
done <<< ""

它仍然打印“line read”。 bash 的联机帮助页说:

A variant of here documents, the format is:

[n]<<<word

[lines snipped]
The result is supplied as a single string, with a newline appended, to the command on its standard input (or file descriptor n if n is specified).

然后while循环读取空行执行echo.
如果将代码修改为:

while read line; do
    echo "line read"
done < <(find . 1>/dev/null)

它不会输出任何内容。

What is adding this blank line

此处的字符串 <<< 正在添加尾随空行。如果你不想要它,你可以使用进程替换来代替:

while read var; do ...; done < <(someCommand)

但是,在您的情况下,您根本不需要循环。 find -exec 可以更快更安全地为您完成工作:

find ./*test* -maxdepth 1 -type f -exec basename {} \; 2>/dev/null

即使没有输出,您也至少将一个空字符串输入循环。您可以使用保证不会产生任何输出的命令来尝试它。我在这个实验中使用空命令 :

while read; do echo read=$REPLY; done  <<<$(:)

产生一个输出行,表示只是

阅读=