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 tee
potokować 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 tee
do 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 zsh
i pod warunkiem, że mult_ios
opcja nie została wyłączona, gdy deskryptor pliku (tutaj 1) jest kilkakrotnie przekierowywany do zapisu, wówczas powłoka implementuje wbudowaną funkcję tee
kopiowania 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) tee
może dołączyć do wielu plików jednocześnie. (3) Dlaczego nie cat
zamiast tego grep "^"
? (4) twój skrypt zawiedzie, gdy zaczyna się wyjście stderr _stdout_
. (5) Dlaczego?
ls loop
spowoduje 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 tee
jest 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ć tee
stdout (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 >>file1
cmd 2>>file1 > >( tee -a file2 >>file1 )
( cmd | tee -a file2 ) >> file1 2>&1
Opcja 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 cmd
omija tee
i wychodzi ze stderr rurociągu.
Więc
cmd
icmd
zmieszanego.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 ),
file1
linie mogą być nieczynne.
out+err
iout
tu na myśli. Nazwy plików Strumienie do przekierowania?