Edycja: oryginalny tytuł brzmiał: „odczyt kończy się niepowodzeniem”
W ksh używam read jako wygodnego sposobu na rozdzielanie wartości:
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
2 1
$
Ale kończy się niepowodzeniem:
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
$
Nie znalazłem powodu na stronie podręcznika, dlaczego to się nie udaje, jakiś pomysł?
Odpowiedzi:
bash
uruchamia prawą stronę potoku w kontekście podpowłoki , więc zmiany zmiennych (co sięread
dzieje) nie są zachowywane - umierają, gdy podpowłoka robi to, na końcu polecenia.Zamiast tego możesz użyć podstawienia procesu :
W tym przypadku
read
działa w naszej podstawowej powłoce, a nasze polecenie generujące dane wyjściowe działa w podpowłoce.<(...)
Składnia tworzy podpowłoce i łączy swoje wyjście do rury, którą przekierowania na wejścieread
ze zwykłej<
eksploatacji . Ponieważread
uruchomiono w naszej głównej powłoce, zmienne są ustawione poprawnie.Jak wskazano w komentarzu, jeśli Twoim celem jest dosłowne podzielenie łańcucha na zmienne, możesz użyć łańcucha tutaj :
Zakładam, że jest w tym coś więcej, ale jest to lepsza opcja, jeśli nie ma.
źródło
read a b dump <<< '1 2 3 4 5'
.cat /etc/passwd | (read -r line ; echo $line)
. Ale obokecho
z$line
którym nie jest w rurociągu put nic na ekranie, ponieważ wartość została istniał tylko w nawiasie (podpowłoki). Mam nadzieję, że to komuś pomaga.Nie jest to
bash
błąd, ponieważPOSIX
pozwala zarówno na zachowanie, jakbash
iksh
zachowanie, co prowadzi do niefortunnej rozbieżności, którą obserwujesz.http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_12
Ponadto każde polecenie potoku z wieloma poleceniami znajduje się w środowisku podpowłoki; jednak jako rozszerzenie dowolne lub wszystkie polecenia w potoku mogą być wykonywane w bieżącym środowisku. Wszystkie pozostałe polecenia będą wykonywane w bieżącym środowisku powłoki.
Jednak za pomocą
bash 4.2
i nowszych można ustawićlastpipe
opcję w nieinteraktywnych skryptach, aby uzyskać oczekiwany wynik, np .:Wynik:
źródło
lastpipe
polega na tym, że nie działa on w innych powłokach (np. myślnik). w zasadzie nie ma sposobu, aby zrobić to przenośne, nie uruchamiając wszystkiego w tej podpowłoce, patrz stackoverflow.com/questions/36268479/…