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


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.