So verwenden Sie den Befehl "read" in einem Shell-Skript, das seine Argumente von stdin liest

So verwenden Sie den Befehl "read" in einem Shell-Skript, das seine Argumente von stdin liest

Zunächst einmal vielen Dank im Voraus für Ihre Hilfe und entschuldigen Sie, falls dies bereits beantwortet wurde. Ich konnte es nicht finden.

Zum besseren Verständnis meiner Frage habe ich das folgende einfache Skript mit dem Namen „list_server_owners“ geschrieben (es ist nutzlos, aber nur ein Beispiel):

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

Ich habe die folgende Textdatei namens "server_list":

Server1
Server2

Und dies ist die Ausgabe des Skripts, das „server_list“ über stdin übergibt:

$ 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

Das Problem ist einfach zu beschreiben: Die Zeile des Skripts "read OWNER" funktioniert nicht wie ich es gerne hätte. Der Name des Serverbesitzers wird auf dem Bildschirm nicht abgefragt.

Wissen Sie, wie ich mit dem Befehl „Lesen“ eine Zeichenfolge auf dem Bildschirm anfordern kann?

Antwort1

Die Datei /dev/tty ist ein Synonym für das Steuerterminal des Prozesses. Leiten Sie die Eingabe also einfach von diesem Gerät um:

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

Sie können die Ausgabe des Echo-Prompts auch vorher nach /dev/tty umleiten und das Skript dann in einer Pipe verwenden:

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

Und verwenden Sie Folgendes:

 cat server_list | assign_owner > server_owner

Antwort2

Ich habe die Lösung gefunden.

Sie müssen Folgendes hinzufügen:

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

Antwort3

Eine andere Möglichkeit, und für mich die einfachste:

exec 0</dev/tty
read OWNER

Damit müssen Sie nicht bei allen „Lese“-Befehlen im Skript die Standardeingabe angeben.

Ich war verwirrt, weil keine Ausgabe erfolgt, wenn man den Befehl „tty“ in das Skript schreibt, aber, wie im letzten Kommentar steht (danke), die spezielle Datei /dev/tty erkannt wird.

verwandte Informationen