W bashu wywołanie foo
wyświetlałoby dane wyjściowe z tego polecenia na standardowym wyjściu.
Wywołanie foo > output
przekieruje dane wyjściowe z tej komendy do określonego pliku (w tym przypadku „wynik”).
Czy istnieje sposób przekierowania wyjścia do pliku i wyświetlania go na standardowym wyjściu?
foo > output
dane są zapisywane na stdout, a stdout to plik o nazwieoutput
. Oznacza to, że zapis do pliku jest zapisywany na standardowe wyjście. Pytasz, czy można napisać zarówno na standardowe wyjście, jak i na terminal.Odpowiedzi:
Polecenie ma nazwę
tee
:Na przykład, jeśli zależy Ci tylko na standardowym:
Jeśli chcesz dołączyć stderr, wykonaj:
2>&1
przekierowuje kanał 2 (stderr / błąd standardowy) na kanał 1 (wyjście standardowe / standardowe wyjście), tak że oba są zapisywane jako standardowe wyjście. Jest również kierowany do podanego pliku wyjściowego odtee
polecenia.Ponadto, jeśli chcesz dołączyć do pliku dziennika, użyj
tee -a
jako:źródło
-a
argumentu,tee
aby dołączyć treśćoutput.file
, zamiast nadpisywać:ls -lR / | tee -a output.file
$?
później, zwróci kod stanutee
, który prawdopodobnie nie jest tym, czego chcesz. Zamiast tego możesz użyć${PIPESTATUS[0]}
.2>&1
zrzuca strumienie stderr i stdout.tee outfile
pobiera otrzymany strumień i zapisuje go na ekranie oraz w pliku „outfile”.Tego prawdopodobnie szuka większość ludzi. Prawdopodobną sytuacją jest to, że jakiś program lub skrypt ciężko pracuje przez długi czas i generuje wiele wyników. Użytkownik chce okresowo sprawdzać postęp, ale chce również, aby dane wyjściowe były zapisywane w pliku.
Problem (szczególnie przy mieszaniu strumieni stdout i stderr) polega na tym, że program polega na opróżnianiu strumieni. Jeśli na przykład wszystkie zapisy na standardowe wyjście nie zostaną usunięte, ale wszystkie zapisy na standardowe zostaną wyczyszczone, to skończy się to chronologicznie w pliku wyjściowym i na ekranie.
Jest to również złe, jeśli program wyświetla tylko 1 lub 2 linie co kilka minut, aby zgłosić postęp. W takim przypadku, jeśli dane wyjściowe nie zostałyby wyczyszczone przez program, użytkownik nawet nie widziałby żadnych danych wyjściowych na ekranie przez wiele godzin, ponieważ żadne z nich nie zostałoby przepchnięte przez rurę przez wiele godzin.
Aktualizacja: program
unbuffer
, będący częściąexpect
pakietu, rozwiąże problem buforowania. Spowoduje to, że stdout i stderr będą natychmiast zapisywać na ekranie i pliku i utrzymywać je w synchronizacji podczas łączenia i przekierowywania dotee
. Na przykład:źródło
$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
python
ma wbudowaną opcję,-u
która rozpakowuje dane wyjściowe.Innym sposobem, który działa dla mnie jest
jak pokazano w instrukcji gnu bash
Przykład:
Aby uzyskać więcej informacji, zobacz przekierowanie
źródło
$?
później, zwróci kod stanutee
, który prawdopodobnie nie jest tym, czego chcesz. Zamiast tego możesz użyć${PIPESTATUS[0]}
.Możesz przede wszystkim użyć rozwiązania Zoredache , ale jeśli nie chcesz nadpisywać pliku wyjściowego, powinieneś napisać tee z opcją -a w następujący sposób:
źródło
Coś do dodania ...
Rozpakowywanie pakietów ma problemy z obsługą niektórych pakietów w wydaniach fedora i redhat unix.
Odkładając na bok kłopoty
Obserwowanie działało dla mnie
źródło
Używanie
tail -f output
powinno działać.źródło
Dodatkowa odpowiedź, ponieważ ten przypadek użycia przywiózł mnie tutaj:
W przypadku, gdy musisz to zrobić jako inny użytkownik
Zauważ, że echo pojawi się tak jak ty, a zapis pliku nastąpi jako „some_user”, co NIE zadziała, jeśli uruchomisz echo jako „some_user” i przekierujesz dane wyjściowe za pomocą >> „some_file”, ponieważ nastąpi przekierowanie pliku jak ty.
Wskazówka: tee obsługuje także append z flagą -a, jeśli chcesz zastąpić linię w pliku innym użytkownikiem, możesz uruchomić sed jako pożądany użytkownik.
źródło
< command > |& tee filename
# spowoduje to utworzenie pliku „nazwa pliku” ze statusem polecenia jako treści. Jeśli plik już istnieje, usunie istniejącą zawartość i zapisze status polecenia.< command > | tee >> filename
# to dołącza status do pliku, ale nie drukuje statusu polecenia na standard_output (screen).Chcę wydrukować coś za pomocą „echa” na ekranie i dołączyć dane echa do pliku
źródło
Możesz to zrobić dla całego skryptu, używając czegoś takiego na początku skryptu:
To przekierowuje zarówno wyjścia stderr, jak i stdout do pliku o nazwie
mylogfile
i pozwala, aby wszystko poszło w tym samym czasie .Używa się kilku głupich sztuczek:
exec
bez polecenia, aby skonfigurować przekierowania,tee
do powielania wyników,NUL
znaku określonego w$'string'
specjalnej notacji bash), aby określić, że skrypt zostanie zrestartowany (w oryginalnej pracy nie można użyć równoważnego parametru),pipefail
opcji.Brzydkie, ale przydatne w niektórych sytuacjach.
źródło
tee jest do tego idealna, ale to też zadziała
źródło
;
, wyjście będzie znacznie opóźnione podczas powolnego polecenia.