在bash中,有什么区别吗;而read-r行;做完成<;file`和'cat file |而IFS=read-r行;做完成了吗?

在bash中,有什么区别吗;而read-r行;做完成<;file`和'cat file |而IFS=read-r行;做完成了吗?,bash,Bash,我正在学习bash,我在互联网上找到了一个教程,上面说这些都是一样的: while read -r line; do ... done < file $ cat file | while IFS= read -r line; do ... done 读取-r行时; 做 ... 完成foo=$line#假设$line不是5 >完成 $echo$foo 5. $while IFS=读取-r行;做 >foo=$line >done

我正在学习bash,我在互联网上找到了一个教程,上面说这些都是一样的:

while read -r line;
do
    ...
done < file

$ cat file | while IFS= read -r line;
do
    ...
done
读取-r行时
;
做
...
完成<文件
$cat file |而IFS=read-r行;
做
...
完成

这两个循环是否有细微的区别?它们是否真的相同?

最大的区别是在管道中,
while
循环在子shell中执行,因此如果更改
while
主体中任何变量的值,管道完成后这些变量将丢失

$ foo=5
$ cat file | while IFS= read -r line; do
>    foo=$line  # assume $line is not 5
> done
$ echo $foo
5
$ while IFS= read -r line; do
>  foo=$line
> done < file  # Assume one line with the word foo
$ echo $foo
foo
$foo=5
$cat file |而IFS=read-r行;做
>foo=$line#假设$line不是5
>完成
$echo$foo
5.
$while IFS=读取-r行;做
>foo=$line
>done
bash
4.2中,这可以通过使用
lastpipe
选项来缓解,该选项允许管道中的最后一个命令在当前shell而不是子shell中执行


除此之外,使用输入重定向的版本效率更高,因为它不需要启动额外的进程。

除了chepner对子shell的观察之外,其中一个循环使用了
IFS=
,而另一个则不使用

read
使用此变量拆分单词。对于一个变量,这会影响前导和尾随空格

如果使用
IFS=
,它将被保留:

$ IFS= read -r line <<< "   test   "
$ printf "<%s>\n" "$line"
<   test   >
$IFS=read-r行
否则,它将被剥离:

$ read -r line <<< "   test   "
$ printf "<%s>\n" "$line"
<test>

$read-r line我的建议是:不要解析
cat
命令的输出。为了放大切普纳已经提到的内容:一般来说
cat foo | bar
bar相反,这两个循环都应该有
IFS=
?@那不是,只是第二个循环。IFS=在第二个循环中做什么?回答得好!当我提到“cat的无用使用”时,我经常忘记变量作用域的事情:(1)但它们都有while循环?对不起,我没有明确说明哪个构造需要子shell;编辑。