2> & 1> output.log와 2> & 1 |의 차이점 | 티 output.log


35

다음 두 명령의 차이점을 알고 싶었습니다.

2>&1 > output.log 

2>&1 | tee output.log

동료 중 하나가 두 번째 옵션을 사용하여 리디렉션하는 것을 보았습니다. 나는 2> & 1이 무엇을하고 있는지, 나의 유일한 질문은 간단한 리디렉션 ">"연산자를 사용할 수있는 티를 사용하는 목적이 무엇인가?

답변:


11

두 명령을 개별적으로 살펴보십시오.

utility 2>&1 >output.log 

여기서 리디렉션은 왼쪽에서 오른쪽으로 처리되기 때문에 표준 오류 스트림은 표준 출력 스트림이있는 곳 (콘솔로)으로 리디렉션 된 다음 표준 출력 스트림이 파일로 리디렉션됩니다. 표준 오류 스트림은 해당 파일로 리디렉션 되지 않습니다 .

이것의 가시적 인 효과는 화면의 표준 오류에서 생성 된 것과 파일의 표준 출력에서 ​​생성 된 것을 얻는 것입니다.

utility 2>&1 | tee output.log

여기서 표준 오류를 표준 출력 스트림과 같은 위치로 리디렉션합니다. 이것은 스트림이 tee하나의 통합 된 출력 스트림으로 유틸리티에 파이프 되고이 표준 출력 데이터가에 의해 지정된 파일에 저장됨을 의미 tee합니다. tee콘솔에서 데이터가 추가로 재생산됩니다 (이것이 tee데이터 스트림을 복제 함).

이 중 어느 것이 사용되는지는 달성하고자하는 것에 달려 있습니다.

두 번째 파이프 라인의 효과 는 파일에서 표준 출력과 오류를 모두 저장하는 >(와 같이) 두 번째 파이프 라인의 효과를 재현 할 수 없습니다 utility >output.log 2>&1. tee콘솔과 출력 파일에서 데이터를 가져 오는 데 사용해야 합니다.


추가 사항 :

첫 번째 명령 의 가시적 인 효과

utility 2>&1 >output.log 

~와 같을 것이다

utility >output.log

즉, 표준 출력은 파일로 가고 표준 오류는 콘솔로갑니다.

위의 각 명령 끝에 추가 처리 단계가 추가 된 경우 다음과 같이 큰 차이가 있습니다.

utility 2>&1 >output.log | more_stuff

utility >output.log      | more_stuff

첫 번째 파이프 라인에서는 more_stuff원래 표준 오류 스트림을 utility표준 입력 데이터로 가져 오는 반면, 두 번째 파이프 라인에서는 파이프를 통해 전송되는 결과 표준 출력 스트림이므로 more_stuff파이프 라인 의 일부는 아무것도 얻지 못합니다. 표준 입력을 읽습니다.


명령 "으로 utility 2>&1 | tee output.log파일에 기록으로, 당신은 1 일부터 2뿐만 아니라이다, 티로 이동되고 있음을 말 뜻 이죠. 티가 스트림을 복제하기 때문에, 출력이 모두?뿐만 아니라 콘솔에 표시되는 사이에 따라서 차이 utility 2>&1 > output.logutility 2>&1 | tee output.log이다 tee는 스트림을 중복 점에서 올바른 것이라고.?
동기를

