嵌套bash while循环不接受用户输入

时间:2016-01-29 17:53:37

标签: bash while-loop nested

我试图用bash编写(Mac OSX但安装了GNU shell程序)a"是或否"从输入文件中逐行迭代读取。举个例子,假设我有一个数字从1到5(逐行)的文件作为输入,我想问他们是素数。

#!bin/bash
while read NUMBER
  do echo "Prime number (answer y or n)?"
  while read ANSWER
  do
    test "$ANSWER" == "y" && echo "Prime" && break
    test "$ANSWER" == "n" && echo "Non-prime" && break
    test "$ANSWER" != "y" -a "$ANSWER" != "n" && echo "Type y or n"
  done
done < 1_to_5_file.txt

以下输出不会打开用户输入

Prime number (answer y or n)?
Type y or n
Type y or n
Type y or n

1 个答案:

答案 0 :(得分:1)

因为外部while循环的stdin(脚本的输入)设置为从1_to_5_file.txt读取,所以继承到while循环内运行的所有命令。解决这个问题的一种方法是将原始stdin保存在不同的描述符中,然后我们可以在循环中使用它。在我的例子中,我将它存储在文件描述符3中。

#!/bin/bash
while read NUMBER
  do echo "Prime number (answer y or n)?"
  while read ANSWER
  do
    test "$ANSWER" == "y" && echo "Prime" && break
    test "$ANSWER" == "n" && echo "Non-prime" && break
    test "$ANSWER" != "y" -a "$ANSWER" != "n" && echo "Type y or n"
  done 0<&3
done 3<&0 < 1_to_5_file.txt

最后一行在文件描述符3中创建文件描述符0的副本。然后在循环文件描述符3中指向原始标准输入。在内部while循环的最后一行,然后我将文件描述符3复制到文件描述符0,从而使循环内的stdin再次指向原始stdin。

为了记录,&#34;&lt;&#34;与&#34; 0&lt;&#34;相同和&#34;&gt;&#34;与&#34; 1&gt;&#34;相同。因此,0<&3也可以只写<&3

@chepner提出的另一个更精确的解决方案是打开文件描述符3上的1_to_5_file.txt,而只是改变第一个读取命令而不是从那个读取:

#!/bin/bash
while read NUMBER <&3
  do echo "Prime number (answer y or n)?"
  while read ANSWER
  do
    test "$ANSWER" == "y" && echo "Prime" && break
    test "$ANSWER" == "n" && echo "Non-prime" && break
    test "$ANSWER" != "y" -a "$ANSWER" != "n" && echo "Type y or n"
  done
done 3< 1_to_5_file.txt

请注意,与问题中的代码相比,最后一行包含3<而非3