출처 :
http://revoman.tistory.com/entry/stderr-redirection
표준 에러 출력(stderr) 재지정(>&, 2>)
표준에러(stderr) 재지정
유닉스 쉘에서는 표준 입력(stdin), 표준 출력(stdout), 표준 에러 출력(stderr)로 이미 정해진 파일이나 장치로 지정되어 있다. 유닉스 쉘에서 표준으로 지정된 에러출력(/dev/null)를 다른 파일이나 장치로 다시 지정하는 것을 재지정(redirection)이라 하며, 이렇게 방향을 재지정함으로써, 어떤 명령이 실행되는 과정에서 발생하는 오류 메시지를 모니터가 아닌 지정한 파일 따위에 저장하므으로써 에러를 정확하게 분석할 때 유용하게 사용할 수 있다.
---------- 출력 ------------------------------
> write (command > filename)
>> append (command >> filename)
< read (command < filename)
2> stderr (command 2> filename) - sh, ksh, bash
>& stderr (command >& filename) - csh
기본적으로 stdin, stdout, stderr를 위해 오픈 되는 파일은 /dev/tty, 즉 자신의 터미널의 이름이다.
기본이 터미널이므로 사용자들은 프로그램에게 어디에서 읽고 어디에 쓰라고 지정할 필요가 없다.
모든 쉘들은 stdin, stdout, stderr에 대한 기본적인 리다이렉션을 제공한다. 다만 Bourne 쉘은 추가로 파일 기술어 번호를 3에서 9까지 다룰 수 있다.
csh에서는 표준 에러 전환은 sh(bash)와는 다르다. 본쉘(sh)이나 콘쉘(ksh)에서는 표준 에러 전환으로 2> 를 사용하나, C쉘(csh)에서는 >& 를 사용한다.
noclobber 선택자가 설정된 경우는 >! 와 >&! 기호를 사용하면 csh가 기존의 파일 위에 덧붙여 기록한다. 또한 기존 파일 뒤에 출력을 추가하는 경우는 >>! 나 >>&! 기호를 사용한다.
쉘은 항상 기본적으로 표준입력(stdin, 키보드), 표준출력(stdout, 모니터), 표준에러(stderr, 모니터에 나타낼 에러 메세지) "파일들"을 열어 놓는다. 이 파일들을 포함해서 열려 있는 어떤 파일이라도 재지정 될 수 있다. 그러므로 재지정하여 파일, 명령어, 프로그램, 스크립트, 심지어는 스크립트 속의 코드 블럭의 출력을 받아 다른 파일, 명령어, 프로그램, 스크립트의 입력으로 보내는 것이 가능하다.
열려 있는 파일 각각은 파일 디스크립터(file descriptor)를 할당 받는다.
[1] 표준입력, 표준출력, 표준에러에 해당하는 파일 디스크립터는 각각 0, 1, 2 이다. 추가적으로 열리는 파일을 위해서 3부터 9까지의 파일 디스크립터가 남겨져 있다.
종종, 이 추가적인 파일 디스크립터들중의 하나를 표준입력, 표준출력, 표준에러로 할당해서 임시적인 중복된 링크로 쓰는 것이 유용할 때가 있다.
[2] 이런 방법을 쓰면 아주 복잡한 재지정이나 파일 디스크립터를 뒤죽 박죽 사용했을 때, 아주 간단하게 원래대로 복구시켜 준다
【예제】
$ echo 1234567890 > aa ☜ "aa"에 문자열을 씀
$ exec 3<> aa ☜ "aa"을 열고 3번 파일 디스크립터를 할당
$ read -n 4 <&3 ☜ "aa"을 열고 3번 파일 디스크립터를 할당
$ echo -n . >&3 ☜ 소수점을 쓰고
$ exec 3>&- ☜ 3번 파일 디스크립터를 닫음
$ cat aa
1234.67890
$
파일 디스크립터 닫기
연산자 |
의미 |
n<&- |
n번 입력 파일 디스크립터를 닫음 |
0<&-, <&- |
표준입력을 닫음 |
n>&- |
n번 출력 파일 디스크립터를 닫음 |
1>&-, >&- |
표준출력을 닫음 |
|
【예제】
자식 프로세스는 열려 있는 파일 디스크립터를 상속 받는데 이것 때문에 파이프가 동작한다. 파일 디스크립터가 상속되길 바라지 않는다면 그 파일 디스크립터를 닫으면 된다.
$ exec 3>&1 ☜ 표준출력의 현재 "값"을 저장.
$ ls -l 2>&1 >&3 3>&- | grep bad 3>&- ☜ 'ls'와 'grep'을 위해 3번 파일 디스크립터를 닫고,
$ exec 3>&- ☜ 이제, 스크립트 나머지 부분을 위해 닫습니다.
【예제】
% bash ☜ bash로 쉘 전환
$ ping -c 1 203.234.57.256 2> bb >&2 ☜ 203.234.57.256이라는 호스트는 없음
$ cat bb ☜ 그러므로 표준 에러 출력이 bb파일에 저장됨
ping: unknown host 203.234.57.256
$ ping -c 1 203.234.57.33 2> kk >&2 ☜ 정상적인 ping 결과가 kk 파일에 저장됨
$ cat kk
203.234.57.33 is alive
$
$ csh ☜ csh로 쉘 전환
% ping -c 1 203.234.57.256 >& aa ☜ 203.234.57.256이라는 호스트가 없음
% cat aa ☜ 그러므로 표준 에러 출력이 aa 파일에 저장됨
ping: unknown host 203.234.57.256
%