Bash: leggere l'input all'interno mentre il ciclo di lettura non funziona


14

La lettura dell'input in un ciclo di lettura un po 'non sembra funzionare

while read line
do
 echo "get some input from the user"
 read response
done < some_file.txt

l'esecuzione non si interrompe come se la lettura fosse fuori dal ciclo. Perchè è questo? Esiste una soluzione alternativa per leggere l'input in un ciclo di lettura while?

Risposte:


15

Il problema è che sia read linee read responsedi dati si aspetta (e ottiene) da stdin.
Questa domanda su SO ne spiega alcune con un collegamento a ulteriori informazioni.

tl; dr
La risposta accettata suggerisce:

Leggi dal dispositivo terminale di controllo: read input </dev/tty


16

lascia che il comando di lettura interno usi stdin e usa un descrittore di file diverso per il ciclo while

while read -u 3 line; do
  read -p "get some input from the user" response
done 3< some_file.txt

1

Nifle ha esattamente ragione. Quando si utilizzano più terminali, tuttavia, è necessario essere specifici.

Per quelli di voi che provengono da Google, congratulazioni per aver trovato questa pagina. Se avete bisogno di fare alcun input da parte dell'utente nel corso di un ciclo while lettura (questo include rm -i, reado qualsiasi altra cosa), è possibile specificare che il tubo di alimentazione da utilizzare.

Ecco un frammento di questa soluzione che ho usato:

#in declarations
thistty=$(tty)

lsuser -R LDAP -a home pgrp ALL 2>/dev/null | while read line
do
   homedir=$(echo $homedir | awk -F= '{print $2}')
   sudo rm -ir "$homedir" < $thistty
done

1

Grazie Nifle! E anche grazie a bgStack. Dopo aver cercato per ore ho finalmente ottenuto la risposta! Grande !! Ho usato "echo $ (tty)" per rilevare il mio percorso terminale o lo prendi semplicemente come variabile. Per me è stato un altro caso d'uso. U stava leggendo un file e vorrei confermare l'esecuzione. Forse l'esempio che segue aiuta qualcun altro.

#!/bin/bash

export terminal=$(tty)

cat file | while read val1 val2
do
   while true; 
            do
              read -p "would you like to XYZ" yn
              case $yn in
                        [Yy]* )     echo "# Move $val1 to $val2        #";break;;
                        [Nn]* )     echo "#---------no action----------#";break;;
                        * )         echo "# Please answer yes or no.   #";;
              esac
            done < $terminal
done

Nel mio caso ho avuto whilela lettura da un tubo ... e poi ho usato il reindirizzamento a leggere da stdin: read something < %terminal.
eftshift0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.