Ottenere l'input dell'utente dopo che STDIN è stato reindirizzato, in uno script Bourne
Domanda
(Questa è indirettamente una parte di un incarico di compiti molto più grandi)
Ho qualcosa di simile
while read LINE do stuff-done-to-$LINE echo "Enter input:" read INPUT stuff-done-to-$INPUT done < infile
Non riesco a trovare un modo riuscito di utilizzare la stdin console/predefinita per la seconda lettura, anziché la Stdin reindirizzata.
Deve essere pura sceneggiatura di Bourne.
Soluzione
Credo che questo sia supportato nella shell di Bourne:
exec 3<doc.txt
while read LINE <&3
do
stuff-done-to-$LINE
# the next two lines could be replaced by: read -p "Enter input: " INPUT
echo "Enter input:"
read INPUT
stuff-done-to-$INPUT
done < infile
L'input è alternato tra il file e l'utente. In effetti, questo sarebbe un modo pulito per emettere una serie di istruzioni da un file.
Ciò reindirizza il file "infila" al descrittore del file numero 3 da cui il primo read
ottiene il suo input. Descrittore di file 0 è stdin
, 1 è stdout
e 2 è stderr
. Puoi usare altri FD insieme a loro.
L'ho provato su Bash e Dash (sul mio sistema SH è sinonimo di Dash).
Ovviamente funziona. Ecco un po 'di più divertimento:
exec 3<doc1.txt
exec 4<doc2.txt
while read line1 <&3 && read line2 <&4
do
echo "ONE: $line1"
echo "TWO: $line2"
line1=($line1) # convert to an array
line2=($line2)
echo "Colors: ${line1[0]} and ${line2[0]}"
done
Ciò si alterna a stampare il contenuto di due file, scartando le righe extra di qualunque file sia più lungo.
ONE: Red first line of doc1
TWO: Blue first line of doc2
Colors: Red and Blue
ONE: Green second line of doc1
TWO: Yellow second line of doc2
Colors: Green and Yellow
DOC1 ha solo due righe. La terza riga e le linee successive di DOC2 vengono scartate.
Altri suggerimenti
Puoi leggere/scrivere il terminale dell'utente tramite/dev/tty, questo è indipendente da quale shell stai usando e se stdin/stdout viene reindirizzato, quindi hai solo bisogno di:
echo "Enter input:" > /dev/tty
read INPUT < /dev/tty
Questo dovrebbe funzionare:
for LINE in `cat infile`; do
stuff-done-to-$LINE
echo "Enter input:"
read INPUT
stuff-done-to-$INPUT
done
Non puoi. Non c'è stdin predefinita e reindirizzata stdin. C'è stdin e ciò a cui è collegato è la console o il file.
L'unica cosa che puoi fare è fare un po 'di tempo usando un contatore sul numero di righe del tuo file. Quindi, estrai ogni riga usando un uso intelligente di sed o coda+testa. Non puoi usare while read line
Perché non avresti alcun modo di differenziare la lettura dalla console e la lettura dal file.