Как использовать команду «read» в скрипте Shell, который считывает свои аргументы из stdin

Как использовать команду «read» в скрипте Shell, который считывает свои аргументы из stdin

Прежде всего, заранее благодарю за помощь и прошу прощения, если на этот вопрос уже был дан ответ. Я не смог его найти.

Чтобы помочь понять мой вопрос, я написал следующий простой скрипт под названием «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

А это вывод скрипта, передающего «server_list» через stdin:

$ 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" не работает так, как хотелось бы. Имя владельца сервера не запрашивается на экране.

Знаете ли вы, как сделать так, чтобы команда «read» запрашивала строку на экране?

решение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 распознается.

Связанный контент