简体   繁体   English

如何在while-loop读取行中读取用户?

[英]How to read from user within while-loop read line?

I had a bash file which prompted the user for some parameters and used defaults if nothing was given. 我有一个bash文件,它提示用户输入一些参数,如果没有给出任何参数则使用默认值。 The script then went on to perform some other commands with the parameters. 然后该脚本继续使用参数执行一些其他命令。 This worked great - no problems until most recent addition. 这很有效 - 直到最近添加才有问题。

In an attempt to read the NAMES parameter from a txt file, I've added a while-loop to take in the names in the file, but I would still like the remaining parameters prompted for. 为了尝试从txt文件中读取NAMES参数,我添加了一个while循环来接收文件中的名称,但我仍然希望提示其余的参数。

But once I added the while loop, the output shows the printed prompt in get_ans() and never pauses for a read, thus all the defaults are selected. 但是一旦我添加了while循环,输出就会在get_ans()中显示打印的提示,并且永远不会暂停读取,因此会选择所有默认值。

I would like to read the first parameter from a file, then all subsequent files from prompting the user. 我想从文件中读取第一个参数,然后从提示用户读取所有后续文件。

What did I break by adding the while-loop? 通过添加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
}

(NOTE: Code is not copy&paste so please excuse typos. Actual code has function defined before the main()) (注意:代码不是复制和粘贴,所以请原谅错别字。实际代码在main()之前定义了函数)

You pipe data into your the while loops STDIN. 您将数据传输到while循环STDIN。 So the read in get_ans is also taking data from that STDIN stream. 因此get_ansread也从该STDIN流中获取数据。

You can pipe data into while on a different file descriptor to avoid the issue and stop bothering with temp files: 您可以在不同的文件描述符上管理数据,以避免问题并停止使用临时文件:

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}"
}

To read directly from the terminal, not from stdin (assuming you're on a *NIX machine, not a Windows machine): 要直接从终端读取,而不是从stdin读取(假设您使用的是* NIX机器,而不是Windows机器):

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

When you pipe one command into another on the command line, like: 在命令行上将一个命令传递给另一个命令时,如:

$ foo | bar

The shell is going to set it up so that bar 's standard input comes from foo 's standard output. shell将进行设置,以便bar的标准输入来自foo的标准输出。 Anything that foo sends to stdout will go directly to bar 's stdin. foo发送到stdout的任何内容都会直接转到bar的stdin。

In your case, this means that the only thing that your script can read from is the standard output of the cat command, which will contain the contents of your file. 在您的情况下,这意味着您的脚本可以读取的唯一内容是cat命令的标准输出,它将包含文件的内容。

Instead of using a pipe on the command line, make the filename be the first parameter of your script. 不要在命令行上使用管道,而是将文件名作为脚本的第一个参数。 Then open and read from the file inside your code and read from the user as normal. 然后打开并从代码中的文件中读取并正常读取用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM