2014-12-04 13 views
5

Może ktoś wyjaśnić, dlaczego ta komenda krótki bash/python nie ma wyjścia „hello”Czytaj stdin z inlined python bash

$ echo hello | python - <<END 
import sys 
for line in sys.stdin: 
    print line 
END 

Jeśli mogę zapisać skrypt Pythona do pliku, to polecenie działa zgodnie z oczekiwaniami.

W script.py

import sys 
for line in sys.stdin: 
    print line 
END 

$ echo "hello" | pyton script.py

"cześć"

Odpowiedz

4

Ponieważ python << END przekierowuje stdin do przeczytania programu. Nie można również odczytać linii wyprowadzonej z echo na stdin.

3

Och, chłopcze, to ma sens! Walczę z tym od ostatniej godziny i wreszcie rozumiem, dziękuję wam.

Aby zapewnić alternatywę pracy dla oryginalnego programu, można zrobić coś takiego:

$ echo hello | python <(cat <<END 
import sys 
for line in sys.stdin: 
    print line 
END 
) 

Ale uważaj! Jeśli umieścisz to w pliku, ostateczna END musi dotykać lewej rynny (bez białych znaków). W przeciwnym razie nie będzie analizować "nieoczekiwanego końca pliku podczas szukania pasującego znaku" lub czegoś podobnego (w rzeczywistości zajęło mi to dwie godziny, zanim zacząłem odpowiadać).

Wyjaśniając ten kod, co się dzieje, jest to, że <<END ... END połączeniu z <(cat ...) utworzyć plik (w /dev/fd) tak, że może być podawany do python, jak gdyby był prawdziwym plikiem. Cytowanie this objaśnienie o <(...):

Jest to podstawienie procesu. Przesyła dane wyjściowe polecenia do formatu FIFO, który można odczytać z normalnego pliku.

Jest jeszcze jedna ciekawa odpowiedź na ten temat here.

+0

To innowacyjne, ale nadal zasadniczo [bezużyteczny użycie 'cat'] (http://www.iki.fi/era/unix/award.html). Powłoka nie potrzebuje pomocy "cat" w podstawianiu procesu, aby przekazać tutaj dokument do Pythona, chociaż konstrukcja nie wiąże się ze standardowym wejściem (powłoka w zasadzie sprawia, że ​​wyjście z substytucji procesu jest dostępne jako nazwany tymczasowy plik) . – tripleee

3

Powodem, dla którego nie działa, są sprzeczne przekierowania. echo | python próbuje przywiązać standardowe wejście do rury od echo, podczas gdy python - <<HERE próbuje przywiązać standardowe wejście do tego dokumentu. Nie możesz mieć obu. (Dokument tutaj wygrywa.)

Jednak naprawdę nie ma powodu, aby chcieć potokować skrypt na standardowym wejściu.

bash$ echo hello | python -c ' 
> import sys 
> for line in sys.stdin: 
> print line' 
hello