Como usar o comando “read” em um script Shell que lê seus argumentos do stdin

Como usar o comando “read” em um script Shell que lê seus argumentos do stdin

Primeiramente, obrigado antecipadamente pela sua ajuda e desculpe caso isso tenha sido respondido antes. Não consegui encontrá-lo.

Para ajudar a entender minha dúvida, escrevi o seguinte script simples chamado "list_server_owners" (é inútil, mas é apenas um exemplo):

#!/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

Eu tenho o seguinte arquivo de texto chamado "server_list":

Server1
Server2

E esta é a saída do script passando "server_list" através do 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

O problema é fácil de descrever: a linha do script “read OWNER” não está funcionando como eu gostaria. O nome do dono do servidor não está sendo solicitado na tela.

Você sabe como posso fazer com que o comando "ler" solicite uma string na tela?

Responder1

O arquivo /dev/tty é sinônimo de terminal de controle do processo, então basta redirecionar a entrada desse dispositivo:

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

Você também pode redirecionar a saída do prompt de eco anterior para /dev/tty e, então, poder usar o script em um canal:

#!/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

E use como:

 cat server_list | assign_owner > server_owner

Responder2

Eu encontrei a solução.

Você tem que adicionar faça isso:

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

Responder3

Outra possibilidade, e é a mais simples para mim:

exec 0</dev/tty
read OWNER

Com isso, você não precisa especificar a entrada padrão em todos os comandos de “leitura” ao longo do script.

Fiquei confuso porque se você escrever o comando "tty" dentro do script não haverá saída, mas, como diz o último comentário (obrigado), o arquivo especial /dev/tty é reconhecido.

informação relacionada