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