Próbuję uzyskać bash do przetwarzania danych ze standardowego wejścia, które jest przesyłane do, ale bez powodzenia. Mam na myśli to, że żadna z następujących prac:
echo "hello world" | test=($(< /dev/stdin)); echo test=$test
test=
echo "hello world" | read test; echo test=$test
test=
echo "hello world" | test=`cat`; echo test=$test
test=
gdzie chcę, aby wynik był test=hello world
. Próbowałem wstawiać cytaty "$test"
, ale to też nie działa.
shopt -s lastpipe
- tldp.org/LDP/abs/html/bashver4.html#LASTPIPEOPTOdpowiedzi:
Posługiwać się
Państwo może skłonić
read
do przyjęcia z rury tak:lub nawet napisz taką funkcję:
Ale nie ma sensu - przypisania zmiennych mogą nie trwać! Potok może odrodzić podpowłokę, w której środowisko jest dziedziczone przez wartość, a nie przez referencję. To dlatego
read
nie przeszkadza wejście z potoku - jest niezdefiniowane.FYI, http://www.etalabs.net/sh_tricks.html to sprytna kolekcja cruft niezbędna do zwalczania osobliwości i niekompatybilności muszli Bourne'a, sh.
źródło
test=`echo "hello world" | { read test; echo $test; }`
{}
zamiast()
grupować te dwa polecenia?read
pobieraniu danych z potoku, ale na używaniu zmiennej w tej samej powłoce, która wykonuje polecenieread
.bash permission denied
gdy próbujesz użyć tego rozwiązania. Moja sprawa jest zupełnie inna, ale nie mogłem znaleźć odpowiedź na to gdzie, co pracował dla mnie (inny przykład, ale podobną użycia)pip install -U echo $(ls -t *.py | head -1)
. Na wypadek, gdyby ktoś miał podobny problem i natknął się na tę odpowiedź, tak jak ja.jeśli chcesz czytać wiele danych i pracować nad każdą linią osobno, możesz użyć czegoś takiego:
jeśli chcesz podzielić wiersze na wiele słów, możesz użyć wielu zmiennych zamiast x:
alternatywnie:
Ale gdy tylko zaczniesz robić coś naprawdę sprytnego z tego rodzaju rzeczami, lepiej wybrać język skryptowy, taki jak Perl, w którym możesz spróbować czegoś takiego:
W Perlu jest dość stroma krzywa uczenia się (lub, jak sądzę, któregoś z tych języków), ale na dłuższą metę będzie ci o wiele łatwiej, jeśli chcesz robić tylko najprostsze skrypty. Poleciłbym Perl Cookbook i, oczywiście, Perl Programming Language autorstwa Larry'ego Walla i in.
źródło
read
nie będzie czytać z potoku (być może wynik zostanie utracony, ponieważ potok tworzy podpowłokę). Możesz jednak użyć ciągu tutaj w Bash:Ale zobacz odpowiedź @ chepnera, aby uzyskać informacje na temat
lastpipe
.źródło
To kolejna opcja
źródło
<(..)
jest$(..)
to, że<(..)
zwraca każdą linię dzwoniącemu, gdy tylko polecenie, które wykonuje, udostępnia ją.$(..)
, jednak czeka na zakończenie komendy i wygenerowanie wszystkich danych wyjściowych, zanim udostępni dane wywołujące.Nie jestem ekspertem w Bash, ale zastanawiam się, dlaczego nie zaproponowano tego:
Jednoliniowy dowód, że to działa dla mnie:
źródło
bash
4.2 wprowadzalastpipe
opcję, która pozwala twojemu kodowi działać tak, jak napisano, wykonując ostatnie polecenie w potoku w bieżącej powłoce, a nie w podpowłoce.źródło
Składnia niejawnego potoku z polecenia powłoki do zmiennej bash to
lub
W swoich przykładach przesyłasz dane do instrukcji przypisania, która nie oczekuje żadnych danych wejściowych.
źródło
Pierwsza próba była dość bliska. Ta odmiana powinna działać:
a wynikiem jest:
Potrzebne są nawiasy klamrowe za rurą, aby zamknąć zadanie do przetestowania i echa.
Bez nawiasów przypisanie do testowania (po potoku) znajduje się w jednej powłoce, a echo „test = $ test” znajduje się w osobnej powłoce, która nie wie o tym przypisaniu. Dlatego otrzymujesz „test =” w danych wyjściowych zamiast „test = witaj świecie”.
źródło
Moim zdaniem najlepszy sposób na czytanie ze standardowego wejścia w bash jest następujący, który pozwala również pracować na liniach przed zakończeniem wprowadzania:
źródło
Ponieważ mi się to podoba, chciałbym upuścić notatkę. Znalazłem ten wątek, ponieważ muszę przepisać stary skrypt sh, aby był zgodny z POSIX. Zasadniczo oznacza to obejście problemu potoku / podpowłoki wprowadzonego przez POSIX poprzez przepisanie kodu w następujący sposób:
w:
I kod w ten sposób:
w:
Ale to ostatnie nie zachowuje się tak samo przy pustym wejściu. W starej notacji pętla while nie jest wprowadzana przy pustym wejściu, ale w notacji POSIX jest! Myślę, że wynika to z nowej linii przed EOF, której nie można pominąć. Kod POSIX, który zachowuje się bardziej jak stara notacja, wygląda następująco:
W większości przypadków powinno to być wystarczająco dobre. Ale niestety to nadal nie działa dokładnie tak, jak stara notacja, jeśli some_command wypisuje pustą linię. W starej notacji ciało while jest wykonywane, aw notacji POSIX łamiemy się przed ciałem.
Podejście do rozwiązania tego problemu może wyglądać następująco:
źródło
Inteligentny skrypt, który może zarówno odczytywać dane z PIPE, jak i argumenty wiersza poleceń:
Wynik:
Objaśnienie: Kiedy skrypt odbiera dane przez potok, wtedy stdin / proc / self / fd / 0 będzie dowiązaniem symbolicznym do potoku.
Jeśli nie, wskaże bieżący terminal:
Opcja bash
[[ -p
może sprawdzić, czy jest to potok, czy nie.cat -
czyta zstdin
.Jeśli użyjemy,
cat -
gdy nie mastdin
, będzie czekać wiecznie, dlatego umieszczamy go wif
warunku.źródło
/dev/stdin
linku do/proc/self/fd/0
Przeniesienie czegoś do wyrażenia obejmującego zadanie nie zachowuje się w ten sposób.
Zamiast tego spróbuj:
źródło
Poniższy kod:
też będzie działać, ale otworzy kolejną nową podpowłokę za potokiem, gdzie
przyzwyczajenie.
Musiałem wyłączyć kontrolę zadań, aby skorzystać z metody Chepnars (uruchamiałem to polecenie z terminala):
Bash Manual mówi :
Uwaga: kontrola zadań jest domyślnie wyłączona w nieinteraktywnej powłoce, dlatego nie potrzebujesz
set +m
wewnętrznej strony skryptu.źródło
Myślę, że próbowałeś napisać skrypt powłoki, który mógłby pobierać dane wejściowe ze standardowego wejścia. ale kiedy próbujesz to zrobić in-line, zgubiłeś się, próbując utworzyć zmienną test =. Myślę, że nie ma większego sensu robienie tego w linii i dlatego nie działa tak, jak się spodziewasz.
Próbowałem zmniejszyć
aby uzyskać konkretny wiersz z różnych danych wejściowych. żebym mógł napisać ...
więc potrzebuję małego programu powłoki, który może czytać ze standardowego wejścia. tak jak ty.
proszę bardzo.
źródło
Co powiesz na to:
źródło