의 예제 utility 2>&1 > output.log | more_stuffutility >ouput.log| more_stuff , is the difference that more_stuff`는 표준 오류를 콘솔에 입력으로 출력 more_stuff합니까? 두 번째 예에서는 콘솔에 출력이 없으므로 본질적으로 more_stuff?에 대한 입력이 없습니다 . 그렇다면 이전 단락 이후 표준 출력이 파일로 이동하고 표준 오류가 콘솔로 이동한다는 사실을 알 수 없습니다.
동기 부여

@Motivated 첫 번째 의견이 맞습니다. 예. 두 번째 주석에 관해서는 : 첫 번째 명령에서 원래 오류 스트림으로 보낸 것을 more_stuff수신 하지만 표준 출력으로 리디렉션됩니다. 콘솔에 없으면 콘솔에서 끝나기 때문이 아니라 표준 출력 스트림으로 이동하기 때문 입니다. 두 번째 명령에서는 파이프 라인의 왼쪽에서 표준 출력이 없으므로 아무 것도 받지 않습니다 . 오류 스트림 은 여전히 ​​콘솔에서 두 번째 명령으로 종료됩니다. utilitymore_stuffmore_stuffutility
Kusalananda

감사. 명령 utility > output.log | more_stuff이 표준 오류 관점에서 표준 출력 스트림으로 출력되지 않기 때문에 의미 합니까?
동기 부여

@Motivated 왼쪽은 표준 출력에서 ​​아무 것도 생성하지 않으므로 (리디렉션 됨) 파이프를 통해 데이터가 전송되지 않습니다.
Kusalananda

24

편집 메모

이 답변에 대한 의견을 반드시 읽으십시오derobert .


원래 답변

2>&1 >output.log는 먼저 모든 파일 핸들 2 항목 (표준 오류)을 파일 핸들 1 (표준 출력) 보낸 다음 파일 보냅니다 output.log. 즉, 표준 오류 및 표준 출력을 로그 파일로 보냅니다.

2>&1 | tee output.log2>&1비트 와 동일하며 표준 출력과 표준 오류를 표준 출력 스트림에 결합합니다. 그 후, 그 파이프 관통 tee(같은 표준 출력을 표준 입력을 보낼 프로그램 cat)과 같은 파일로. 따라서 두 스트림 (오류 및 출력)을 결합한 다음이를 터미널과 파일로 출력합니다.

결론은 첫 번째 전송하는 것입니다 stderr/ stdout두 번째로 전송하는 동안, 파일에 모두 파일 및입니다 (표준 출력 아마 당신은 표준 출력을 리디렉션 한 다른 구조 내부 아니라면 터미널).

마지막 가능성은 다음과 같습니다.

(echo hello | tee xyzzy.txt) >plugh.txt

터미널에서 아무것도 끝나지 않습니다.


13
-1 구문은 맞지만 의미는 없습니다. 실행 cat /doesnotexist 2>&1 >output.txt- cat: /doesnotexist: No such file or directory터미널에 표시되는 것을 볼 수 있으며 output.txt는 빈 파일입니다. 우선 순위와 클로저 순서는 다음과 같습니다. 2>&1( 현재 fd1 에서 fd2를 fup2로 >output.txt변경) fd1을 output.txt로 리디렉션하고 다른 것은 변경하지 마십시오. 그 이유 2>&1 |는 다른 때문에 우선 순위입니다 : |전에 >.
Arcege

5
이 대답은 본질적으로 모든면에서 근본적으로 잘못되었습니다 . 아래 답변 중 많은 것이 더 좋지만 Kusalananda의 답변 이 가장 명확 하다고 생각 합니다 .
마이클 호머

2
@ user14408 : 유닉스와 리눅스 에서 계정을 만들고이 답변을 주장 하고 있다면 , 의견을 다룬 후 편집장을 제거해주십시오.
derobert

8

첫 번째 명령은 다른 작업을 수행합니다.

2>&1 > output.log 

이전 STDOUT은 STDERR에 저장 (복사) 된 다음 STDOUT이 파일로 리디렉션됩니다.

따라서 stdout은 파일로 이동하고 stderr은 콘솔로 이동합니다.

그리고

 2>&1 | tee output.log

두 스트림 모두 티로 리디렉션됩니다. Tee는 모든 입력을 표준 출력 (귀하의 콘솔)과 파일 ( output.log)에 복제합니다 .

그리고 또 다른 형태의 첫 번째가 있습니다.

    > output.log  2>&1

STDOUT 및 STDERR이 파일로 경로 재 지정됩니다.


4

전자는 파일로만 출력합니다. 두 번째는 파일 화면 모두에 출력 됩니다.


4

그 이유 2>&1 | tee는 stdout과 stderr을 로그 파일로 캡처하고 동시에 화면에서 볼 수 있기 때문입니다. 이 작업도 수행 할 수 >output.txt 2>&1 & tail -f있지만 백그라운드 명령이 언제 종료되었는지 알 수 없습니다. 프로그램이 종료되었거나 출력없이 실행되고 있습니다. 는 2>&1 | tee프로그래머를위한 공통 관용구이었다.


예를 들어 2> & 1> file.txt가 stdout 및 stderr을 file.txt로 캡처하지 않는다고 말 하시겠습니까?
동기 부여

0

샘플 코드를 먼저 보자.

#include <stdio.h>
main() 
{
// message 1, on stdout (using  printf)
printf("%s",          "message 1, on stdout (using  printf)\n");

// message 2, on stdout (using fprintf)
fprintf(stdout, "%s", "message 2, on stdout (using fprintf)\n");

// message 3, on stderr (using fprintf)
fprintf(stderr, "%s", "message 3, on stderr (using fprintf)\n");
}

결과를 비교할 수 있습니다.
./helloerror
+ 파일 : 메시지 없음; 콘솔 : 메시지 1,2,3;

./helloerror >error.txt
+ 파일 : 메시지 1,2; 콘솔 : 메시지 3;

./helloerror 2>&1 >error.txt
+ 파일 : 메시지 1,2; 콘솔 : 메시지 3;
+ ./helloerror> error.txt와 동일

./helloerror >error.txt 2>&1
+ 파일 : 메시지 3,1,2; 콘솔 : 메시지 없음;
+ 순서가 3, 1, 2 순

./helloerror | tee error.txt 2>&1
+ 파일 : 메시지 1,2; 콘솔 : 메시지 3,1,2;
+ 순서가 3, 1, 2 순

./helloerror 2>&1 | tee error.txt
+ 파일 : 메시지 3,1,2; 콘솔 : 메시지 3,1,2;

사용하려면 :
./helloerror >error.txt 2>&1
-> 파일에 모든 (stdout + stderr) 메시지를 원하지만 콘솔에 고정되지 않은 경우

./helloerror 2>&1 | tee error.txt
-> 파일에 모든 (stdout + stderr) 메시지를 원하고 콘솔에 인쇄 하려는 경우


-1

다음은 Unix 출력 스트림을 요약 한 게시물입니다. http://www.devcodenote.com/2015/04/unix-output-streams.html

게시물의 스 니펫 :

3 가지 표준 출력 스트림이 있습니다.

STDIN - Standard Input - Writes from an input device to the program
STDOUT - Standard Output - Writes program output to screen unless specified otherwise.
STDERR - Standard Error Output - Writes error messages. Also printed to the screen unless specified otherwise.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.