유닉스 쉘에서 추가 조작 을 위해 스트림 으로 결합 stderr
하고 싶다면 명령 끝에 다음을 추가 할 수 있습니다.stdout
stdout
2>&1
따라서 head
의 출력에서 사용하려면 g++
다음과 같이 할 수 있습니다.
g++ lots_of_errors 2>&1 | head
처음 몇 개의 오류 만 볼 수 있습니다.
나는 항상 이것을 기억하는 데 어려움을 겪고 있으며 끊임없이 찾아야하며, 주로이 특정 트릭의 구문을 완전히 이해하지 못하기 때문입니다.
누군가 이것을 분해하여 성격별로 설명 할 수 있습니까 2>&1
?
답변
파일 디스크립터 1은 표준 출력 ( stdout
)입니다.
파일 디스크립터 2는 표준 오류 ( stderr
)입니다.
첫째,에 : 여기에 (이 완전히 정확하지 않지만)이 구문을 기억하는 한 방법입니다 2>1
리디렉션 할 수있는 좋은 방법처럼 보일 수 있습니다 stderr
에가 stdout
. 그러나 실제로는 ” stderr
이름이 지정된 파일로 리디렉션”으로 해석됩니다 1
. &
다음은 파일 설명자가 아니라 파일 설명 자임을 나타냅니다. 따라서 구문은 다음과 같습니다 2>&1
.
답변
echo test > afile.txt
stdout을로 리디렉션합니다 afile.txt
. 이것은하는 것과 같습니다
echo test 1> afile.txt
stderr을 리디렉션하려면 다음을 수행하십시오.
echo test 2> afile.txt
>&
스트림을 다른 파일 설명 자로 리디렉션하는 구문입니다. 0은 stdin, 1은 stdout, 2는 stderr입니다.
다음을 수행하여 stdout을 stderr로 리디렉션 할 수 있습니다.
echo test 1>&2 # or echo test >&2
혹은 그 반대로도:
echo test 2>&1
즉, 2>
stderr을 (지정되지 않은) 파일로 &1
리디렉션하고 stderr을 stdout에 리디렉션합니다.
답변
리디렉션에 대한 몇 가지 요령
이것에 대한 일부 구문 특수성은 중요한 동작을 가질 수 있습니다. 리디렉션에 대한 몇 가지 작은 샘플이 STDERR
, STDOUT
그리고 인수 순서 .
1-덮어 쓰기 또는 추가?
기호 >
의미 리디렉션 .
>
전체 완성 된 파일로 전송 , 대상이있는 경우 덮어 쓰기 를 의미 합니다 ( 나중에 # 3의noclobber
bash 기능 참조 ).>>
존재하는 경우 대상 에 추가하는 것 외에도 보내기를 의미 합니다.
어쨌든 파일이 없으면 작성됩니다.
2- 쉘 명령 행 은 순서에 따라 다릅니다 !!
이를 테스트하기 위해 두 가지 출력 모두에 무언가를 보내는 간단한 명령이 필요 합니다 .
$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
( /tnt
물론; 이라는 이름의 디렉토리가 없을 것으로 예상합니다 .) 글쎄, 우리는 그것을 가지고있다 !!
자, 보자 :
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1
$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory
마지막 명령 줄 STDERR
은 콘솔에 덤프 되며 예상되는 동작이 아닌 것 같습니다 … 그러나 …
한 출력, 다른 출력 또는 둘 다에 대해 일부 포스트 필터링 을 수행하려는 경우 :
$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'
$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
이 문단의 마지막 명령 행은 이전 문단과 똑같습니다. 여기에서 필자 가 예상 한 동작이 아닌 것 같습니다 (따라서 이것은 예상 된 동작 일 수도 있습니다).
글쎄, 두 출력에서 다른 작업 을 수행 하기 위해 리디렉션에 대한 약간의 트릭이 있습니다
.
$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2 2>&1 | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan 7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory
참고 : &9
디스크립터는로 인해 자연스럽게 발생합니다 ) 9>&2
.
부록 : nota! 새로운 버전으로세게 때리다( >4.0
) 이런 종류의 작업을 수행하기위한 새로운 기능과 더 섹시한 구문이 있습니다.
$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory
마지막으로 이러한 계단식 출력 형식의 경우 :
$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
1 O: drwxrwxrwt 118 root root 196608 Jan 7 12:29 /tmp
2 E: ls: cannot access /tnt: No such file or directory
부록 : nota! 두 가지 방식으로 동일한 새 구문 :
$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
1 O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
2 E: ls: cannot access /tnt: No such file or directory
경우 STDOUT
, 특정 필터를 통해 이동 STDERR
다른 그리고 마지막으로 모두 출력은 세 번째 명령 필터를 통해 이동을 합병했다.
3- noclobber
옵션과 >|
구문 에 관한 단어
덮어 쓰기 에 관한 것입니다 .
set -o noclobber
bash가 기존 파일을 덮어 쓰지 않도록 지시 하지만 >|
구문을 사용하면 다음 과 같은 제한 사항을 통과 할 수 있습니다.
$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:15 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:19 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:21 CET 2013
매번 파일을 덮어 씁니다.
$ set -o noclobber
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
로 통과 >|
:
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:18:58 CET 2013
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:19:01 CET 2013
이 옵션을 설정 해제하거나 이미 설정했는지 문의하십시오.
$ set -o | grep noclobber
noclobber on
$ set +o noclobber
$ set -o | grep noclobber
noclobber off
$ date > $testfile ; cat $testfile
Mon Jan 7 13:24:27 CET 2013
$ rm $testfile
4-마지막 트릭 등 …
주어진 명령의 두 출력을 리디렉션하기 위해 올바른 구문은 다음과 같습니다.
$ ls -ld /tmp /tnt >/dev/null 2>&1
이 특별한 경우에는 다음과 같은 바로 가기 구문이 있습니다. &>
… 또는>&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
참고 : 2>&1
존재 1>&2
하는 경우 올바른 구문이기도합니다.
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b- 이제 다음에 대해 생각해 보도록하겠습니다.
$ ls -ld /tmp /tnt 2>&1 1>&2 | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
$ ls -ld /tmp /tnt 1>&2 2>&1 | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
4c- 더 많은 정보에 관심이 있다면
다음을 누르면 훌륭한 매뉴얼을 읽을 수 있습니다.
man -Len -Pless\ +/^REDIRECTION bash
안에 세게 때리다 콘솔 😉
답변
나는 리디렉션에이 화려한 게시물을 발견 : 모든 재 지정에 대해
표준 출력 및 표준 오류를 파일로 리디렉션
$ 명령 &> 파일
이 단일 라이너는 &>
연산자를 사용하여 출력 스트림 (stdout 및 stderr)을 명령에서 파일로 리디렉션합니다. 두 스트림을 동일한 대상으로 빠르게 리디렉션하기위한 Bash의 바로 가기입니다.
Bash가 두 스트림을 리디렉션 한 후 파일 디스크립터 테이블의 모습은 다음과 같습니다.
보시다시피 stdout과 stderr은 이제를 가리 킵니다 file
. 따라서 stdout 및 stderr에 작성된 내용은으로 기록됩니다 file
.
두 스트림을 동일한 대상으로 리디렉션하는 방법에는 여러 가지가 있습니다. 각 스트림을 차례로 리디렉션 할 수 있습니다.
$ 명령> 파일 2> & 1
이것은 두 스트림을 파일로 리디렉션하는 훨씬 일반적인 방법입니다. 첫 번째 stdout이 파일로 경로 재 지정된 후 stderr이 stdout과 동일하도록 복제됩니다. 따라서 두 스트림이 모두를 가리 킵니다 file
.
Bash가 여러 리디렉션을 발견하면 왼쪽에서 오른쪽으로 처리합니다. 단계를 수행하고 어떻게 발생하는지 봅시다. 명령을 실행하기 전에 Bash의 파일 디스크립터 테이블은 다음과 같습니다.
이제 Bash는 첫 번째 리디렉션 파일을 처리합니다. 우리는 이것을 전에 보았고 stdout이 파일을 가리 키도록합니다.
다음 Bash는 두 번째 리디렉션 2> & 1을 봅니다. 우리는 이전에이 리디렉션을 보지 못했습니다. 이것은 파일 디스크립터 2를 파일 디스크립터 1의 사본으로 복제하여 다음을 얻습니다.
두 스트림 모두 파일로 리디렉션되었습니다.
그러나 여기서 조심하십시오! 쓰기
명령> 파일 2> & 1
쓰기와 동일하지 않습니다 :
$ 명령 2> & 1> 파일
Bash에서 리디렉션 순서가 중요합니다! 이 명령은 표준 출력 만 파일로 리디렉션합니다. stderr는 여전히 터미널에 인쇄됩니다. 그 이유를 이해하려면 단계를 다시 수행하십시오. 따라서 명령을 실행하기 전에 파일 디스크립터 테이블은 다음과 같습니다.
이제 Bash는 리디렉션을 왼쪽에서 오른쪽으로 처리합니다. 먼저 2> & 1을보고 stderr을 stdout에 복제합니다. 파일 디스크립터 테이블은 다음과 같습니다.
이제 Bash는 두 번째 경로 재 지정을보고 >file
stdout을 파일로 경로 재 지정합니다.
여기서 무슨 일이 일어나는지 보십니까? Stdout은 이제 파일을 가리 키지 만 stderr은 여전히 터미널을 가리 킵니다! stderr에 기록되는 모든 내용이 여전히 화면에 인쇄됩니다! 따라서 리디렉션 순서에 매우주의하십시오!
또한 Bash에서 다음과 같이 작성하십시오.
$ 명령 &> 파일
정확히 다음과 같습니다.
$ 명령> & file
답변
숫자는 파일 디스크립터 (fd)를 나타냅니다.
- 제로
stdin
- 하나는
stdout
- 두
stderr
2>&1
fd 2를 1로 리디렉션합니다.
프로그램에서 사용하는 파일 디스크립터 수에 관계없이 작동합니다.
/usr/include/unistd.h
잊어 버린 경우 살펴볼 수 있습니다 .
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
즉, 사용자 정의 로깅에 비표준 파일 디스크립터를 사용하는 C 도구를 작성 했으므로 파일이나 파일로 리디렉션하지 않으면 볼 수 없습니다.
답변
이 구문은 표준 오류 스트림 ( stderr
)을 표준 출력 ( ) 의 현재 위치로 보냅니다. stdout
이 통화 문제는 다른 답변에서 무시 된 것으로 보입니다.
이 방법을 사용하여 출력 핸들을 다른 출력 핸들로 리디렉션 할 수 있지만 처리를 위해 단일 스트림으로 채널링 stdout
및 stderr
스트리밍 하는 데 가장 많이 사용됩니다 .
몇 가지 예는 다음과 같습니다.
# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR
# Run the less pager without stderr screwing up the output.
foo 2>&1 | less
# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile
# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2
마지막 한 점에 유의 하지 지시 stderr
에 outfile2
– 그것은 무엇에 리디렉션 stdout
인수가 발견되었을 경우에 (했다 outfile1
)와 다음은 리디렉션 stdout
에 outfile2
.
이것은 꽤 정교한 속임수를 허용합니다.
답변
2>&1
POSIX 쉘 구조입니다. 다음은 토큰 별 분류입니다.
2
: ” 표준 오류 “출력 파일 설명자.
>&
: 출력 파일 디스크립터 연산자 ( 출력 재 지정 연산자 의 변형)를 복제합니다>
. 주어지면 [x]>&[y]
, 파일 디스크립터에 의해 표시 x
출력 디스크립터 파일의 복사본으로 이루어진다 y
.
1
” 표준 출력 “출력 파일 디스크립터.
이 표현식 2>&1
은 파일 디스크립터 1
를 location에 복사 2
하므로 2
실행 환경에서 ( “표준 오류”)로 기록 된 출력 은 원래 1
“표준 출력”으로 설명 된 것과 동일한 파일로 이동합니다 .
추가 설명 :
File Descriptor : “파일 액세스를 위해 열린 파일을 식별하는 데 사용되는 프로세스 별 고유 한 음이 아닌 정수입니다.”
표준 출력 / 오류 : 쉘 설명서 의 리디렉션 섹션 에서 다음 참고 사항을 참조하십시오 .
열린 파일은 0으로 시작하는 10 진수로 표시됩니다. 가능한 최대 값은 구현 정의입니다. 그러나 모든 구현은 응용 프로그램에서 사용하기 위해 0-9 이상을 지원해야합니다. 이 번호를 “파일 디스크립터”라고합니다. 값 0, 1 및 2는 특별한 의미와 일반적인 용도를 가지며 특정 리디렉션 작업에 의해 암시됩니다. 이를 각각 표준 입력, 표준 출력 및 표준 오류라고합니다. 프로그램은 일반적으로 표준 입력에서 입력을 가져 와서 표준 출력에 출력을 씁니다. 오류 메시지는 일반적으로 표준 오류로 작성됩니다. 경로 재 지정 연산자 앞에는 파일 설명자 번호를 지정하기 위해 하나 이상의 숫자 (개입 문자가 허용되지 않음)가있을 수 있습니다.