標準入力から引数を読み取るシェル スクリプトでコマンド「read」を使用する方法

標準入力から引数を読み取るシェル スクリプトでコマンド「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」行が期待どおりに動作していません。サーバーの所有者の名前が画面に要求されていません。

コマンド「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 は認識されます。

関連情報