如何在 Shell 脚本中使用从 stdin 读取参数的命令“read”

如何在 Shell 脚本中使用从 stdin 读取参数的命令“read”

首先,提前感谢您的帮助,如果之前已经回答过这个问题,我很抱歉。我一直找不到它。

为了帮助理解我的问题,我编写了以下名为“list_server_owners”的简单脚本(它没用,但它只是一个例子):

#!/bin/bash

SERVER_LIST=""
SERVER_LIST="$(cat) " # This reads from stdin

for SERVER in $SERVER_LIST
    do
    echo -n "Please, write the server's owner: "
    read OWNER
    echo "${SERVER}'s owner is $OWNER"
    done

我有以下名为“server_list”的文本文件:

Server1
Server2

这是通过 stdin 传递“server_list”的脚本的输出:

$ cat server_list | list_server_owner
Please, write the server's owner: Server1's owner is
Please, write the server's owner: Server2's owner is

问题很容易描述:脚本“read OWNER”这一行没有按我期望的方式工作。屏幕上没有请求显示服务器所有者的名称。

您知道如何让“读取”命令请求屏幕上的字符串吗?

答案1

文件 /dev/tty 是进程控制终端的同义词,因此只需重定向该设备的输入:

...
read OWNER </dev/tty
...

您还可以将 echo 提示的输出重定向到 /dev/tty,然后就可以在管道中使用该脚本:

#!/bin/bash

while read SERVER  # this reads from stdin
do
  echo -n "Please, write the server's owner: " >/dev/tty
  read OWNER </dev/tty
  echo "$SERVER:$OWNER"    # write to stdout
done

并使用如下:

 cat server_list | assign_owner > server_owner

答案2

我找到了解决方案。

您必须添加执行以下操作:

MY_TTY=$(ps -ef | grep -m 1 $$ | awk '{print $6}')
read OWNER </dev/${MY_TTY}

答案3

还有一种可能性,对我来说也是最简单的:

exec 0</dev/tty
read OWNER

这样,您不需要在脚本的所有“读取”命令上指定标准输入。

我很困惑,如果你在脚本中写入命令“tty”,则没有输出,但是,正如最后一条评论所说(谢谢),特殊文件 /dev/tty 可以被识别。

相关内容