在 POSIX shell 中使用while 循环来处理文本通常被认为是不好的做法吗?
正如Stéphane Chazelas 所指出的,不使用 shell 循环的一些原因是概念、可靠性、易读性、性能和安全性。
这个答案解释了可靠性和易读性方面:
while IFS= read -r line <&3; do
printf '%s\n' "$line"
done 3< "$InputFile"
Run Code Online (Sandbox Code Playgroud)
为了性能,从文件或管道读取时,while循环和读取非常慢,因为内置的read shell一次读取一个字符。
怎么样的概念和安全性方面?
我想在命令行上显示文本文件的内容。该文件仅包含 5-6 个字符。是否有捷径可寻?
过去的旧建议是对任何涉及 a 的表达式加双引号$VARIABLE,至少在希望 shell 将其解释为单个项目的情况下,否则,内容中的任何空格$VARIABLE都会脱离 shell。
但是,我知道在较新版本的 shell 中,不再总是需要双引号(至少出于上述目的)。例如,在bash:
% FOO='bar baz'
% [ $FOO = 'bar baz' ] && echo OK
bash: [: too many arguments
% [[ $FOO = 'bar baz' ]] && echo OK
OK
% touch 'bar baz'
% ls $FOO
ls: cannot access bar: No such file or directory
ls: cannot access baz: No such file or directory
Run Code Online (Sandbox Code Playgroud)
在zsh,而另一方面,同样的三个命令成功。因此,基于此实验,似乎在 中bash可以省略 内部的双引号[[ ... ]],但不能省略内部 …
我以前用来cat查看文件。然后我了解到这less通常更好,如果文件长于几十行,这是必须的。
我的问题:有没有理由使用cat而不是less?有没有cat更好的解决方案?
我使用了一个文件描述符
mkfifo fifo
Run Code Online (Sandbox Code Playgroud)
一旦有东西写入这个管道,我想立即重用它。我应该使用
tail -f fifo
Run Code Online (Sandbox Code Playgroud)
或者
while true; do cat fifo; done
Run Code Online (Sandbox Code Playgroud)
?
他们似乎做同样的事情,我无法衡量性能差异。但是,当系统不支持inotify(例如Busybox)时,前者需要
tail -f -s 0 fifo
Run Code Online (Sandbox Code Playgroud)
但这会以 100% 的使用率消耗 CPU(测试一下:mkfifo fifo && busybox tail -f -s 0 fifo & echo hi>fifo/ 用fg 1和取消CtrlC)。那么 while-true-cat 是更可靠的解决方案吗?