셸 명령 중 >/dev/null 2 > & 1 의 실현 원 리 를 탐구 합 니 다.

8327 단어 linuxshell
우선 표준 입력, 표준 출력, 표준 오류:
표준 입력 은 프로그램 이 입력 을 읽 을 수 있 는 위치 입 니 다.결 성 된 상황 에서 프로 세 스 는 키보드 에서 stdin 을 읽 습 니 다
표준 출력 은 프로그램 이 출력 을 기록 하 는 위치 입 니 다.결 성 된 상황 에서 프로 세 스 는 stdout 을 터미널 화면 에 기록 합 니 다
표준 오 류 는 프로그램 이 잘못된 메 시 지 를 기록 하 는 위치 입 니 다.결 성 된 상황 에서 프로 세 스 는 stderr 를 터미널 화면 에 씁 니 다
왜 이 세 가지 중요 한 개념 이 있 습 니까?프로그램 이 실행 되 려 면 입력, 출력 이 필요 하 며, 오류 가 발생 하면 자신의 오 류 를 나 타 낼 수 있어 야 한 다 는 것 을 잘 알 고 있 습 니 다.이것 은 바로 어 딘 가 에서 데 이 터 를 읽 고 데 이 터 를 어 딘 가 에 출력 해 야 하 며, 잘못 되면 오 류 를 한 곳 으로 가 져 가 야 한다. 이것 만으로 도 데이터 흐름 (stream) 이 될 수 있다.따라서 일반적으로 모든 유 닉 스 프로그램 은 시작 할 때 세 개의 흐름 을 엽 니 다. 하 나 는 입력 에 사용 되 고 하 나 는 출력 에 사용 되 며 하 나 는 진단 이나 오류 메 시 지 를 인쇄 하 는 데 사 용 됩 니 다.
이 세 가지 개념 이 생 겼 다.
다시 말 하면 방향 을 바꾼다.
데이터 흐름 재 설정 (재 설정) 은 특정한 명령 (명령) 을 실행 한 후의 실행 반환 값 입 니 다. 일반적으로 이 반환 값 은 실행 한 후에 화면 에 나타 나 는 결과 데이터 입 니 다. 만약 에 제 가 그 에 게 기본 값 으로 화면 으로 흐 르 게 하고 싶 지 않다 면 저 는 이 결과 데 이 터 를 다른 곳 으로 전송 할 수 있 습 니 다. 예 를 들 어 파일 이나 장치 등 입 니 다.(예 를 들 어 프린터, 하지만 Linux 에 서 는 모든 것 이 파일 이기 때문에 프린터 와 같은 장치 도 파일 입 니 다). 이렇게 하면 데 이 터 는 내 가 다른 곳 으로 가 는 것 이다. 알 잖 아. 그래서 물건 을 화면 에 출력 하 는 거 야. 데이터 가 너무 많 으 면 우 리 는 참 을 수 없어. 그리고 화면의 terminal 이 꺼 지면 물건 을 더 이상 찾 을 수 없어. 내 가 파일 로 다시 설정 하면 실 행 된 로 그 를 장기 적 으로 저장 할 수 있어.
4. 567917. > 데이터 흐름 재 가이드: 출력 가이드, 안내 되 는 파일 내용 을 교체 합 니 다. 4. 567918.
4. 567917. >> 데이터 흐름 재 가이드: 출력 가이드, 안내 되 는 파일 내용 을 교체 하지 않 습 니 다. 엉덩이 뒤에 데 이 터 를 누적 합 니 다. 4. 567918.
파일 설명자 계속 보기:
위 키 백과, 자유로운 백과사전 에 서 는 이렇게 말 합 니 다. 파일 설명자 (File descriptor)컴퓨터 과학 의 용어 입 니 다. 파일 을 가리 키 는 인용 을 표현 하 는 추상 화 된 개념 입 니 다. 파일 설명 자 는 형식 상 마이너스 정수 가 아 닙 니 다. 실제로 색인 값 입 니 다. 커 널 이 모든 프로 세 스 가 유지 하 는 프로 세 스 를 가리 키 며 파일 기록 표를 엽 니 다. 프로그램 이 기 존 파일 을 열거 나 새 파일 을 만 들 때 커 널 은 프로 세 스 로 향 합 니 다.파일 설명 자 를 되 돌려 줍 니 다. 프로 그래 밍 에 서 는 기본 적 인 프로그램 작성 이 파일 설명 자 를 중심 으로 전개 되 는 경우 가 많 습 니 다. 그러나 파일 설명자 라 는 개념 은 유 닉 스, 리 눅 스 와 같은 운영 체제 에 만 적 용 됩 니 다. 파일 설명자 의 장점 은 주로 두 가지 가 있 습 니 다. 파일 설명 자 를 기반 으로 하 는 I/O 작업 호 환 POSIX 표준 입 니 다. 유 닉 스, 리 눅 스 시스템 호출 에 서 는 많은 양의 파일 설명 자 를 사용 합 니 다.시스템 호출 은 모두 파일 설명자 에 의존 합 니 다. 이것 은 정말 추상 적 인 것 같 습 니 다. 즉, 프로그램 이 열 리 지 않 으 면 파일 이 디스크 위 에 외 로 울 때 파일 설명자 가 없습니다. 상상 해 보 세 요. 첫 번 째 로 열 린 파일 은 0 이 고 두 번 째 는 1 입 니 다. 이 유추 에 따 르 면 유 닉 스 운영 체 제 는 보통 모든 프로 세 스 가 열 수 있 는 파일 의 수량 에 제한 을 가 합 니 다.더 심 한 것 은 유 닉 스 는 보통 시스템 등급 의 제한 이 있 습 니 다. 물론 0, 1, 2 는 일반적으로 어떤 개념 에 의 해 점용 되 었 습 니 다. 게다가 시스템 이 시 작 된 후에 얼마나 많은 파일 을 열 었 는 지 모 릅 니 다. 그래서 저 희 는 보통 파일 을 열 때 설명자 도 큰 데이터 에 이 르 렀 을 것 입 니 다. 그러나 이 파일 설명자 의 단점 도 있 습 니 다. 예 를 들 어 완 성 된 코드 의 가 독성 등 입 니 다.이 세 기호 상수 의 정 의 는 헤더 파일 unistd. h 에 있 습 니 다. 파일 설명자 의 유효 범 위 는 0 에서 OPEN MAX 입 니 다. 일반적으로 프로 세 스 마다 최대 64 개의 파일 (0 - 63) 을 열 수 있 습 니 다.FreeBSD 5.2.1, Mac OS X 10.3, Solaris 9 의 경우 프로 세 스 마다 파일 을 최대 로 열 수 있 는 정 도 는 시스템 메모리 의 크기, int 의 크기, 시스템 관리자 가 설정 한 제한 에 달 려 있 습 니 다. Linux 2.4.22 강제 규정 은 최대 1, 048, 576 을 초과 해 서 는 안 됩 니 다.
위의 기본 개념 을 종합 하면 아래 의 것 도 이해 하기 어렵 지 않다.
표준 입력 (stdin): 파일 설명 자 는 0 입 니 다. < 또는 <; 를 사용 합 니 다.
표준 출력 (stdout): 파일 설명 자 는 1 입 니 다. > 또는 > 를 사용 합 니 다. (굳이 1 > 또는 1 > 로 쓰 지 는 않 겠 죠? 사실 이것 도 맞습니다. 하지만 너무 피곤 합 니 다) 출력 할 때 < 또는 < 를 사용 할 수 없습니다. 명령 이 항상 앞 에 있 기 때 문 입 니 다. 여기 서 데 이 터 를 출력 하 라 고 명령 합 니 다. 따라서 데이터 의 출처 는 명령 입 니 다. 데 이 터 는 화살표 에 따라 당신 이 주 는 방향 을 가리 키 게 됩 니 다.
표준 오류 출력 (stderr): 파일 설명 자 는 2 이 고 2 > 또는 2 >> 를 사용 합 니 다.
다시 예 를 들 어 설명 한다.
먼저 command > file 2 > file 은 명령 에 의 한 표준 출력 정보 와 잘못된 출력 정 보 를 file 에 보 내 는 것 을 의미 합 니 다. command > file 2 > file 과 같은 쓰기, stdout 과 stderr 는 모두 file 에 직접 보 내 고 file 은 두 번 열 립 니 다. 그러면 stdout 과 stderr 는 서로 덮어 씁 니 다. 이렇게 쓰 면 동시에 file 을 차지 하 는 파 이 프 를 두 번 사용 합 니 다. 방향 을 두 번 정 했 습 니 다.
command > file 2 > & 1 명령 을 사용 하면 stdout 을 file 에 직접 보 냅 니 다. stderr 는 첫 번 째 방향 변경 (FD1) 을 계 승 했 습 니 다.파이프 에 도착 한 후에 file 로 보 내 졌 습 니 다. 이때 file 은 한 번 만 열 렸 고 하나의 파이프 FD1 만 사 용 했 습 니 다. stdout 과 stderr 의 내용 도 포함 되 어 있 습 니 다. 이렇게 이해 할 수 있 습 니 다. file 을 파이프 로 표준 출력 에 연결 한 것 이 라 고 생각 합 니 다. 그리고 2 대표 의 표준 오류 출력 을 1 세대 표 의 표준 정보 출력 에 받 았 습 니 다. 모두 file 로 통 했 습 니 다.
 IO 효율 에 있어 서 이전 명령 의 효율 은 뒤의 명령 보다 낮 기 때문에 셸 스 크 립 트 를 작성 할 때 command > file 2 > & 1 을 많이 사용 합 니 다.
