비 차단 버퍼링 명명 된 파이프?


20

나는 존재하지 않는 것으로 의심되는 것을 찾고 있습니다 : 커맨드 라인에서 사용하기위한 비 차단 버퍼링 명명 된 파이프 (fifo). 그런 것이 있습니까?

유스 케이스는 다음과 같습니다. 백그라운드에서 오랜 시간 동안 실행되고에 많은 출력을 뿌릴 프로세스가 있다고 가정합니다 stdout. 출력에 대해서는 신경 쓰지 않고 저장하고 싶지 않습니다 (아마도 충분한 공간이 없을 것입니다). 그러나 주기적으로 "들어가서"수행하고있는 작업을 수행 한 다음 다시 제거하고 싶습니다. 작업을 수행하도록 남겨 두십시오. 따라서 출력을 이론적으로 버퍼링 된 비 차단 명명 된 파이프로 리디렉션 한 다음 주기적으로 활용하고 싶습니다.

기본적으로 다음과 같이 시작하고 싶습니다 ( 10M버퍼 크기).

mkmagicfifo magicfifo 10M
spewingprocess > magicfifo &

... 무슨 일이 벌어지고 있는지 정기적으로 살펴 봅니다.

tail -f magicfifo

... 모든 출력 (정상 파일이 아님) magicfifo 저장 하지 않고 채우고 눌렀을 때 스푸핑 프로세스를 차단 하지 않고 (따라서 명명 된 파이프는 아닙니다).

나는 솔루션과 관련된 생각하지 않는다 tail또는 prune(내가 관련된 해결 방법을 생각할 수 있고, 잘 할 것 tail때문에) tail, 아직도 내가 (내가 드롭하고 그것을보고 중퇴 할 경우) 모든 데이터 어딘가에 저장하는 것이 필요 그리고 prune모든 출력을 생성하는 프로세스의 리디렉션을 깨는 아마 (내가이 입증 / 시도하지 않은 인정한다), 파일을 다시 작성해야합니다.

나는 이것을하기 위해 유틸리티를 쓸 수있을 것으로 기대하지만 * nix는 파일과 파이프의 멋진 측면을 많이 가지고 있습니다.

그래서 : 그런 것이 있습니까? 그렇다면 그렇다면 무엇입니까?


1
설명하는 것은 "링 버퍼"또는 "원형 버퍼"입니다. 나는 그것을 만드는 것이 쉽지는 않지만 그러한 것을 유지하기위한 명령 줄 도구를 모른다.
Shawn J. Goff

2
"Linux 비 차단 fifo (온 디맨드 로깅)", stackoverflow.com/questions/7360473/… 에 설명 된 솔루션을 살펴보십시오 .

1
StackOverflow에서 해결 된 것 같습니다 : stackoverflow.com/questions/7360473/…
James Blackburn

@JamesBlackburn : 감사합니다! 매우 흥미로운.
TJ Crowder 2016 년

답변:


16

나는 당신이 찾고있는 것이 GNU라고 생각합니다 screen. 하나 이상의 프로그램에서 마지막 화면 전체 또는 두 개 출력을 유지하기 위해 버퍼를 유지하며 연결을 끊었다가 나중에 다시 올 수 있습니다.


화면 제안에 +1 BTW, 많은 "히스토리 라인"을 보유하도록 구성 할 수 있습니다.
Mr Shunz

1
감사. 내 질문에 보여준 명령에 어떻게 적용 할 수 있는지 예를 들어 줄 수 있습니까? 매뉴얼 페이지는 창 관리자라고 말합니다 (그래픽 의미가 아니라 여전히 터미널 의미라고 생각합니다). 그리고 여전히 ssh를 통해 들어오고 필요에 따라 떨어질 수 있습니까? (예 : 원격 서버 운영)
TJ Crowder

예, 이런 식으로 GNU 화면을 사용할 수 있습니다. 새로운 (잠재적으로 명명 된) 세션을 만들고 해당 세션 내에서 명령을 실행 한 다음 연결을 끊습니다.
TML

2
이이기도 tmux하고 dtach- 터미널 멀티플렉서 / 세션 관리자 응용 프로그램의 같은 클래스에서 아무것도 같은 일을 달성 할 수 있어야한다.
jw013

5

pv파이프 라인에서 원하는만큼 버퍼링을 제공하는를 사용할 수 있습니다 . 다음과 같이 사용할 수 있습니다.

sprewingprocess | pv -B 1g > ordinaryfifo &

그러면 spewingprocessfifo 사이에 최대 1GB의 버퍼링이 제공 됩니다. 대부분의 Linux 배포판은 pv패키지를 믿거 나 말거나 패키지로 제공합니다 pv.


고맙지 만 파이프라는 대상을 읽지 않으면 버퍼가 가득 차면 그 블록이 안됩니까?
TJ Crowder

1
예,하지만 당신은 어떤 선택을해야합니까? 유한 한 우주에서는 문자 그대로 무제한 버퍼링을 가질 수 없습니다.
David Schwartz

다른 선택은 내 질문에 설명 된 것처럼 모든 출력을 저장하지 않습니다. 버퍼가 가득 차면 가장 오래된 것들이 버려집니다.
TJ Crowder

흠, 나는 이것을 테스트했는데 불행히도 완전히 작동하지는 않습니다. fifo를 읽는 프로세스가 잠시 동안 읽기를 중지하면 pv는 fifo에 쓰려고 시도하는 것을 차단하며 멀티 스레드가 아니기 때문에 pv의 버퍼로 데이터를 읽는 것도 차단합니다. 따라서 pv의 버퍼는 fifo를 읽는 프로세스가 계속 읽는 동안에 만 계속 채워집니다. pv는 일부 데이터를 읽고 버퍼링 할 수 있지만 기록기가 완전히 차단하지는 않습니다.
Daniel S. Sterling

1

나는 같은 문제가 있었다. 이것이 나의 첫 번째 해결책입니다. 먼저 각 줄마다 잘리는 파일에 출력을 쓰면 무한히 커지지 않습니다.

spewingprocess | while read line; do echo $line > buffer.txt ; done

그런 다음 tail을 사용하여 파일에서 읽습니다 ( 2> /dev/null"파일이 잘린"오류 메시지가 제거됩니다).

tail -f ./buffer.txt 2> /dev/null

이런 식으로 버퍼가 커지지 않고 원하는만큼 테일을 멀티플렉싱 할 수 있습니다. 그러나이 접근 방식의 문제점은이 테스트에서 볼 수 있듯이 꼬리가 읽을 수있는 것보다 빠르게 잘라낼 때 데이터를 잃을 수 있다는 것입니다.

for ((i=0; ; i++)) ; do echo "$i" ; done | while read line; do  echo $line > buffer.txt ; done
tail -f ./buffer.txt 2> /dev/null > log.txt

얼마 동안 실행 한 후 첫 줄과 마지막 줄은 다음과 같습니다.

$ head -n 1 log.txt
0
$ tail -n 1 log.txt
78783

그러나 파일의 줄 수가 적으므로 일부는 손실됩니다.

$ wc log.txt
67087  67087 392819 log.txt

데이터 손실에 대해 신경 쓰지 않거나 데이터 유출이 발생하기에 충분한 분출 과정이 빠르지 않은 경우에도 여전히 유용한 솔루션입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.