출력을 파일 및 stdout으로 리디렉션하는 방법


988

bash에서 호출 foo하면 stdout에서 해당 명령의 출력이 표시됩니다.

호출 foo > output하면 해당 명령의 출력이 지정된 파일 (이 경우 'output')로 리디렉션됩니다.

리디렉션 출력 할 수있는 방법은 파일에 있는가 는 표준 출력에 표시 한?


3
누군가가 파일에 오류 출력을 캡처하려고 여기에 온 경우 -unix.stackexchange.com/questions/132511/…
Murphy

2
용어에 대한 참고 사항 : 당신이 실행할 때 foo > output데이터가 되는 표준 출력과 표준 출력에 기록이 있다 라는 이름의 파일 output. 즉, 파일 쓰는 것이 stdout에 쓰는 것입니다. stdout과 터미널 모두에 쓸 수 있는지 묻습니다.
윌리엄 Pursell

2
@WilliamPursell 나는 확실히 당신의 설명은 물건을 향상 아니에요 :-) 이건 어때 : 그것은 직접 가능하다면 영업 이익은 요구하고있다 라는 프로그램의 파일과 모두 표준 출력을 호출 프로그램 (후자는 표준 출력되는 표준 출력 호출 된 프로그램이 것 특별한 일이없는 경우, 즉 호출 프로그램이 대화식 bash 세션 인 경우 터미널을 상속합니다. 그리고 그들은 또한 호출 된 프로그램의 stderr를 비슷하게 지시하고 싶을 수도 있습니다 ( "해당 명령의 출력"은 stderr를 포함하는 것으로 합리적으로 해석 될 수 있습니다).
Don Hatch

답변:


1379

원하는 명령의 이름은 tee다음과 같습니다.

foo | tee output.file

예를 들어 stdout에만 관심이있는 경우 :

ls -a | tee output.file

stderr을 포함 시키려면 다음을 수행하십시오.

program [arguments...] 2>&1 | tee outfile

2>&1채널 2 (stderr / standard error)를 채널 1 (stdout / standard output)로 리디렉션하여 둘 다 stdout으로 작성됩니다. 또한 tee명령 으로 지정된 출력 파일로 보내집니다 .

또한 로그 파일 에 추가 하려면 다음 tee -a과 같이 사용하십시오 .

program [arguments...] 2>&1 | tee -a outfile

173
OP가 "모든 출력"을 경로 재 지정하려면 stderr를 가져와야합니다. "ls -lR / 2> & 1 | tee output.file"
James Brady

45
@evanmcdonnal 정답은 틀리지 않습니다. 요구 사항에 따라 구체적이지 않거나 완전하지 않을 수 있습니다. 출력에 파일로 저장되는 부분으로 stderr을 원하지 않는 조건이 있습니다. 내가 5 년 전에이 질문에 대답했을 때 나는 OP가 게시물의 주제에서 stdout을 언급했기 때문에 stdout 만 원한다고 가정했다.
Zoredache

3
아 죄송합니다. 조금 혼란 스러웠을 수도 있습니다. 내가 그것을 시도했을 때 나는 단지 출력을 얻지 못했다. 아마 그것은 모두 stderr에 갈 것이다.
evanmcdonnal

38
덮어 쓰지 않고 -aon tee에 내용을 추가 하려면 on 인수를 사용하십시오 output.file.ls -lR / | tee -a output.file
kazy

16
$?나중에 사용하는 경우 상태 코드 인을 반환하며 tee이는 아마도 원하는 것이 아닙니다. 대신을 사용할 수 있습니다 ${PIPESTATUS[0]}.
LaGoutte

501
$ program [arguments...] 2>&1 | tee outfile

2>&1stderr 및 stdout 스트림을 덤프합니다. tee outfile스트림을 가져 와서 화면과 "outfile"파일에 씁니다.

이것은 아마도 대부분의 사람들이 찾고있는 것입니다. 아마도 일부 프로그램이나 스크립트가 오랫동안 열심히 일하고 많은 결과를 낳을 수 있습니다. 사용자는 정기적으로 진행 상태를 확인하고 출력을 파일에 기록하려고합니다.

문제는 (특히 stdout과 stderr 스트림을 혼합 할 때) 프로그램에 의해 플러시되는 스트림에 의존한다는 것입니다. 예를 들어 stdout에 대한 모든 쓰기가 플러시 되지 않지만 stderr에 대한 모든 쓰기 플러시되면 출력 파일 및 화면에서 시간 순서대로 종료됩니다.

프로그램이 진행 상황을보고하기 위해 몇 분마다 한두 줄만 출력하면 나쁘다. 이 경우 프로그램에서 출력을 플러시하지 않으면 몇 시간 동안 파이프를 통해 출력되는 것이 없기 때문에 사용자는 몇 시간 동안 화면에서 출력을 볼 수도 없습니다.

업데이트 : 패키지의 unbuffer일부인 프로그램 expect이 버퍼링 문제를 해결합니다. 이로 인해 stdout과 stderr이 화면과 파일에 즉시 기록되어 결합 및 리디렉션 될 때 동기화됩니다 tee. 예 :

$ unbuffer program [arguments...] 2>&1 | tee outfile

7
누구나 osx에 대한 '언 버퍼'를 알고 있습니까?
John Mee

7
unbuffer를 사용할 수 없다면 GNU coreutils에는 stdbuff 라는 도구가 포함되어 있습니다.이 도구는 출력 버퍼링을 방지하는 데 사용할 수 있습니다$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
Peter

1
OS X를 사용하는 경우 실행중인 명령에 신호를 전달하지 않더라도 대부분의 경우 언 버퍼를 사용하는 것이 훨씬 쉽습니다. 필자의 의견은 기본적으로 coreutils가 설치되어있는 Linux 사용자를위한 것이 었습니다. @Ethan, stdbuf 구문에 대해 혼란 스러우면이 답변을 참조하십시오 : stackoverflow.com/a/25548995/942781
Peter

3
참고 pythonA는 옵션이 내장되어 -u그 unbuffers 출력.
fabian789

1
추가 코드없이 로그하고 싶지만 실행 시간 / 일 동안 출력을 보는 ML 모델 교육을위한 절대적인 생명의 은인, 감사합니다!
rococo

126

나를 위해 일하는 또 다른 방법은

<command> |& tee  <outputFile>

gnu bash 매뉴얼에 표시된대로

예:

ls |& tee files.txt

'| &'를 사용하면 표준 출력 외에도 command1의 표준 오류 가 파이프를 통해 command2의 표준 입력에 연결됩니다. 그것은됩니다 2> & 1 나타내는 표현 |. 표준 오류를 표준 출력으로 암시 적으로 재지 정하는 것은 명령으로 지정된 재 지정 후에 수행됩니다.

자세한 내용은 리디렉션을 참조하십시오.


10
$?나중에 사용하는 경우 상태 코드 인을 반환하며 tee이는 아마도 원하는 것이 아닙니다. 대신을 사용할 수 있습니다 ${PIPESTATUS[0]}.
LaGoutte

1
이 방법은 컬러 콘솔 출력, 아이디어를 버립니다.
shakram02

시도 : 버퍼 해제 ls -l --color = auto | 티 files.txt
루치아노 안드레스 마티니

17

주로 Zoredache 솔루션을 사용할 수 있지만 출력 파일을 덮어 쓰지 않으려면 다음과 같이 -a 옵션을 사용하여 tee를 작성해야합니다.

ls -lR / | tee -a output.file

11

추가해야 할 것 ...

패키지 언 버퍼는 fedora 및 redhat unix 릴리스에서 일부 패키지에 대한 문제를 지원합니다.

문제 해결

다음은 나를 위해 일했습니다.

bash myscript.sh 2>&1 | tee output.log

감사합니다 ScDF & matthew 입력 시간이 많이 절약되었습니다 ..



3

이 유스 케이스 이후의 보너스 답변으로 나를 여기로 데려 왔습니다.

다른 사용자로이 작업을 수행해야하는 경우

echo "some output" | sudo -u some_user tee /some/path/some_file

에코는 사용자와 함께 발생하며 파일 쓰기는 "some_user"로 발생 합니다. 에코를 "some_user"로 실행하고 >> "some_file"로 출력을 리디렉션하는 경우 파일 리디렉션이 발생하는 경우 작동 하지 않습니다. 당신처럼.

힌트 : tee는 -a 플래그와 함께 append를 지원합니다. 파일에서 다른 사용자로 줄을 바꾸어야하는 경우 sed를 원하는 사용자로 실행할 수 있습니다.


2

< command > |& tee filename # 명령 상태를 컨텐츠로하여 "filename"파일을 작성합니다. 파일이 이미 존재하면 기존 컨텐츠를 제거하고 명령 상태를 기록합니다.

< command > | tee >> filename # 파일에 상태를 추가하지만 standard_output (화면)에 명령 상태를 인쇄하지 않습니다.

화면에서 "echo"를 사용하여 무언가를 인쇄하고 에코 된 데이터를 파일에 추가하고 싶습니다

echo "hi there, Have to print this on screen and append to a file" 

1

스크립트 시작 부분에 다음과 같은 것을 사용하여 전체 스크립트에 대해 그렇게 할 수 있습니다.

#!/usr/bin/env bash

test x$1 = x$'\x00' && shift || { set -o pipefail ; ( exec 2>&1 ; $0 $'\x00' "$@" ) | tee mylogfile ; exit $? ; }

# do whaetever you want

이 리디렉션 표준 오류 및 표준 출력 출력라는 파일에 모두 mylogfile 모든 표준 출력으로 이동하자 같은 시간에 .

바보 같은 속임수가 사용됩니다.

  • exec명령을 사용 하지 않고 리디렉션을 설정하고
  • tee출력을 복제 하는 데 사용
  • 원하는 리디렉션으로 스크립트를 다시 시작하십시오.
  • 특수 첫 번째 매개 변수 ( 특수 bash 표기법으로 NUL지정된 단순 문자 $'string')를 사용하여 스크립트가 다시 시작되도록 지정하십시오 (원래 작업에서 동등한 매개 변수를 사용할 수 없음).
  • pipefail옵션을 사용하여 스크립트를 다시 시작할 때 원래 종료 상태를 유지하십시오 .

추악하지만 특정 상황에서 나에게 유용합니다.


-13

티는 이것에 완벽하지만 이것 또한 일을 할 것입니다

ls -lr / > output | cat output

10
출력이 존재하지 않고 원하는 경우 원하는 것을 수행하지 않으면 오류가 발생합니다. 전반적으로 무의미합니다. 아마도 당신은 ";"을 의미했을 것입니다 "|"대신 ?
Robert Gamble

6
를 사용하더라도 ;느린 명령 중에 출력이 훨씬 지연됩니다.
Brad Koch
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.