답변:
문제는 출력을 리디렉션 할 때 다음 리디렉션에 더 이상 사용할 수 없다는 것입니다. tee
서브 쉘로 파이프 하여 두 번째 경로 재 지정에 대한 출력을 유지할 수 있습니다 .
( cmd | tee -a file2 ) >> file1 2>&1
또는 터미널에서 출력을 보려면 다음을 수행하십시오.
( cmd | tee -a file2 ) 2>&1 | tee -a file1
최초의 표준 오류를 추가 방지하기 tee
위해 file1
, 당신은 어떤 파일 기술자 (예 : 3)에 명령의 표준 오류 리디렉션, 나중에 다시 표준 출력하려면이 옵션을 추가해야합니다 :
( 2>&3 cmd | tee -a file2 ) >> file1 3>&1
# or
( 2>&3 cmd | tee -a file2 ) 3>&1 | tee -a file1
(@ fra-san 덕분에)
로 zsh
:
cmd >& out+err.log > out.log
추가 모드에서 :
cmd >>& out+err.log >> out.log
에서 zsh
1, 제공된 mult_ios
파일 기술자 (여기 1) 쓰기를 위해 여러 번 리디렉션 할 때 옵션을 비활성화되지 않았습니다 후 쉘 구현 내장 된 tee
모든 대상에 출력을 복제 할 수 있습니다.
cmd >& file1 > file2
다음과 같이 할 수 있습니다. stdout에 태그를 지정하십시오 (UNBUFFERED sed 사용). sed -u ...
stderr에 stdout (태깅 sed를 거치지 않았으므로 태그가 지정되지 않음)으로 이동하여 결과 로그 파일에서 2를 구분할 수 있습니다.
다음은 :입니다 느린 (; 할 ...; 그것은 심각 대신하면서 ...의 exemple 펄 스크립트를 사용하여, 최적화 할 수있는 모든 라인에서 서브 쉘 및 명령을 산란 것, exemple를 들어, 다!), 이상한 에 ": 등, 그러나 그것이 (내가 하나 개의 이름 바꾸기 표준 출력에 다음 다른 하나의 그것에 표준 오류"를 통해 오리엔트 "추가하려면 2 {} 단계를 필요로 보인다) 개념의 증거 ", 즉 유지하려고합니다 출력 순서는 가능한 한 많은 stdout & 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
)를 사용 하여 stderr에 무언가를 인쇄합니까? >&2 echo "error"
괜찮을 것입니다. (2) tee
한 번에 여러 파일을 추가 할 수 있습니다. (3) 왜 cat
대신에 grep "^"
? (4) stderr 출력이로 시작하면 스크립트가 실패합니다 _stdout_
. (5) 왜?
ls loop
stdout과 stderr의 출력을 제어 된 순서로 혼합 (대안 적으로)하여 stdout의 태그 지정에도 불구하고 stderr / stdout 순서를 유지했는지 확인할 수 있습니다. 2) : gnu tail, 아마도, 그렇지 않습니다 규칙적인 꼬리 (예 : aix.). 3) : grep "^"에도 두 파일 이름이 모두 표시됩니다. 4) : 변수에 의해 변경 될 수 있습니다. 5) : 복잡한 예제는 내가 테스트 한 오래된 oses (ex, old aix)에서 작동합니다 (사용 가능한 펄 없음).
uniquetag="banaNa11F453355B28E1158D4E516A2D3EDF96B3450406
...)
출력 순서가 stdout이면 stderr ; 리디렉션 만있는 솔루션은 없습니다.
stderr은 임시 파일에 저장해야합니다
cmd 2>>file-err | tee -a file1 >>file2
cat file-err >> file1
rm file-err
기술:
하나의 출력 (stdout 또는 stderr와 같은 fd)을 두 파일 로 리디렉션하는 유일한 방법은 출력 을 재생하는 것입니다. 이 명령 tee
은 파일 디스크립터 컨텐츠를 재생하는 올바른 도구입니다. 따라서 두 파일에 하나의 출력을 갖는 초기 아이디어는 다음을 사용하는 것입니다.
... | tee file1 file2
이것은 티의 stdin을 두 파일 (1 & 2)로 재생하여 티의 출력을 여전히 사용하지 않습니다. 그러나 우리는 (use -a
) 를 추가해야하고 사본 하나만 필요합니다. 이렇게하면 두 가지 문제가 모두 해결됩니다.
... | tee -a file1 >>file2
공급하려면 tee
우리는 명령에서 직접 표준 에러 소비 할 필요가 표준 출력 (반복에 하나)와 함께. 한 가지 방법은 순서가 중요하지 않은 경우 (출력 순서는 생성 된대로 유지 될 것입니다 (아마도 먼저 출력되는 쪽이 먼저 저장 됨)). 어느 한 쪽:
cmd 2>>file1 | tee -a file2 >>file1
cmd 2>>file1 > >( tee -a file2 >>file1 )
( cmd | tee -a file2 ) >> file1 2>&1
옵션 2는 일부 쉘에서만 작동합니다. 옵션 3은 추가 서브 쉘 (느리게)을 사용하지만 파일 이름은 한 번만 사용하십시오.
하지만 표준 출력이 해야한다 먼저 우리는 마지막에 파일에 추가 할 저장 stderr에 필요 (중 위해 출력하는 생성) (최초의 솔루션이 게시).
sponge
.(cmd | tee -a out >> out+err) 2>&1 | sponge >> out+err
다양성을 위해 :
시스템 지원하는 경우 /dev/stderr
, 다음
(cmd | tee -a /dev/stderr) 2>> file1 >> file2
작동합니다. 의 표준 출력은 cmd
파이프 라인의 stdout 및 stderr 모두로 전송됩니다. cmd
바이 패스 의 표준 오차 는tee
는 파이프 라인 하고 나옵니다.
그래서
cmd
과cmd
은의 혼합 된 stdout과 stderr입니다 .그런 다음 해당 스트림을 올바른 파일로 보내는 것은 간단합니다.
(을 포함하여이 같은 거의 모든 방법과 마찬가지로 스테판의 대답 ),
file1
순서가 라인을 얻을 수 있습니다.
out+err
을out
의미 하는지 알 수 없습니다 . 파일명? 스트림을 리디렉션 하시겠습니까?