유닉스 / 리눅스에서 버퍼링하지 않고 출력을 파일로 리디렉션하는 방법이 있습니까?


49

디버그 및 프로세스 정보를 stdout에 출력하는 배치 프로세스가 오래 실행됩니다. 터미널에서 방금 실행하면 '어디에 있는지'를 추적 할 수 있지만 데이터가 너무 많아 져 화면에서 스크롤됩니다.

출력을 파일 '> out.txt'로 리디렉션하면 결국 전체 출력을 얻지 만 버퍼링되므로 더 이상 현재 수행중인 작업을 볼 수 없습니다.

출력을 리디렉션하지만 쓰기를 버퍼링하지 않는 방법이 있습니까?


1
아래의 (및 @cnst 's) "토론"을 살펴보십시오. 출력을 파일에 기록하는 것과 동시에 출력을 보는 것이 유일한 것 같습니다. 해결책을 찾은 경우 저희에게 알려주십시오.;)!
— Benj

답변:


52

setvbufC 에서 호출을 사용하여 표준 스트림의 버퍼링 옵션을 명시 적으로 설정할 수 있지만 ( 이 링크 참조 ) 기존 프로그램의 동작을 수정하려는 경우 stdbuf( coreutils버전 7.5 로 시작하는 부분 ).

이것은 stdout한 줄까지 버퍼링 합니다 :

stdbuf -oL command > output

이렇게하면 stdout버퍼링이 완전히 비활성화 됩니다.

stdbuf -o0 command > output

aaarghhh ... 내 우분투에는 7.4 coreutils 만 있습니다 ... :(
— Calmarius

@Calmarius : coreutils 컴파일은 매우 쉬워야합니다. ftp.gnu.org/gnu/coreutils 에서 새 버전을 가져 와서 사용하십시오. 표준 ./configure && make요금입니다. 나중에 설치하지 않아도 stdbuf바이너리 만 사용할 수 있습니다 src/.
— Eduardo Ivanec

두 번 아아. 나는 우분투뿐만 아니라 오래된 centos 배포판과 OSX에서도 이것을 필요로합니다.
— edk750


알려진 PID로 이미 실행중인 프로세스에 대해 파이프 / printf 버퍼를 외부에서 강제로 실행하는 방법이 있습니까?
— Mvorisek

9

다음 script과 같은 명령 을 사용하여 파일에 라인 버퍼 출력을 얻을 수 있습니다 .

stty -echo -onlcr   # avoid added \r in output
script -q /dev/null batch_process | tee output.log        # Mac OS X, FreeBSD
script -q -c "batch_process" /dev/null | tee output.log   # Linux
stty echo onlcr

-1 때문에 : a) 허용 된 답변과 달리 백그라운드에서 명령을 실행하려는 경우 작동하지 않습니다 ( 적어도 Linux 상자에서 위의 명령 batch_process을 추가 &하면 명령이 완료 되지 않고 즉시 종료됩니다 ). 매우 일반적인 사용 사례처럼, b)이 주문이 어떻게 작동하는지에 대한 설명은 없습니다.
— Mark Amery

8

우분투에서 unbuffer프로그램 ( expect-dev) 패키지가 나를 위해 속였습니다. 그냥 실행 :

unbuffer your_command

버퍼링하지 않습니다.


6

내가 찾은 가장 쉬운 솔루션 (설치 된 타사 패키지가 필요하지 않음)은 Unix & Linux 사이트 의 비슷한 스레드에서 언급되었습니다 script. 명령을 사용하십시오 . 오래되었으며 이미 설치되었을 수 있습니다.

$ script -q /dev/null long_running_command | print_progress       # FreeBSD, Mac OS X
$ script -q -c "long_running_command" /dev/null | print_progress  # Linux

참고 에 대한 첫 번째 파일 이름 매개 변수 script명령을 기록하는 로그 파일입니다 . 단순히 script -q your_command를 실행하면 로그 파일로 실행하도록 들여 쓴 명령을 덮어 씁니다. man script시도하기 전에 안전을 확인하십시오 .


4

script명령을 시도하십시오 . 시스템에 파일 이름이 있으면 파일 이름을 인수로 사용하고 stdout에 덤프 된 모든 텍스트가 파일에 복사됩니다. 설치 프로그램에 상호 작용이 필요할 때 매우 유용합니다.


'script -a out.txt'트릭을 알고 있습니다. 쓰기 프로세스를 버퍼링하지 않는 다른 방법이 있는지 궁금합니다.
— 제임스 딘

3

개인적으로 나는 검사하고 싶은 명령의 파이프 출력을 선호합니다 tee.

script키 누름 타이밍 및 인쇄 할 수없는 많은 문자를 포함하여 너무 많은 정보를 기록합니다. 무엇 tee저장하는 것은 더 많은 사람이 읽을 수 나를 위해입니다.


또한 명령 줄에 "| less"를 추가합니다.
— HUB

4
tee버퍼링에도 영향을받는 다고 확신합니다 . find명령의 출력을 분할 할 때 여전히 티에 의해 부분 라인이 표시되는 경우가 많습니다 .
— Magellan

2

출력을 파일로 재지 정하고 tail -f명령으로 파일을 따르십시오 .

편집하다

그래도 버퍼링이 발생하면 syslog 기능을 사용하십시오 (일반적으로 버퍼링되지 않음). 배치 프로세스가 쉘 스크립트로 실행되는 경우 logger 명령을 사용하여이를 수행 할 수 있습니다. 배치 작업이 스크립팅 언어로 실행되는 경우 어쨌든 로깅 기능이 있어야합니다.


3
이것이 내가 지금하는 일이지만 프로세스는 파일에 대한 쓰기를 버퍼링하므로 피하고 싶은 것입니다.
— 제임스 딘

업데이트 된 제안에 대한 내 편집을 참조하십시오.
— wolfgangsz

1
명백한 이유로 작동하지 않습니다. 도대체 누가 This answer is useful효과가없고 어쩌면 효과가없는 답을 제공 합니까?
— cnst November

1

tee마법 만 사용하면됩니다 !

someCommand | tee logFile.log것입니다 모두 콘솔에 표시하고 로그 파일에 작성합니다.


작동하지 않습니다. tee버퍼링이 발생하는 것을 막지 않습니다.
— cnst November

1
@cnst 효과적으로, tee일부 버퍼링을 피할 수는 없지만 출력이 무엇인지 볼 수만 있습니다. 이것은 @JamesDean이 원했던 것입니다 (나는 그의 질문을 이해하지 못했기 때문에). 버퍼링은 실제로 여기서 문제가되지 않는다고 생각합니다. 자세한 내용이 있으면 알려주십시오.
— Benj

그는 출력을보고 싶었고 (버퍼링되지 않은 방식으로) tee출력을 얻지 못했지만 출력을 얻지 못하는 것을 더 잘 볼 수 있도록 사용 하는 것이 좋습니다 .
— cnst

1
어떻게 @JamesDean 질문을 빨간색으로 표시합니까 : "파일 '> out.txt'로 출력으로 리디렉션합니다"는 콘솔 출력이 없다는 것을 의미합니다. 전체 출력이 리디렉션되는 동안 프로세스가 완료 될 때까지 기다리십시오. 사용 >하면 콘솔에 아무것도 표시되지 않습니다. @JamesDean이이를 설명하기 위해 "버퍼링"이라는 단어를 사용하고있는 것 같습니다. 나는 그가 원하는 것에 대해 더 많이 말할 수 있도록 그의 질문에 대한 의견을 게시 할 것입니다.
— Benj
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.