Co może sprawić, że `>` po cichu zawiedzie w systemie Linux?

20

Uruchomiłem to polecenie:

python ./manage.py dumpdata partyapp.InvitationTemplate > partyapp_dump.json

Aby zrzucić dane do partyapp_dump.jsonpliku. Ale wszystkie dane są po prostu drukowane na ekranie i partyapp_dump.jsontworzony jest pusty plik.

Dlaczego tak się stało? Testowałem ls > partyapp_dump.jsoni to działało idealnie.

Ram Rachum
źródło

Odpowiedzi:

40

Za pomocą > przekierowujesz tylko standardowe wyjście. Spróbuj 2> zamiast tego, aby przekierować wyjście błędu. Użyj &>, aby przekierować oba.

fab
źródło
1
FYI, &>będzie działać tylko w Bash 4.0 i iirc najnowszych wersjach zsh. Dla bardziej przenośnego rozwiązania foo > bar 2&>1. Odniesienie: mywiki.wooledge.org/BashFAQ/014
Rein Henrichs
6
@ Rein Henrichs: To 2> i 1, a nie 2 i> 1
camh
Pamiętam to z pneumonią (?) Od programowania: „2”, do („>”) Lokalizacja („&”) „1”
hometoast
1
@hometoast: Masz na myśli mnemonic? :) Pneumoniczny oznacza płuco ...
carlpett 16.04.11
22

Twoja aplikacja w Pythonie musi zapisywać dane wyjściowe w kanale wyjściowym STDERR zamiast w normalnym STDOUT. Używanie konstrukcji powłoki >tylko przechwytuje i przekierowuje dane zapisane do kanału wyjściowego, ale tak naprawdę istnieje kilka innych kanałów, które można wydrukować, przy czym najczęściej jest to drugi, zwykle używany do błędów.

Możesz spróbować przechwycić STDERR (drugi kanał) w następujący sposób:

python ./manage.py dumpdata partyapp.InvitationTemplate > partyapp_dump.json 2>&1

2>&1Konstrukcja łączy wyjściowy strumień błędów do normalnego kanału wyjściowego. To niezwykłe, że program generuje dane wyjściowe, które chciałbyś przechwycić w kanale błędów; zwykle byłyby zarezerwowane dla informacji debugowania, a nie danych aplikacji. Proszę używać tego skryptu z pewną ostrożnością, ponieważ działa on w niestandardowy sposób.

Możesz także zrzucić kanały wyjściowe i kanały błędów do różnych plików, takich jak to:

python ./manage.py dumpdata partyapp.InvitationTemplate > partyapp_dump.json 2> error_output.txt
Caleb
źródło
5

Oprócz już sugerowanego objaśnienia wyjścia stderr vs stdout, aplikacja może po prostu zignorować oba strumienie i jawnie otworzyć „/ dev / tty” dla swoich danych wyjściowych.

jlliagre
źródło
1

Jeśli noclobberustawiona jest opcja bash, przekierowanie nie powiedzie się (choć nie po cichu), jeśli plik docelowy już istnieje.

Aby uzyskać lepszą przenośność, użyj, cmd >| fileaby wymusić zastąpienie dowolnego istniejącego pliku.

tylerl
źródło
0

Jeśli się zgubisz, zawsze możesz spróbować uruchomić go strace, aby zobaczyć, co robią procesy:

strace -f command
bluszcz
źródło
1
Prawdziwa odpowiedź, ale niezbyt istotna. Jeśli facet nie chciałby teraz zarządzać strumieniem błędów, nie sądzę, żeby wiedział, co zrobić z wyjściem pliku strace.
Caleb