为循环中的变量赋值

and*_*_su 0 bash loops pipe

这里有2段代码,值in $1是包含3行文本的文件名.

现在,我有一个问题.在第一段代码中,我无法从循环中获得"正确"的值,但在第二段代码中,我可以得到正确的结果.我不知道为什么.

如何让第一段代码得到正确的结果?

#!/bin/bash

count=0
cat "$1" | while read line
do
    count=$[ $count + 1 ]
done
echo "$count line(s) in all."

#-----------------------------------------

count2=0
for var in a b c
do
    count2=$[ $count2 + 1 ]
done
echo "$count2 line(s) in all."
Run Code Online (Sandbox Code Playgroud)

use*_*001 5

这是因为while循环之前的管道.它创建一个子shell,因此变量中的更改不会传递给主脚本.要解决此问题,请使用流程替换:

while read -r line
do
    # do some stuff
done < <( some commad)
Run Code Online (Sandbox Code Playgroud)

在4.2或更高版本中,您还可以设置lastpipe选项,管道中的最后一个命令将在当前shell中运行,而不是子shell.

shopt -s lastpipe
some command | while read -r line; do
  # do some stuff
done
Run Code Online (Sandbox Code Playgroud)

在这种情况下,由于您只是使用文件的内容,您可以使用输入重定向:

while read -r line
do
    # do some stuff
done < "$file"
Run Code Online (Sandbox Code Playgroud)