【问题标题】:How to read from user within while-loop read line?如何在while循环读取行中从用户读取?
【发布时间】:2012-03-30 02:38:20
【问题描述】:

我有一个 bash 文件,它提示用户输入一些参数,如果没有给出任何参数,则使用默认值。然后脚本继续使用参数执行一些其他命令。 这很有效 - 直到最近添加之前没有问题。

在尝试从 txt 文件中读取 NAMES 参数时,我添加了一个 while 循环来接收文件中的名称,但我仍然希望提示输入其余参数。

但是一旦我添加了 while 循环,输出会在 get_ans() 中显示打印的提示,并且不会暂停读取,因此选择了所有默认值。

我想从文件中读取第一个参数,然后从提示用户中读取所有后续文件。

我通过添加 while 循环破坏了什么?

cat list.txt | 
while read line
do 
  get_ans "Name" "$line"
  read NAME < $tmp_file

  get_ans "Name" "$line"
  read NAME < $tmp_file
done

function get_ans
{
  if [ -f $tmp_file ]; then
    rm $tmp_file

  PROMPT=$1
  DEFAULT=$2

  echo -n "$PROMPT [$DEFAULT]: "
  read ans
  if [ -z "$ans" ]; then
    ans="$DEFAULT"
  fi
  echo "$ans" > $tmp_file
}

(注意:代码不是复制粘贴,所以请原谅拼写错误。实际代码在 main() 之前定义了函数)

【问题讨论】:

  • 在决定接受之前,我会先看看你的其他答案(其中一个告诉你如何解决问题,而不仅仅是它是什么)。跨度>

标签: linux bash while-loop


【解决方案1】:

当您在命令行上将一个命令传递给另一个命令时,例如:

$ foo | bar

shell 将对其进行设置,以便bar 的标准输入来自foo 的标准输出。 foo 发送到标准输出的任何内容都将直接发送到 bar 的标准输入。

在您的情况下,这意味着您的脚本可以读取的唯一内容是 cat 命令的标准输出,其中将包含您的文件内容。

不要在命令行上使用管道,而是将文件名作为脚本的第一个参数。然后打开并从代码中的文件读取,并正常从用户读取。

【讨论】:

  • 好的,很好,这是有道理的。谢谢
  • 好的,移除管道并在读取行时使用; do ... done
【解决方案2】:

您将数据通过管道传输到 while 循环 STDIN。所以get_ans 中的read 也从该STDIN 流中获取数据。

您可以在不同的文件描述符上将数据通过管道传输到 while 以避免问题并停止使用临时文件:

while read -u 9 line; do
   NAME=$(get_ans Name "$line")
done 9< list.txt

get_ans() {
    local PROMPT=$1 DEFAULT=$2 ans
    read -p "$PROMPT [$DEFAULT]: " ans
    echo "${ans:-$DEFAULT}"
}

【讨论】:

    【解决方案3】:

    直接从终端读取,而不是从标准输入(假设您在 *NIX 机器上,而不是 Windows 机器上):

    while read foo</some/file; do
        read bar</dev/tty
        echo "got <$bar>"
    done
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-09
      • 2020-10-21
      • 2012-10-18
      • 2013-07-08
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 2018-09-05
      相关资源
      最近更新 更多