2012-03-13 15 views
5

Miałem plik bash, który monitował użytkownika o niektóre parametry i używał domyślnych, jeśli nic nie zostało podane. Następnie skrypt wykonał kilka innych poleceń z parametrami. To działało świetnie - bez problemów do ostatniego dodania.Jak czytać od użytkownika w linii odczytu pętli while?

Próbując odczytać parametr NAMES z pliku txt, dodałem pętlę while, aby pobrać nazwy w pliku, ale nadal chciałbym, aby pozostałe parametry były monitowane.

Ale raz dodałem pętlę while, wyjście pokazuje drukowany znak zachęty w get_ans() i nigdy nie pauzuje dla odczytu, więc wszystkie wartości domyślne są wybrane.

Chciałbym odczytać pierwszy parametr z pliku, a następnie wszystkie kolejne pliki od pytania użytkownika.

Co złamałem, dodając pętlę while?

cat list.txt | 
while read line 
do 
    get_ans "Name" "$line" 
    read NAME < $tmp_file 

    get_ans "Name" "$line" 
    read NAME < $tmp_file 
done 

function get_ans 
{ 
    if [ -f $tmp_file ]; then 
    rm $tmp_file 

    PROMPT=$1 
    DEFAULT=$2 

    echo -n "$PROMPT [$DEFAULT]: " 
    read ans 
    if [ -z "$ans" ]; then 
    ans="$DEFAULT" 
    fi 
    echo "$ans" > $tmp_file 
} 

(UWAGA:. Kodeks nie jest skopiować & pasty więc proszę wybaczyć literówki rzeczywisty kod jest funkcja określona przed main())

+0

będę patrzeć na innych odpowiedzi, z których (jeden mówi, jak _solve_ problem, nie tylko to, co to jest) przed podjęciem decyzji, aby zaakceptować. –

Odpowiedz

3

Wężysz dane do swoich pętli while STDIN. Tak więc read w get_ans również pobiera dane z tego strumienia STDIN.

Można dane rurę w czasie na innym deskryptora pliku, aby uniknąć tego problemu i nie kłopotać z plikami temp:

while read -u 9 line; do 
    NAME=$(get_ans Name "$line") 
done 9< list.txt 

get_ans() { 
    local PROMPT=$1 DEFAULT=$2 ans 
    read -p "$PROMPT [$DEFAULT]: " ans 
    echo "${ans:-$DEFAULT}" 
} 
+0

zrozumiano, gdy przeczytano <& 9 –

1

Gdy rura jedno polecenie do drugiego w linii poleceń, takich jak:

$ foo | bar 

powłoka ma zamiar ustawić go tak, że bar „s standardowe wejście pochodzi z foo” standardowe wyjście s. Wszystko, co foo wysyła na standardowe wyjście, trafi bezpośrednio do stdin z bar.

W twoim przypadku oznacza to, że jedyną rzeczą, którą twój skrypt może odczytać, jest standardowe wyjście komendy cat, które będzie zawierać zawartość twojego pliku.

Zamiast używać potoku w linii komend, ustaw nazwę pliku jako pierwszy parametr skryptu. Następnie otwórz i odczytaj z pliku wewnątrz kodu i odczytaj od niego normalnie.

+0

Okay świetnie, to ma sens. Dziękuję –

+0

OK, usunięto rurę i używano podczas czytania linii; zrobić ... zrobić <1 $ i nadal pomija odczytane dane wejściowe. –

3

Aby odczytać bezpośrednio z terminala, a nie ze standardowego wejścia (zakładając, że jesteś na * NIX maszyna, a nie maszyna Windows):

while read foo</some/file; do 
    read bar</dev/tty 
    echo "got <$bar>" 
done