bash - 의미 - 표준 출력 표준 에러




셸에서 "2> & 1"은 무엇을 의미합니까? (10)

유닉스 셸에서 stderrstdout 을 더 많은 조작을 위해 stdout 스트림에 결합하고자한다면 다음과 같이 명령을 추가 할 수 있습니다.

2>&1

그래서 g++ 의 결과물에 head 를 쓰고 싶다면 다음과 같이 할 수 있습니다 :

g++ lots_of_errors 2>&1 | head

그래서 처음 몇 가지 오류 만 볼 수 있습니다.

나는 항상 이것을 기억하는 데 어려움이 있으며, 나는 끊임없이 그것을 찾아야 만한다. 그리고 이것은 내가이 특별한 트릭의 구문을 완전히 이해하지 못하기 때문에 주로 발생한다.

누군가 이것을 깨뜨리고 캐릭터가 2>&1 무엇을 의미하는지 설명 할 수 있습니까?


입력 방향 재 지정

입력을 재 지정하면 단어의 확장으로 인해 생성 된 이름의 파일이 파일 설명자 n에서 읽히도록 열리 며, n이 지정되지 않으면 표준 입력 (파일 설명자 0)이됩니다.

입력을 리디렉션하는 일반적인 형식은 다음과 같습니다.

[n]<word

출력 방향 재 지정

출력을 재 지정하면 단어의 확장으로 인해 생성 된 파일의 이름이 파일 설명자 n에 쓰여지며, n이 지정되지 않으면 표준 출력 (파일 설명자 1)이됩니다. 파일이 존재하지 않으면 생성됩니다. 존재하지 않으면 크기가 0으로 절단됩니다.

출력 방향 재 지정을위한 일반적인 형식은 다음과 같습니다.

[n]>word

파일 설명자 이동

리다이렉션 연산자,

[n]<&digit-

파일 설명자 숫자를 파일 설명자 n으로 이동 시키거나 n이 지정되지 않은 경우 표준 입력 (파일 설명자 0)으로 이동합니다. digit는 n으로 복제 된 후 닫힙니다.

마찬가지로 리디렉션 연산자

[n]>&digit-

파일 설명자 숫자를 파일 설명자 n으로 이동 시키거나 n이 지정되지 않은 경우 표준 출력 (파일 설명자 1)으로 이동합니다.

참고 :

man bash

/^REDIRECT 를 입력하여 redirection 섹션으로 이동하고 자세히 알아보기 ...

온라인 버전은 다음과 같습니다 : 3.6 Redirections

추신:

많은 시간 동안, man 은 리눅스를 배우는 강력한 도구였습니다.


리디렉션에 대한 몇 가지 트릭

이에 대한 구문의 특수성은 중요한 행동을 할 수 있습니다. 리디렉션, 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! 새로운 버전의 bash ( >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 을 다른 필터로 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

bash 콘솔에서 ;-)


귀하의 질문에 대답하려면 : 그것은 정상적으로 stderr 보낸 모든 오류 출력 걸리고 표준 출력 (stdout) 씁니다.

예를 들어 모든 출력에 대해 페이징이 필요할 때 'more'와 같이 유용합니다. 일부 프로그램은 사용 정보를 stderr에 인쇄하는 것과 같습니다.

기억할 수 있도록

  • 1 = 표준 출력 (프로그램이 정상 출력을 인쇄하는 곳)
  • 2 = 표준 오류 (프로그램이 오류를 인쇄하는 곳)

"2> & 1"은 stderr로 보낸 모든 것을 단순히 stdout으로 가리 킵니다.

또한이 주제가 어디서 자세히 다루어 지는지 오류가 발생하면이 게시물을 읽는 것이 좋습니다.


리디렉션에서이 훌륭한 게시물을 발견했습니다. 리디렉션 에 대한 모든 것

표준 출력과 표준 오류 모두를 파일로 리디렉션

$ command &> 파일

이 한면은 &> 연산자를 사용하여 stdout 및 stderr과 같은 두 출력 스트림을 명령에서 파일로 리디렉션합니다. Bash는 두 스트림을 동일한 대상으로 신속하게 리디렉션 할 수있는 바로 가기입니다.

다음은 Bash가 두 스트림을 모두 리디렉션 한 후 파일 설명자 테이블이 어떻게 표시되는지 나타냅니다.

보시다시피 stdout과 stderr가 모두 file 가리 킵니다. 그래서 stdout과 stderr에 쓰여진 것은 file 기록 file .

두 스트림을 동일한 대상으로 리디렉션하는 데는 여러 가지 방법이 있습니다. 각 스트림을 차례로 리디렉션 할 수 있습니다.

$ command> 파일 2> & 1

두 스트림을 파일로 리디렉션하는 훨씬 더 일반적인 방법입니다. 첫 번째 stdout은 file로 리디렉션되고 stderr은 stdout과 동일하게 복제됩니다. 따라서 두 스트림 모두 file 을 가리키게 file .

Bash는 몇 가지 리디렉션을 보았을 때 왼쪽에서 오른쪽으로 처리합니다. 계단을 거치며 어떻게되는지보십시오. 명령을 실행하기 전에 Bash의 파일 설명자 테이블은 다음과 같습니다.

이제 Bash는 첫 번째 리디렉션> 파일을 처리합니다. 우리는 전에 이것을 보았고 stdout이 파일을 가리킨다.

다음 Bash는 두 번째 리디렉션 2> & 1을 봅니다. 이전에는이 ​​리디렉션을 보지 못했습니다. 이 파일 디스크립터 2를 파일 디스크립터 1의 복사본으로 복제하면 다음과 같은 결과를 얻는다.

두 스트림 모두 파일로 리디렉션되었습니다.

