Jak mogę to osiągnąć?
cmd >> file1 2>&1 1>>file2
Oznacza to, że stdout i stderr powinny przekierowywać do jednego pliku (plik1) i tylko stdout (plik2) powinien przekierowywać do innego (oba w trybie dołączania)?
Jak mogę to osiągnąć?
cmd >> file1 2>&1 1>>file2
Oznacza to, że stdout i stderr powinny przekierowywać do jednego pliku (plik1) i tylko stdout (plik2) powinien przekierowywać do innego (oba w trybie dołączania)?
Odpowiedzi:
Problem polega na tym, że po przekierowaniu danych wyjściowych nie jest już dostępny dla następnego przekierowania. Możesz teepotokować do podpowłoki, aby zachować dane wyjściowe dla drugiego przekierowania:
( cmd | tee -a file2 ) >> file1 2>&1
lub jeśli chcesz zobaczyć dane wyjściowe w terminalu:
( cmd | tee -a file2 ) 2>&1 | tee -a file1
Aby uniknąć dodania stderr pierwszego teedo file1, powinieneś przekierować stderr swojego polecenia do jakiegoś deskryptora pliku (np. 3), a następnie dodać to ponownie do stdout:
( 2>&3 cmd | tee -a file2 ) >> file1 3>&1
# or
( 2>&3 cmd | tee -a file2 ) 3>&1 | tee -a file1
(dzięki @ fra-san)
Z zsh:
cmd >& out+err.log > out.log
W trybie dołączania:
cmd >>& out+err.log >> out.log
W zshi pod warunkiem, że mult_iosopcja nie została wyłączona, gdy deskryptor pliku (tutaj 1) jest kilkakrotnie przekierowywany do zapisu, wówczas powłoka implementuje wbudowaną funkcję teekopiowania danych wyjściowych do wszystkich celów.
cmd >& file1 > file2
Możesz: otagować stdout (używając sedera UNBUFFERED, tj .:) sed -u ..., aby stderr również przeszedł do stdout (nieoznaczony, ponieważ nie przeszedł przez tagowania sed), a tym samym móc rozróżnić 2 w wynikowym pliku logu.
Następujące: jest powolny (można go poważnie zoptymalizować, używając na przykład skryptu perl zamiast while ...; do ...; zrobiono, na przykład, który będzie tworzył podpowłoki i polecenia w każdym wierszu!), Dziwne (wydaje się, że potrzebuję 2 {} etapów, aby w jednym zmienić nazwę stdout, a następnie w drugim dodać do niego „przewrócony” stderr), itd. Ale to jest: „ dowód koncepcji ”, który będzie próbował zachować porządek wyjścia jak najwięcej stdout i stderr:
#basic principle (some un-necessary "{}" to visually help see the layers):
# { { complex command ;} | sed -e "s/^/TAGstdout/" ;} 2>&1 | read_stdin_and_redispatch
#exemple:
# complex command = a (slowed) ls of several things (some existing, others not)
# to see if the order of stdout&stderr is kept
#preparation, not needed for the "proof of concept", but needed for our specific exemple setup:
\rm out.file out_AND_err.file unknown unknown2
touch existing existing2 existing3
#and the (slow, too many execs, etc) "proof of concept":
uniquetag="_stdout_" # change this to something unique, that will NOT appear in all the commands outputs...
# avoid regexp characters ("+" "?" "*" etc) to make it easy to remove with another sed later on.
{
{ for f in existing unknown existing2 unknown2 existing3 ; do ls -l "$f" ; sleep 1; done ;
} | sed -u -e "s/^/${uniquetag}/" ;
} 2>&1 | while IFS="" read -r line ; do
case "$line" in
${uniquetag}*) printf "%s\n" "$line" | tee -a out_AND_err.file | sed -e "s/^${uniquetag}//" >> out.file ;;
*) printf "%s\n" "$line" >> out_AND_err.file ;;
esac;
done;
# see the results:
grep "^" out.file out_AND_err.file
ls unknown), aby wydrukować coś na stderr? >&2 echo "error"będzie dobrze. (2) teemoże dołączyć do wielu plików jednocześnie. (3) Dlaczego nie catzamiast tego grep "^"? (4) twój skrypt zawiedzie, gdy zaczyna się wyjście stderr _stdout_. (5) Dlaczego?
ls loopspowoduje to wyświetlenie zarówno wyjścia standardowego, jak i standardowego, mieszanego (alternatywnie), w kontrolowanej kolejności; tak, abyśmy mogli sprawdzić, czy zachowaliśmy porządkowanie standardowego standardowego standardu pomimo oznaczenia standardowego standardu 2): może gnu ogon, ale nie zwykły ogon (np. na aix.). 3): grep „^” pokazuje także obie nazwy plików. 4): można to zmienić za pomocą zmiennej. 5): zwinięty przykład działa na starych osesach (np. Stary aix), gdzie go przetestowałem (brak dostępnego perla).
uniquetag="banaNa11F453355B28E1158D4E516A2D3EDF96B3450406...)
Jeśli kolejność danych wyjściowych musi być: stdout, to stderr ; nie ma rozwiązania tylko z przekierowaniem.
Stderr musi być zapisany w pliku tymczasowym
cmd 2>>file-err | tee -a file1 >>file2
cat file-err >> file1
rm file-err
Opis:
Jedynym sposobem przekierowania jednego wyjścia (fd takiego jak stdout lub stderr) do dwóch plików jest odtworzenie go. Polecenie teejest właściwym narzędziem do odtwarzania zawartości deskryptora pliku. Tak więc początkowym pomysłem posiadania jednego wyjścia na dwóch plikach byłoby użycie:
... | tee file1 file2
To odtwarza standardowe wejście tee do obu plików (1 i 2), pozostawiając wyjście tee wciąż nieużywane. Ale musimy dołączyć (użyć -a) i potrzebujemy tylko jednej kopii. To rozwiązuje oba problemy:
... | tee -a file1 >>file2
Aby dostarczyć teestdout (ten do powtórzenia), musimy użyć stderr bezpośrednio z komendy. Jednym ze sposobów, jeśli kolejność nie jest ważna (kolejność wyjścia zostanie (najprawdopodobniej) zachowana w stanie wygenerowanym, w zależności od tego, co nastąpi jako pierwsze, zostanie zapisane najpierw). Zarówno:
cmd 2>>file1 | tee -a file2 >>file1cmd 2>>file1 > >( tee -a file2 >>file1 )( cmd | tee -a file2 ) >> file1 2>&1Opcja 2 działa tylko w niektórych powłokach. Opcja 3 korzysta z dodatkowej podpowłoki (wolniej), ale nazwy plików należy używać tylko raz.
Ale jeśli stdout musi być pierwszy (cokolwiek zostanie wygenerowane wyjście zamówienia), musimy zapisać stderr, aby dołączyć go do pliku na końcu (pierwsze opublikowane rozwiązanie).
sponge:(cmd | tee -a out >> out+err) 2>&1 | sponge >> out+err
W interesie różnorodności:
Jeśli twój system obsługuje /dev/stderr, to
(cmd | tee -a /dev/stderr) 2>> file1 >> file2
będzie działać. Standardowe wyjście cmd
jest wysyłane zarówno do standardowego, jak i standardowego potoku. Standardowy błąd cmdomija tee
i wychodzi ze stderr rurociągu.
Więc
cmdicmdzmieszanego.W takim razie wystarczy wysłać te strumienie do odpowiednich plików.
Jak w przypadku prawie każdego takiego podejścia (w tym odpowiedzi Stéphane'a ),
file1linie mogą być nieczynne.
out+erriouttu na myśli. Nazwy plików Strumienie do przekierowania?