[linux] 파이프로“티”를 사용하는 동안 파일에 stderr를 쓰려면 어떻게해야합니까?
내가 사용하는 방법을 알고 tee
출력 (작성 STDOUT
중) aaa.sh
에을 bbb.out
여전히 단말기에 표시하는 동안 :
./aaa.sh | tee bbb.out
이제 STDERR
라는 파일 ccc.out
을 계속 표시하면서 어떻게합니까?
답변
터미널에 STDERR 및 STDOUT이 계속 표시되기를 원한다고 가정합니다. 조쉬 켈리 (Josh Kelley)의 답변을 얻을 수는 있지만 tail
로그 파일을 매우 해킹하고 어리석게 출력하는 백그라운드를 유지합니다 . exra FD를 어떻게 유지하고 나중에 죽여서 정리해야하는지 기술적으로 기술적으로해야합니다 trap '...' EXIT
.
이를 수행하는 더 좋은 방법이 있으며 이미 발견했습니다 tee
..
stdout에 사용하는 대신 stdout에 대한 티와 stderr에 대한 티를 사용하십시오. 당신은 이것을 어떻게 성취 할 것입니까? 프로세스 대체 및 파일 리디렉션 :
command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
그것을 나누고 설명합시다.
> >(..)
>(...)
(프로세스 대체) FIFO를 작성하고 tee
청취하십시오. 그런 다음 >
(파일 리디렉션)을 사용 하여 STDOUT을 command
처음 tee
듣고 있는 FIFO 로 리디렉션합니다 .
두 번째도 마찬가지입니다.
2> >(tee -a stderr.log >&2)
프로세스 대체를 다시 사용 tee
하여 STDIN에서 읽고 프로세스를 덤프 하는 프로세스 를 만듭니다 stderr.log
. tee
입력을 STDOUT에 다시 출력하지만 입력이 STDERR이므로 tee
의 STDOUT을 STDERR로 다시 리디렉션하려고 합니다. 그런 다음 파일 리디렉션을 사용하여 command
의 STDERR을 FIFO의 입력 ( tee
STDIN) 으로 리디렉션 합니다.
http://mywiki.wooledge.org/BashGuide/InputAndOutput을 참조하십시오 .
프로세스 대체는 (POSIX 또는 Bourne) bash
과 달리 쉘로 선택하는 보너스로 얻는 정말 멋진 것들 중 하나입니다 sh
.
에서 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
이것은 단순히 리디렉션 stderr
하기 stdout
, 티 에코 그래서 모두가 로그인 화면에 할 수 있습니다. 다른 솔루션 중 일부가 실제로 복잡해 보이므로 뭔가 빠졌을 수 있습니다.
참고 : 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}
답변
stderr을 파일로 리디렉션하려면 stdout을 화면에 표시하고 stdout을 파일에 저장하십시오.
./aaa.sh 2> ccc.out | 티 ./bbb.out
편집 : stderr 및 stdout을 화면에 표시하고 파일에 모두 저장하려면 bash의 I / O 리디렉션을 사용할 수 있습니다 .
#!/bin/bash
# Create a new file descriptor 4, pointed at the file
# which will receive stderr.
exec 4<>ccc.out
# Also print the contents of this file to screen.
tail -f ccc.out &
# Run the command; tee stdout as normal, and send stderr
# 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) 도 참조하십시오 . 그리고 언제 추가 파일 디스크립터를 사용한다?
bash (및 ksh 및 zsh)에서는 대시와 같은 다른 POSIX 셸에서는 프로세스 대체를 사용할 수 있습니다 .
./aaa.sh > >(tee bbb.out) 2> >(tee ccc.out)
bash에서는이 명령 이 여전히 실행 되더라도 (ksh 및 zsh가 하위 프로세스를 기다리 ./aaa.sh
더라도) 완료 되 자마자이 명령이 리턴된다는 점에 유의하십시오 tee
. 다음과 같은 작업을 수행하면 문제가 될 수 있습니다 ./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
신용 (내 머리 위에서 대답하지 않음)은 여기에 있습니다 : http://www.cygwin.com/ml/cygwin/2003-06/msg00772.html
답변
필자의 경우 stdout 및 stderr을 파일로 리디렉션하는 동안 스크립트가 명령을 실행 중이었습니다.
cmd > log 2>&1
오류가 발생했을 때 오류 메시지를 기반으로 몇 가지 조치를 취하도록 업데이트해야했습니다. 물론 dup을 제거하고 2>&1
스크립트에서 stderr을 캡처 할 수는 있지만 오류 메시지는 참조를 위해 로그 파일로 이동하지 않습니다. @lhunath에서 허용 대답은 동일한 기능을 수행하도록되어 있지만, 리디렉션 stdout
및 stderr
내가 원하는하지 않은, 다른 파일에 있지만, 그것은 나를 정확한 해결책을 마련하는 데 도움이된다는 사실을 내가 필요 :
(cmd 2> >(tee /dev/stderr)) > log
위로, 로그는 모두의 사본을해야합니다 stdout
그리고 stderr
내가 캡처 할 수 있습니다 stderr
에 대해 걱정할 필요없이 내 스크립트 stdout
.