Przykład:
ls | echo
nie drukuje nic (właściwie pusta linia). Spodziewałbym się, że wydrukuje listę plików.
ls | grep 'foo'
z drugiej strony działa zgodnie z oczekiwaniami (drukuje pliki z imieniem „foo”).
To, co robię w takich sytuacjach, jest takie:
ls | while read OUT; do echo $OUT; done
ale jest to raczej kłopotliwe.
Dlaczego przesyłanie potokowe działa z niektórymi poleceniami, a nie z innymi? Jak mogę obejść ten problem?
ls | echo
zrobić? dlaczego po prostu nie uruchomićls
?git cat-file
, ale to po prostu nie działało. Najwyraźniej echo ma takie samo zachowanie, więc użyłem go jako przykładu.Odpowiedzi:
Istnieje różnica między argumentami wiersza poleceń a standardowymi danymi wejściowymi. Rura połączy standardowe wyjście jednego procesu ze standardowym wejściem innego. Więc
Łączy standardowe wyjście ls ze standardowym wejściem echa. Dobrze, prawda? Cóż, echo ignoruje standardowe wejście i zrzuci argumenty wiersza poleceń - których w tym przypadku nie ma - na swoje standardowe wyjście. Wynik: w ogóle nic.
W tym przypadku istnieje kilka rozwiązań. Jednym z nich jest użycie polecenia, które odczytuje stdin i zrzuca na standardowe wyjście, takie jak cat.
Będzie „działać”, w zależności od twojej definicji pracy.
Ale co z ogólnym przypadkiem. Naprawdę chcesz przekonwertować standardowe wyjście jednego polecenia na argumenty wiersza poleceń innego. Jak powiedzieli inni,
xargs
jest kanonicznym narzędziem pomocniczym w tym przypadku, czytając jego linię poleceń argumentów dla polecenia ze standardowego wejścia i konstruując polecenia do uruchomienia.Można to również przekonwertować za pomocą polecenia podstawienia
$()
Zrobiłbym również, co chcesz.
Oba te narzędzia są bardzo ważne dla skryptów powłoki, powinieneś nauczyć się obu.
Dla kompletności, jak wskazano w pytaniu, innym podstawowym sposobem konwersji stdin na argumenty linii poleceń jest wbudowane
read
polecenie powłoki . Konwertuje „słowa” (słowa zdefiniowane przezIFS
zmienną) na zmienną tymczasową, której można używać w dowolnych uruchomieniach poleceń.źródło
ls | echo
wypisuje tylko pustą linię, ponieważecho
nie czyta żadnych danych wejściowych; ostatnią komendą potoku jest to,echo
że drukuje tylko pustą linię.Ogólnie:
upewnia się, że dane wyjściowe
a
stają się danymi wejściowymib
. Proponuję przeczytaćPipelines
sekcjęman bash
.Jeśli naprawdę chcesz używać
ls
iecho
razem oto kilka (całkiem bezużytecznych) przykładów:źródło
Jeśli chcesz, aby
echo
wls
próbie polecenia:To wywoła
echo
z wyjściemls
.źródło
ls | xargs -I {} echo {}
jeśli chcesz, aby był wywoływany dla każdej linii osobnoDlaczego nie po prostu użyć:
Lub o wiele bezpieczniej:
źródło
echo *
.