파이프와 함께 "tee"를 사용하는 동안 파일에 표준 오류를 쓰는 방법은 무엇입니까?
있습니다.tee
출력(표준 출력)을 쓰다aaa.sh
로로 합니다.bbb.out
단말기에 표시하면서 다음을 수행합니다.
./aaa.sh | tee bbb.out
다음 파일에 표준 오류도 어떻게 쓸 수 있을까요?ccc.out
시해해 둔???
터미널에서 표준 오류와 표준 출력을 보고 싶으시겠죠.조쉬 켈리의 대답을 들을 수도 있지만, 난 그 대답에 대해tail
백그라운드에서 로그 파일을 매우 해킹하고 투박하게 출력합니다.추가 파일 기술자를 보관하고 나중에 파일을 삭제함으로써 정리하는 방법을 알아두십시오.기술적으로는 파일 기술자를 삭제해야 합니다.trap '...' EXIT
.
더 은 이미 발견하셨을 거예요.tee
.
표준 출력에만 사용하는 것이 아니라 표준 출력과 표준 오류에 대한 티만 사용하십시오.어떻게 해내실 건가요?프로세스 대체 및 파일 리디렉션:
command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
분할하여 설명하겠습니다.
> >(..)
>(...)
치환되어 FIFO가 생성됩니다.tee
나서, '이렇게'를 사용합니다.>
리다이렉트.command
번째 FIFO에 tee
고고있있있있다다
두 번째도 마찬가지입니다.
2> >(tee -a stderr.log >&2)
해서 ''를 요.tee
「」에 하는 .stderr.log
tee
, 그 에러이므로, 「 에러」를 리다이렉트 .tee
을 사용하다 다음 파일 하여 리다이렉트합니다.command
FIFO)tee
의준표입입입입 。
를 셸로 수 중입니다.는 Bash가 Bash를 입니다.sh
(POSIX 본).
»sh
작업을 수동으로 수행해야 합니다.
out="${TMPDIR:-/tmp}/out.$$" err="${TMPDIR:-/tmp}/err.$$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"
심플:
./aaa.sh 2>&1 | tee -a log
이것은 표준 에러를 표준 출력으로 리다이렉트 할 뿐이기 때문에, TEE는 로그와 화면 양쪽에 에코를 울립니다.제가 뭔가 놓치고 있는 건지도 몰라요. 다른 해결책들은 너무 복잡해 보이거든요.
주의: Bash 버전4부터는|&
의 줄임말로서2>&1 |
:
./aaa.sh |& tee -a log
이것은 구글을 통해 이것을 찾는 사람들에게 유용할 수 있다.시험해 보고 싶은 예를 간단히 설명하세요.물론 출력 파일의 이름을 변경할 수 있습니다.
#!/bin/bash
STATUSFILE=x.out
LOGFILE=x.log
### All output to screen
### Do nothing, this is the default
### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1
### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1
### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)
### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)
### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}
### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)
### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}
### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)
echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}
표준 에러를 파일로 리다이렉트 하려면 , 화면에 표준 출력을 표시하고,
./aaa.sh 2> ccc.out | tee ./bb.out
화면에 표준 오류와 표준 출력을 모두 표시하고 둘 다 파일에 저장하려면 Bash의 I/O 리디렉션을 사용할 수 있습니다.
#!/bin/bash
# Create a new file descriptor 4, pointed at the file
# which will receive standard error.
exec 4<>ccc.out
# Also print the contents of this file to screen.
tail -f ccc.out &
# Run the command; tee standard output as normal, and send standard error
# to our file descriptor 4.
./aaa.sh 2>&4 | tee bbb.out
# Clean up: Close file descriptor 4 and kill tail -f.
exec 4>&-
kill %1
필터(「」, 「stdout」)에 파이프 합니다.tee bbb.out
에 넣습니다stderr').tee ccc.out
의 것을 stdout을 저글링하여 할 수
{ { ./aaa.sh | tee bbb.out; } 2>&1 1>&3 | tee ccc.out; } 3>&1 1>&2
「표준 에러 스트림(stderr)의 grep 방법」도 참조해 주세요.파일 기술자를 추가할 때는 언제입니까?
bash(및 ksh 및 zsh)에서는 사용할 수 있지만 대시 등의 다른 POSIX 쉘에서는 사용할 수 없습니다.
./aaa.sh > >(tee bbb.out) 2> >(tee ccc.out)
이 는 bash가 반환되는 ../aaa.sh
.tee
명령은 계속 실행됩니다(ksh 및 zsh는 하위 프로세스를 기다립니다).가 될 수 있어요../aaa.sh > >(tee bbb.out) 2> >(tee ccc.out); process_logs bbb.out ccc.out
ksh/zsh로 하다
Bash를 사용하는 경우:
# Redirect standard out and standard error separately
% cmd >stdout-redirect 2>stderr-redirect
# Redirect standard error and out together
% cmd >stdout-redirect 2>&1
# Merge standard error with standard out and pipe
% cmd 2>&1 |cmd2
크레딧(내 머리에서부터 대답하지 않음)은 여기에 있습니다: Re: bash: stderr & more(stderr의 파이프)
Z 쉘을 사용하는 경우(zsh
리다이렉션을 할 수 리다이렉션은 필요 tee
:
./cmd 1>&1 2>&2 1>out_file 2>err_file
여기서는 각 스트림을 자신 및 대상 파일로 리디렉션하기만 하면 됩니다.
완전한 예
% (echo "out"; echo "err">/dev/stderr) 1>&1 2>&2 1>/tmp/out_file 2>/tmp/err_file
out
err
% cat /tmp/out_file
out
% cat /tmp/err_file
err
에는 " " 가 필요합니다.MULTIOS
설정하는 옵션(디폴트).
MULTIOS
인 「」를 합니다.
tee
""cat
여러 리다이렉션을 시행하는 경우(리다이렉트 참조).
lhunath가 잘 설명해준 답처럼, 당신은 그것을 사용할 수 있다.
command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
bash를 사용하면 문제가 생길 수 있으니 주의하세요.
매튜 윌콕슨의 예를 들어보겠습니다.
그리고 "보는 것이 믿는 것"을 위한 간단한 테스트:
(echo "Test Out";>&2 echo "Test Err") > >(tee stdout.log) 2> >(tee stderr.log >&2)
개인적으로 시도해보니 다음과 같은 결과가 나옵니다.
user@computer:~$ (echo "Test Out";>&2 echo "Test Err") > >(tee stdout.log) 2> >(tee stderr.log >&2)
user@computer:~$ Test Out
Test Err
두 메시지가 동일한 수준으로 표시되지 않습니다.?는 왜?Test Out
치치 내전 령령 령?? ?? ???
프롬프트가 공백 행에 표시되어 프로세스가 완료되지 않았다고 생각되며, 이 버튼을 누르면 수정됩니다.파일 내용을 확인하면 정상이며 리다이렉트도 가능합니다.
다른 시험을 치르자.
function outerr() {
echo "out" # stdout
echo >&2 "err" # stderr
}
user@computer:~$ outerr
out
err
user@computer:~$ outerr >/dev/null
err
user@computer:~$ outerr 2>/dev/null
out
리다이렉션을 다시 시도하고 있지만 다음 기능을 사용합니다.
function test_redirect() {
fout="stdout.log"
ferr="stderr.log"
echo "$ outerr"
(outerr) > >(tee "$fout") 2> >(tee "$ferr" >&2)
echo "# $fout content: "
cat "$fout"
echo "# $ferr content: "
cat "$ferr"
}
개인적으로 다음과 같은 결과가 있습니다.
user@computer:~$ test_redirect
$ outerr
# stdout.log content:
out
out
err
# stderr.log content:
err
user@computer:~$
빈 줄에 프롬프트가 표시되지 않지만 정상적인 출력이 표시되지 않습니다.stdout.log 내용이 잘못된 것 같고 stderr.log만 정상인 것 같습니다.
다시 시작하면 출력이 달라질 수 있습니다.
그럼, 왜?
왜냐하면 여기서 설명한 바와 같이:
bash에서는 tee 명령이 계속 실행되더라도 [first command]가 끝나는 대로 이 명령이 반환된다는 점에 유의하십시오(ksh 및 zsh는 하위 프로세스를 기다립니다).
따라서 Bash를 사용하는 경우 다음 답변에 제시된 보다 나은 예를 사용하는 것이 좋습니다.
{ { outerr | tee "$fout"; } 2>&1 1>&3 | tee "$ferr"; } 3>&1 1>&2
이전 문제가 해결됩니다.
문제는 종료 상태 코드를 어떻게 검색하느냐는 것입니다.
$?
동작하지 않습니다.
장애로 인한 파이프 더 .set -o pipefail
)set +o pipefail
를 끄고 ${PIPESTATUS[0]}
음음음같 뭇매하다
function outerr() {
echo "out"
echo >&2 "err"
return 11
}
function test_outerr() {
local - # To preserve set option
! [[ -o pipefail ]] && set -o pipefail; # Or use second part directly
local fout="stdout.log"
local ferr="stderr.log"
echo "$ outerr"
{ { outerr | tee "$fout"; } 2>&1 1>&3 | tee "$ferr"; } 3>&1 1>&2
# First save the status or it will be lost
local status="${PIPESTATUS[0]}" # Save first, the second is 0, perhaps tee status code.
echo "==="
echo "# $fout content :"
echo "<==="
cat "$fout"
echo "===>"
echo "# $ferr content :"
echo "<==="
cat "$ferr"
echo "===>"
if (( status > 0 )); then
echo "Fail $status > 0"
return "$status" # or whatever
fi
}
user@computer:~$ test_outerr
$ outerr
err
out
===
# stdout.log content:
<===
out
===>
# stderr.log content:
<===
err
===>
Fail 11 > 0
이 경우 스크립트가 stdout과 stderr를 모두 파일로 리다이렉트하면서 다음과 같은 명령을 실행하고 있었습니다.
cmd > log 2>&1
에러 메세지에 근거해, 에러 메세지에 근거해 몇개의 조치를 취할 필요가 있었습니다. 듀프는 할 수 .2>&1
스크립트에서 stderr을 캡처하면 오류 메시지가 참조용으로 로그 파일에 저장되지 않습니다.lhunath로부터 수신된 응답도 같은 처리를 하도록 되어 있습니다만, 리다이렉트 됩니다.stdout
★★★★★★★★★★★★★★★★★」stderr
하다그것은 제가 원하는 것은 아니지만, 제가 필요로 하는 정확한 솔루션을 생각해 낼 수 있었습니다.
(cmd 2> >(tee /dev/stderr)) > log
경우, 에는, 「중요」와「중요」의 모두의 됩니다.stdout
★★★★★★★★★★★★★★★★★」stderr
할 수 .stderr
하지 되는 내 stdout
.
다음은 프로세스 대체를 사용할 수 없는 KornShell(ksh)에 적용됩니다.
# create a combined (standard input and standard output) collector
exec 3 <> combined.log
# stream standard error instead of standard output to tee, while draining all standard output to the collector
./aaa.sh 2>&1 1>&3 | tee -a stderr.log 1>&3
# cleanup collector
exec 3>&-
은 기서 the of의 입니다.2>&1 1>&3
이 경우 표준 에러를 표준 출력으로 리다이렉트하고 표준 출력을 파일 기술자 3으로 리다이렉트 합니다.현시점에서는 표준오차와 표준출력은 아직 조합되지 않았습니다.
실제로 표준오차(표준입력)는 다음 주소로 전달됩니다.tee
서 「」에 로그 .stderr.log
파일 디스크립터 3으로 리다이렉트 합니다.
파일 은 이 하고 있습니다.combined.log
그...combined.log
에는 표준 출력과 표준 오류가 모두 포함되어 있습니다.
POSIX에 답변해 주셔서 감사합니다.
POSIX에서 필요한 더 복잡한 상황은 다음과 같습니다.
# Start script main() function
# - We redirect standard output to file_out AND terminal
# - We redirect standard error to file_err, file_out AND terminal
# - Terminal and file_out have both standard output and standard error, while file_err only holds standard error
main() {
# my main function
}
log_path="/my_temp_dir"
pfout_fifo="${log_path:-/tmp}/pfout_fifo.$$"
pferr_fifo="${log_path:-/tmp}/pferr_fifo.$$"
mkfifo "$pfout_fifo" "$pferr_fifo"
trap 'rm "$pfout_fifo" "$pferr_fifo"' EXIT
tee -a "file_out" < "$pfout_fifo" &
tee -a "file_err" < "$pferr_fifo" >>"$pfout_fifo" &
main "$@" >"$pfout_fifo" 2>"$pferr_fifo"; exit
( 「」 「」 「」)STDERR
또는 할 수 : ) 、 음 、 음 、 다 、 다 、 다 、 다 、 ) 、 ):::::: 。
배쉬:
gcc temp.c &> error.log
C 쉘(csh
% gcc temp.c |& tee error.log
참고 항목: 컴파일/빌드 오류를 파일로 리디렉션하려면 어떻게 해야 합니까?
언급URL : https://stackoverflow.com/questions/692000/how-do-i-write-standard-error-to-a-file-while-using-tee-with-a-pipe
'programing' 카테고리의 다른 글
* 경유로 숨김 파일을 포함한 모든 파일을 부모 디렉토리로 이동하는 방법 (0) | 2023.04.16 |
---|---|
목표 C의 상수 (0) | 2023.04.16 |
여러 열에 그룹 기준 사용 (0) | 2023.04.16 |
로그아웃 후 다시 로그인하지 않고 .bashrc 설정을 새로고침하려면 어떻게 해야 합니까? (0) | 2023.04.16 |
NSURLC Connection을 사용하여 신뢰할 수 없는 증명서를 SSL로 접속하려면 어떻게 해야 합니까? (0) | 2023.04.16 |