다른 명령으로 파이프하기 전에 명령 출력을 완전히 버퍼링하시겠습니까?

다른 명령으로 파이프하기 전에 명령 출력을 완전히 버퍼링하시겠습니까?

임시 파일 없이 다른 명령이 완료된 후에만 하나의 명령을 실행하는 방법이 있습니까? 장기 실행 명령과 출력 형식을 지정하고 컬을 사용하여 HTTP 서버로 보내는 또 다른 명령이 있습니다. 방금 실행하면 commandA | commandB시작 commandB되고 curl서버에 연결되어 데이터 전송이 시작됩니다. 시간이 너무 오래 걸리기 때문에 commandAHTTP 서버가 시간 초과되었습니다 . 난 내가 원하는 걸 할 수 있어commandA > /tmp/file && commandB </tmp/file && rm -f /tmp/file

호기심에 임시 파일 없이 이 작업을 수행할 수 있는 방법이 있는지 알고 싶습니다. 시도했지만 mbuffer -m 20M -q -P 100컬링 과정은 여전히 ​​처음부터 시작됩니다. Mbuffer는 commandA실제 데이터 전송이 완료될 때까지 기다립니다 . (데이터 자체는 최대 수백 kb에 불과합니다.)

답변1

이것은 다른 여러 답변과 유사합니다. "moreutils" 패키지가 있는 경우 이 sponge명령이 있어야 합니다. 노력하다

commandA | sponge | { IFS= read -r x; { printf "%s\n" "$x"; cat; } | commandB; }

이 명령은 전체 입력을 읽을 때까지 출력 쓰기를 시작하지 않는다는 점을 제외하면 sponge기본적으로 통과 필터(예: )입니다 . cat즉, 데이터를 "흡수"한 다음 (스펀지처럼) 압착하면 데이터를 방출합니다. 따라서 이는 어떤 면에서 "속임수"입니다. 데이터 볼륨이 크면 sponge임시 파일이 거의 확실히 사용됩니다. 그러나 그것은 당신에게 보이지 않습니다. 고유한 파일 이름을 선택하고 나중에 정리하는 것과 같은 집안일에 대해 걱정할 필요가 없습니다.

{ IFS= read -r x; { printf "%s\n" "$x"; cat; } | commandB; } 출력의 첫 번째 줄을 읽으십시오 sponge. commandA완료될 때까지 표시되지 않습니다 .그 다음에start 를 실행 commandB하고 첫 번째 줄을 파이프에 쓴 다음 호출을 통해 cat나머지 출력을 읽고 파이프에 씁니다.

답변2

commandA파이프라인의 명령은 동시에 시작되며 나중에 사용할 수 있도록 출력을 어딘가에 저장 해야 합니다 . 변수를 사용하면 임시 파일을 피할 수 있습니다.

output=$(command A; echo A)
printf '%s' "${output%%A}" | commandB

답변3

나는 이 문제를 해결할 수 있는 표준 UNIX 유틸리티를 알지 못합니다. 한 가지 옵션은 awk누적된 commandA출력을 사용하여 commandB아래와 같이 한 번에 플러시하는 것입니다.

commandA  | awk '{x = x ORS $0}; END{printf "%s", x | "commandB"}'

awk문자열이 입력에서 작성되므로 많은 메모리를 차지할 수 있습니다 .

답변4

또 다른 옵션은음식물;

| tac | tac

관련 정보