2012-10-01 7 views
0

표준 출력을 표준 출력으로 보내는 명령을받는 데 문제가 있습니다. 내가 cron에 넣으려고하지만, 지금은 그냥 수동으로 실행하고 있습니다.표준 출력을 표준 출력으로 전송하지 않습니다.

/home/backups/backup_scripts/backup.sh 2>&1 >> /var/log/backups/backup.log 

나는 로그 파일이 표준 출력에 인쇄 된 메시지를 포함하는 것입니다 기대했다, 그러나 로그 파일은 표준을 보였으며, 콘솔 출력은 오류를 보여 주었다.

내가 뭘 잘못하고 있니?

답변

2

의미 상 동일합니다. 2>&1은 "표준 출력 위치가 인 현재 표준 오류로 리디렉션"을 의미합니다. 그들은 왼쪽에서 오른쪽으로 처리되므로 첫 번째 표준 오류는 현재 표준 출력 (여전히 터미널)로 리디렉션되고 표준 출력은 파일로 리디렉션됩니다. 주문을 전환하면

/home/backups/backup_scripts/backup.sh >> /var/log/backups/backup.log 2>&1 

으로 바뀌면 원하는대로 처리해야합니다. 셸이 bash 인 경우 표준 출력과 표준 오류를 동시에 리디렉션하는 바로 가기가 있습니다. command &> file 두 파일을 파일로 리디렉션하고 command &>> file을 파일에 모두 추가합니다. 이 순서 종속성은 bash 매뉴얼에도 언급되어 있습니다.

리다이렉션 순서가 중요합니다. 표준 오류가 도 중복 때문에 예를 들어, 명령

ls > dirlist 2>&1 

ls 2>&1 > dirlist 

이 dirlist 파일 만 표준 출력을 지시하는 명령하면서, 두 파일 dirlist 표준 출력 및 표준 오류를 지시 표준 출력이 dirlist로 리디렉션되기 전에 표준 출력에서.

파일 설명자 및 리디렉션 작동 방식에 대한 오해가 있다고 생각합니다. 커널은 파일 오프셋, 상태 플래그 및 파일 자체의 이름을 포함하는 시스템상의 모든 열린 파일의 큰 테이블을 가지고 있습니다. 그런 다음 각 프로세스에는 파일 설명자 번호를이 전역 테이블의 항목에 매핑하는 테이블이 있습니다.

어떤 리디렉션 글로벌 테이블 뭔가이

A: TERMINAL 

과 stdin을하는

0: A 
1: A 
2: A 
설명 번호 0, 1부터

, 2

같은 프로세스 테이블 보이는 것처럼 보일 수 있습니다 발생하기 전에, 표준 출력, 및 stderr 각각.

그런 다음 2>&1 리디렉션이 처리됩니다. 이것은 프로세스 테이블을 변경하여 2에 2가 동일한 전역 항목에 1을 포함하도록합니다. 그러나 이들은 이미 동일하므로 아무 일도 일어나지 않습니다.

>> /var/log/backups/backup.log 리디렉션이 처리 될 때. 먼저 파일이 열리고 것처럼 (테이블이

A: TERMINAL 
B: /var/log/backups/backup.log 

0: A 
1: A 
2: A 
3: B 

후 표준 출력이 새롭게 문을 연 파일을 가리 키도록 변경과 같이 있도록 프로세스 테이블에 설명 3 파일에 할당 1>&3는 완료) 그래서 프로세스 테이블 2 (표준 에러)가 여전히 터미널 가리키는

0: A 
1: B 
2: A 
3: B 

하는 것으로 지금 있었다.

다른 순서로 리디렉션이 수행되면 >> /var/log/backups/backup.log 이후의 표는 동일하게 보입니다.

0: A 
1: B 
2: A 
3: B 

하고 다음 2>&1 재 지정은 이제 표준 출력과 표준 에러 모두 파일로 이동을

0: A 
1: B 
2: B 
3: B 

을주는 무슨 2 점을 변경합니다.

+0

저는 이것을 정말로 이해하지 못합니다. 왼쪽에서 오른쪽으로 읽는다면, 당신이 제안하지 않은 명령이 작동하지 않을까요? 표준 출력을 파일로 리디렉션하지 않습니까? 그렇다면 먼저 표준 오류가 먼저 리디렉션되도록해야합니다. 그렇게하기 전에? – Brian

+0

@Brian, 편집을 참조하십시오. 아직도 불분명한지 알려주십시오. –

+0

흠 ... 그리고 당시 STDOUT의 현재 위치는 터미널입니다. 따라서 STDERR을 STDOUT으로 리디렉션하지만 여전히 터미널에 있습니다. 그렇다면 >>는 터미널의 STDOUT을 리디렉션해야합니다. 이제는 bash 스크립트의 STDERR이 포함되어 있지 않습니까? – Brian

2

리디렉션 문제의 순서입니다. 당신은 그것을 변경해야합니다 :

/home/backups/backup_scripts/backup.sh >> /var/log/backups/backup.log 2>&1 

/var/log/backups/backup.log에 표준 출력 리디렉션 후 (파일에 예정되어있는) 표준 출력에 열려진 리디렉션합니다.

또한의 짧은 형태로 사용할 수 있습니다

/home/backups/backup_scripts/backup.sh &>> /var/log/backups/backup.log 

&>>file이 때문에 리디렉션의 순서로 발생 >>file 2>&1

관련 문제