Czy ktoś mógłby wyjaśnić, jak działa następujący kod?
echo '1 2 3 4 5 6' | while read a b c
do
echo $c $b $a
done
W szczególności chciałbym wiedzieć, dlaczego wyjście tej pętli jest 3 4 5 6 2 1
zamiast 3 2 1
i 6 5 4
na dwóch osobnych liniach? Nie mogę się tym zająć ...
Przepisanie pętli w ten sposób ujawnia, co się dzieje:
Daje to jako wynik:
Zauważ najpierw, że uruchamiane jest tylko jedno polecenie echa. Gdyby został uruchomiony więcej niż jeden raz, zobaczyłbyś między innymi napisy
(iteration beginning)
i(iteration ending)
napisy wydrukowane więcej niż jeden raz.To znaczy, że
while
pętla tutaj tak naprawdę niczego nie osiąga.read
Wbudowane odczytuje białymi oddzielone tekst 1 do każdej zmiennej określonej. Dodatkowe dane wejściowe są dołączane na końcu ostatniej określonej zmiennej. 2 W ten sposób zmiennea
ib
odbioru o wartości1
i2
, odpowiednio, ac
przyjmuje wartości3 4 5 6
.Gdy warunek pętli (
while read a b c
) jest oceniany po raz drugi, nie ma już żadnych danych wejściowych z potoku (przesłaliśmy do niego tylko jeden wiersz tekstu), więcread
polecenie ocenia na fałsz zamiast prawdy, a pętla zatrzymuje się (przed wykonaniem polecenia ciało po raz drugi).1 : Aby mieć charakter techniczny i konkretne, wbudowane , gdy przeszedł nazw zmiennych jako argumenty, odczytuje wejścia, dzieląc go na odrębne „słów” , gdy napotka IFS spacje (patrz również na to pytanie i ten artykuł ).
read
2 :
read
zachowanie polegające na blokowaniu jakichkolwiek dodatkowych pól danych wejściowych w ostatniej określonej zmiennej jest początkowo nieintuicyjne dla wielu skrypterów. Łatwiej jest to zrozumieć, gdy weźmie się pod uwagę, że, jak mówi odpowiedź Floriana Diescha ,read
zawsze (spróbuje) przeczytać całą linię - iread
ma to być użyteczne zarówno z pętlą, jak i bez niej.źródło
while
w tym przykładzie nie spełniło to normalnego celu, ale potemread
polecenie mnie wyrzuciło ... W jakiś sposób zinterpretowałem to jako „choćread a b c
nie jest to fałsz, zróbecho ...
”. Dziękujemy za wyjaśnienie, jak to naprawdę działało. Wczoraj natknąłem się na ten kod i wiedziałem, że to mnie zaskoczy, dopóki go nie rozgryzłem ... lolread a b c
, gdy zostanie ustawiona wartość true, a warunek pętli (read a b c
) działa więcej niż jeden raz. Bit, który ocenia jako prawdziwy tylko za pierwszym razem. Za drugim razem nie ma więcej danych do odczytu z potoku, więc napotyka się koniec pliku , co powodujeread
zwrócenie wartości false . (Szczegółowe informacje można znaleźć w ostatniej sekcji wynikuhelp read
„Statusu wyjścia”, zauważając, że w skrypcie powłoki zero oznacza prawda, a niezerowe oznacza fałsz.) Jeśli potokowałeś więcej niż jeden wiersz danych wejściowychwhile read ...
, treść pętli zostać wykonanym wiele razy.