Mam skrypt skorupy, którego stdout i stderr chcę pisać do logfile. Wiem, że można to osiągnąć za pomocą

sh script.sh >> both.log 2>&1

Chcę jednak jednocześnie napisać stderr do osobnego pliku, "Error.log". Czy to osiągalne?

3
Danzo 15 luty 2017, 17:00

2 odpowiedzi

Najlepsza odpowiedź

Aby to najpierw przełączyć Stdout i Stderr, który wymaga dodatkowego deskryptora plików:

sh script.sh 3>&2 2>&1 1>&3 3>&-

Ostatni operator zamyka deskryptor pliku pomocniczego.

Po tym możesz użyć tee, aby zduplikować strumień błędu (który jest teraz na stdin) i dołącz go do dziennika błędów:

sh script.sh 3>&2 2>&1 1>&3 3>&- | tee -a error.log

A potem możesz następnie kierować zarówno STDIN, jak i stderr do połączonego dziennika:

(sh script.sh 3>&2 2>&1 1>&3 3>&- | tee -a error.log) >> both.log 2>&1

Nawiasy wokół polecenia są ważne, aby uchwycić strumień błędu całego polecenia. Bez nich tylko (pusty) strumień błędu tee zostanie schwytany, a reszta nadal trafi do terminala.

Uwaga: Nie sprawdza, czy deskryptor pliku 3 był w użyciu (otwarty) wcześniej. W bash możesz użyć tego, aby wybrać wcześniej nieużywany deskryptor plików i zamknij go na ostatnim przekierowaniu:

sh script.sh {tmpfd}>&2 2>&1 1>&${tmpfd}-
1
mata 15 luty 2017, 15:20

Możesz użyć tee, aby zduplikować wyjście do dwóch lokalizacji. Połącz to z trudnymi przekierowaniem i ...

script.sh 2>&1 >> both.log | tee -a both.log >> error.log

To przekierowuje stderr do stdout, a następnie stdout do both.log. Stderr pozostaje i jest napędzany do tee, który kopiuje go zarówno do plików dziennika.

4
John Kugelman 15 luty 2017, 14:15