인 스 턴 스 를 보 세 요. (관련 이 해 를 깊이 있 게 합 니 다. 이 인 스 턴 스 는 인터넷 블 로 그 를 참조 합 니 다. intel 의 필기시험 문제 라 고 합 니 다)
질문: 다음 프로그램의 출력 은 무엇 입 니까? (intel 필기시험 2011)
int main(){
  fprintf(stdout,"Hello ");
  fprintf(stderr,"World!");
  return0;
}

그리고 출력 이 World! Hello 가 아니 라 Hello World!
이것 은 왜 일 까요? 기본 적 인 상황 에서 stdout 은 줄 버퍼 입 니 다. 그의 출력 은 buffer 안에 놓 여 있 습 니 다. 줄 을 바 꿀 때 만 화면 에 출력 됩 니 다. stderr 는 버퍼 가 없 으 며 직접 출력 합 니 다. 예 를 들 어 printf (stdout, xxxx) 와 printf (stdout, xxxx) 입 니 다. 전 자 는 새 줄 을 만 날 때 까지 참 습 니 다. printf (stderr, xxxx) 는 새 줄 을 만 날 때 까지 함께 출력 합 니 다."xxxx"), 있 든 없 든 출력 합 니 다.
마지막:
/dev/null 이 뭔 지 보 세 요.
UFO@UFO~:cd /dev
UFO@UFO :/dev$ls -l null
crw-rw-rw-  1 root root 1, 3 Feb 14  2012 null

