bash 在while循环内读取bash中的输入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6883363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:49:05  来源:igfitidea点击:

Read input in bash inside a while loop

bashwhile-loop

提问by w2lame

I am having a bash script which is something like following,

我有一个 bash 脚本,类似于以下内容,

cat filename | while read line
do
    read input;
    echo $input;
done

but this is clearly not giving me the right output as when I do read in the while loop it tries to read from the file filename because of the possible I/O redirection.

但这显然没有给我正确的输出,因为当我在 while 循环中读取时,由于可能的 I/O 重定向,它尝试从文件 filename 中读取。

Any other way of doing the same?

还有其他方法可以做同样的事情吗?

回答by dank

Read from the controlling terminal device:

从控制终端设备读取:

read input </dev/tty

more info: http://compgroups.net/comp.unix.shell/Fixing-stdin-inside-a-redirected-loop

更多信息:http: //compgroups.net/comp.unix.shell/Fixing-stdin-inside-a-redirected-loop

回答by Gordon Davisson

You can redirect the regular stdin through unit 3 to keep the get it inside the pipeline:

您可以通过单元 3 重定向常规标准输入以将其保持在管道内:

{ cat notify-finished | while read line; do
    read -u 3 input
    echo "$input"
done; } 3<&0

BTW, if you really are using catthis way, replace it with a redirect and things become even easier:

顺便说一句,如果您真的使用cat这种方式,请将其替换为重定向,事情变得更加容易:

while read line; do
    read -u 3 input
    echo "$input"
done 3<&0 <notify-finished

Or, you can swap stdin and unit 3 in that version -- read the file with unit 3, and just leave stdin alone:

或者,您可以在该版本中交换 stdin 和单元 3 - 使用单元 3 读取文件,然后单独保留 stdin:

while read line <&3; do
    # read & use stdin normally inside the loop
    read input
    echo "$input"
done 3<notify-finished

回答by dimba

Try to change the loop like this:

尝试像这样改变循环:

for line in $(cat filename); do
    read input
    echo $input;
done

Unit test:

单元测试:

for line in $(cat /etc/passwd); do
    read input
    echo $input;
    echo "[$line]"
done

回答by Hai Vu

It looks like you read twice, the read inside the while loop is not needed. Also, you don't need to invoke the cat command:

看起来您阅读了两次,不需要 while 循环内的阅读。此外,您不需要调用 cat 命令:

while read input
do
    echo $input
done < filename

回答by xerostomus

I have found this parameter -u with read.

我找到了这个参数 -u 和 read。

"-u 1" means "read from stdin"

“-u 1”表示“从标准输入读取”

while read -r newline; do
    ((i++))
    read -u 1 -p "Doing $i""th file, called $newline. Write your answer and press Enter!"
    echo "Processing $newline with $REPLY" # united input from two different read commands.
done <<< $(ls)

回答by Munchk1n

echo "Enter the Programs you want to run:"
> ${PROGRAM_LIST}
while read PROGRAM_ENTRY
do
   if [ ! -s ${PROGRAM_ENTRY} ]
   then
      echo ${PROGRAM_ENTRY} >> ${PROGRAM_LIST}
   else
      break
   fi
done