为什么这个“while read”在终端中有效,但在 shell 脚本中无效?

为什么这个“while read”在终端中有效,但在 shell 脚本中无效?

我在用信息文本填充 WM 栏时遇到了这个有趣的问题,这是通过设置根窗口的标题来应用的,即xsetroot -name "clever words"

为此,在终端中打印财富效果很好:

fortune -s | while read -r; do xsetroot -name "$REPLY"; done

然而,当从 shell 脚本运行时,同样会失败:

#!/bin/sh
cat /tmp/afile | while read; do echo "$REPLY"; done

生产:

$ sh afilereader
afilereader: 2: 读取: arg 计数

当然,这可以通过将我们的财富结果分配给一个变量,然后使用 xsetroot 与该变量来解决。但我还是想明白为什么这在脚本中不起作用。

我意识到管道两侧的每个命令都在它自己的子 shell 中运行,但无法看到它们的本地化变量如何影响 while read 循环。或者甚至在循环迭代之间变量是否超出范围?

我错过了什么?

更新:sh使用的链接到 dash,它正在变得符合 POSIX 标准。使用更受尊敬的人bash解决了这个问题。

答案1

您似乎正在运行 中的第一个示例bash,以及 所指向的任何内容中的第二个示例/bin/sh,这是一个 POSIX shell,需要传递一个参数来指定您希望将输入放入的变量。将 shebang 更改为#!/bin/bash应该可以解决此问题。

答案2

在 sh 语法中,您需要

IFS= read -r REPLY

有些 shell(如 ksh、bash 和 zsh)允许在read没有变量名的情况下调用,但它们之间的行为有所不同。例如,参见输出

printf 'te\ st\\\na ' | "$shell" -c 'read; printf "%s\n" "<$REPLY>"'

bash、zsh、pdksh 和 ksh93 均有所不同

相关内容