보 셨 죠? 문자 장치 파일 (c) 입 니 다. 이 물건 은 요? 블랙홀 이 라 고 불 러 도 됩 니 다.
Blackhole? NO. 천문학 에 있 는 블랙홀 이 아 닙 니 다. 파일 만 쓰 는 것 과 매우 같 습 니 다. 모든 기록 내용 은 영원히 잃 어 버 립 니 다. 그 내용 을 읽 으 려 고 시도 하면 아무것도 읽 을 수 없습니다. 그러나/dev/null 은 명령 행 과 스 크 립 트 에 매우 유용 합 니 다.
glibc 라 이브 러 리 의 stdio. h 헤더 파일 에서:
#define    stdin    (&__sF[0])
#define    stdout    (&__sF[1])
#define    stderr    (&__sF[2])

예 를 들 면
fprintf(stderr, "UFO
");// "UFO"

셸 명령 에서 0, 1 과 2 는 각각 glibc 의 stdin, stdout 과 stderr 에 대응 합 니 다. 위 에서 우 리 는 대충 알 고 있 습 니 다.
stdin    표준 입력
stdout   표준 출력
stderr   표준 오류 출력
그래서 >/dev/null 은 프로그램 을 printf 나 fprintf 를 통 해 handle 이 1 인 stdout 파일 에 인쇄 한 정 보 를/dev/null 공동 파일 로 보 내 고/dev/null 노드 에 대응 하 는 kernel 을 실현 하 는 것 은 기 록 된 바이트 수 를 직접 되 돌려 주 는 것 이 므 로 프로그램 은/dev/null 에 성공 적 으로 저장 했다 고 생각 합 니 다. 그러나 >/dev/null 은 fprintf (stderr, "UFO") 를 사용 할 수 없습니다.stderr 에 인쇄 된 문자열 은 >/dev/null 로 보 내기 때문에 2 > & 1 명령 을 사용 해 야 합 니 다. 셸 이 2 stderr 에 있 는 데 이 터 를 1 stdout 으로 전송 한 다 는 뜻 이기 때문에 stderr 에 terminal 에 표 시 된 정보 도/dev/null 로 전 송 됩 니 다.
또 실례 를 봅 시다.
luther@gliethttp:~$ cat a.c
#include <stdio.h>
int main(int argc, char *argv[])
{
    fprintf(stdout,"luther stdout
"); fprintf(stderr,"luther stderr
"); return 0; } luther@gliethttp:~$ gcc a.c luther@gliethttp:~$ ./a.out luther stdout luther stderr luther@gliethttp:~$ ./a.out >/dev/null luther stderr// >/dev/null stderr /dev/null

test. sh 스 크 립 트 를 작성 합 니 다.
luther@gliethttp:~$ chmod +x test.sh
luther@gliethttp:~$ cat test.sh
exec ./a.out >/dev/null
luther@gliethttp:~$ ./test.sh
luther stderr       //    shell    stderr    /dev/null 
luther@gliethttp:~$ cat test.sh
exec ./a.out >/dev/null 2>&1
luther@gliethttp:~$ ./test.sh
luther@gliethttp:~$ //       ,stderr   2>&1      stdout  ,     /dev/null  
luther@gliethttp:~$ cat test.sh
exec ./a.out >/dev/null 1>&2
./test.sh
luther stdout
luther stderr
luther@gliethttp:~$

물론 tee 작업 에 도 위 와 같은 문제 가 존재 합 니 다. stderr 에 인쇄 된 log 는 tee 작업 에 의 해 포착 되 지 않 기 때문에 stderr 를 stdout 으로 재 설정 하여 이 문 제 를 해결 할 수 있 습 니 다.
인 스 턴 스 계속 보기:
luther@gliethttp:~$ ./a.out
luther stdout
luther stderr
luther@gliethttp:~$ ./a.out|tee luther.txt
luther stdout
luther stderr
luther@gliethttp:~$ cat luther.txt
luther stdout
luther@gliethttp:~$ ./a.out 2>&1|tee luther.txt
luther stderr
luther stdout
luther@gliethttp:~$ cat luther.txt
luther stderr
luther stdout
luther@gliethttp:~$ ./a.out 1>&2|tee luther.txt
luther stderr
luther stdout
luther@gliethttp:~$ cat luther.txt
luther@gliethttp:~$ //      ,  stdout    stderr,    log      tee  
  1>&2          shell  ,         ,1>&2            log  ,  :
luther@gliethttp:~$ 1>&2 ./a.out|tee luther.txt
luther stderr
luther stdout
luther@gliethttp:~$ ./a.out 1>2 //   stderr
luther stderr
luther@gliethttp:~$ ./a.out 2>1 //   stdout
luther stdout

OK. 쓰 고 싶 지 않 아 요. 너무 바 빠 요. 저 는 인터넷 에 있 는 많은 글 들 을 대 초 를 붙 여서 여기저기 흩 어 져 있 는 글 들 을 엉망진창 으로 통합 시 켰 을 뿐 이에 요. 그래서 저 는 자 이언 트 의 어깨 에 서서 대 초 를 한 번 했 습 니 다. 자 이언 트 들 에 게 감 사 드 립 니 다. 사실 위 에서 언급 한 개념 은 이 통합 문장 만 으로 는 완전히 설명 할 수 없습니다. 관련 개념 은 더 많은 것 은 자 이언 트 들 에 게 있 습 니 다.실천 과 문 서 를 보고 자신의 뇌 여과 와 사 고 를 더 합 니 다. 여러분 과 토론 하 기 를 바 랍 니 다!

좋은 웹페이지 즐겨찾기