그러나 여기에서 조심하십시오! 쓰기

명령> 파일 2> & 1

글쓰기와 같지 않습니다.

$ 명령 2> & 1> 파일

Bash에서 리디렉션 순서가 중요합니다! 이 명령은 표준 출력만을 파일로 재 지정합니다. 표준 오류는 여전히 터미널에 인쇄됩니다. 그 이유를 이해하려면 단계를 다시 시도해보십시오. 따라서 명령을 실행하기 전에 파일 설명자 테이블은 다음과 같습니다.

이제 Bash는 왼쪽에서 오른쪽으로 리디렉션을 처리합니다. 처음에는 2> & 1을 보게되므로 stderr를 stdout에 복사합니다. 파일 설명자 테이블은 다음과 같습니다.

이제 Bash는 두 번째 리디렉션 인 >file 보고 stdout을 파일로 리디렉션합니다.

여기서 일어나는 일을 보시겠습니까? stdout은 이제 파일을 가리키고 있지만 stderr은 여전히 ​​터미널을 가리 킵니다! stderr에 쓰여지는 모든 것은 여전히 ​​화면에 출력됩니다! 리디렉션 순서에 매우주의하십시오.

또한 Bash에서 글쓰기

$ command &> 파일

정확히 다음과 같습니다.

$ command> & 파일


숫자는 파일 설명자 (fd)를 참조합니다.

  • 제로는 stdin
  • 하나는 stdout
  • 2 개는 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 )의 현재 위치로 전송합니다.이 통화 문제는 다른 응답에 의해 무시 된 것처럼 보입니다.

이 방법을 사용하면 출력 핸들을 다른 핸들로 리디렉션 할 수 있지만 stdoutstderr 스트림을 단일 스트림으로 처리하여 처리 할 때 가장 많이 사용됩니다.

몇 가지 예는 다음과 같습니다.

# 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

마지막 명령은 stderroutfile2 보내지 않을 것임을 주목하십시오 - 인수가 outfile1 경우 stdout 을 리디렉션 한 다음 stdoutoutfile2 리디렉션합니다.

이것은 꽤 정교한 속임수를 허용합니다.


입력의 경우 0, stdout의 경우 1, stderr의 경우 2입니다.

한 가지 팁 : somecmd >1.txt 2>&1 은 맞지만 somecmd 2>&1 >1.txt 는 전혀 효과가 없습니다!


파일 설명자 1은 표준 출력 ( stdout )입니다.
파일 설명자 2는 표준 오류 ( stderr )입니다.

이 구조를 기억하는 한 가지 방법이 있습니다 (완전히 정확하지는 않지만). 처음에는 2>1stderrstdout 으로 리디렉션하는 좋은 방법 인 것처럼 보일 수 있습니다. 그러나 실제로는 " stderr1 이라는 파일로 리디렉션"으로 해석됩니다. & 다음에 나오는 것은 파일 설명자가 아니라 파일 설명 자임을 나타냅니다. 따라서 구성은 2>&1 됩니다.


/foo 가 시스템에없고 /tmp 가없는 경우 ...

$ ls -l /tmp /foo

/tmp 의 내용을 출력하고 /foo 대한 오류 메시지를 출력합니다.

$ ls -l /tmp /foo > /dev/null

/tmp 의 내용을 /dev/null 로 보내고 /foo 대한 오류 메시지를 출력합니다.

$ ls -l /tmp /foo 1> /dev/null

똑같은 일을 할 것입니다.

$ ls -l /tmp /foo 2> /dev/null

/tmp 의 내용을 출력하고 /dev/null 오류 메시지를 보냅니다.

$ ls -l /tmp /foo 1> /dev/null 2> /dev/null

오류 메시지와 함께 목록을 /dev/null 보냅니다.

$ ls -l /tmp /foo > /dev/null 2> &1

속칭이다


2>&1 은 POSIX 쉘 구조입니다. 다음은 토큰 별 분류입니다.

2 : " 표준 오류 "출력 파일 설명자.

>& : Output File Descriptor 연산자 ( Output Redirection 연산자 변형 > )를 복제합니다 . 주어진 [x]>&[y] , x 로 표시된 파일 기술자는 출력 파일 기술자 y 의 복사본이됩니다.

1 " 표준 출력 "출력 파일 설명자.

표현식 2>&1 은 파일 설명자 1 을 위치 2 복사하므로 실행 환경에서 2 ( "표준 오류")로 작성된 모든 출력은 처음에 1 ( "표준 출력")으로 설명 된 동일한 파일로 이동합니다.

추가 설명 :

파일 설명자 : "파일 액세스 목적으로 열린 파일을 식별하는 데 사용되는 프로세스 별 고유 한 음이 아닌 정수입니다."

표준 출력 / 오류 : 셸 설명서의 Redirection 섹션에서 다음 참고 사항을 참조하십시오.

열린 파일은 0으로 시작하는 십진수로 표시됩니다. 가능한 가장 큰 값은 구현 정의입니다. 그러나 모든 구현은 응용 프로그램에서 사용하기 위해 최소한 0에서 9까지를 지원해야합니다. 이 번호를 "파일 설명자"라고합니다. 값 0, 1 및 2는 특별한 의미와 일반적인 용도를 가지며 특정 재 지정 작업에 의해 암시됩니다. 표준 입력, 표준 출력 및 표준 오류라고합니다. 프로그램은 보통 표준 입력에서 입력을 받아 표준 출력으로 출력합니다. 오류 메시지는 대개 표준 오류로 작성됩니다. 리디렉션 연산자 앞에 파일 설명자 번호를 지정하기 위해 하나 이상의 숫자 (중간에 문자를 사용할 수 없음)를 붙일 수 있습니다.







redirect