
스크립트 조각이 있습니다.
MyCoolCommand 2>&1 | tail -n 256 > "report.out" &
cool_pid=$! # FIXME
버그가 있습니다. cool_pid
PID는 입니다 tail
. 파이프라인이 백그라운드에서 실행 중입니다. cool_pid
의 PID 에 저장하는 방법은 무엇입니까 MyCoolCommand
? 쉘은 /bin/sh입니다. 기존의 일반 /bin/sh로는 불가능하다면, 이를 달성할 수 있는 방법이 있다면 Bash로 전환할 준비가 되어 있습니다.
답변1
Bash에서는 프로세스 대체를 사용할 수 있습니다.
MyCoolCommand > >(tail -n 256 > report.out) 2>&1 &
cool_pid=$!
데이터는 원래 명령에서 같은 방향으로 흐르지만 MyCoolCommand
원하는 대로 될 것입니다.tail
$!
노트:
2>&1
이후에해야합니다>
.- 쉘은 종료 직후 작업이 완료된 것으로 간주
MyCoolCommand
하지만tail
아직 실행 중일 수도 있습니다..wait
작업에 대한 어느 시점에서 스크립트가report.out
추가로 처리되는 경우 파일이 아직 준비되지 않았을 수 있다는 점에 유의하세요. 비교를 위해: 귀하의MyCoolCommand | tail … &
작업은 다음 이후에 완료된 것으로 간주됩니다.둘 다프로세스가 종료됩니다.
plain 으로 문제를 해결할 수 있지만 sh
이를 위해서는 수동 배관이 필요합니다.
mkfifo myfifo
<myfifo tail -n 256 >report.out &
MyCoolCommand >myfifo 2>&1 &
cool_pid=$!
rm myfifo
노트:
아직 사용 중일 때 FIFO를 제거하는 것이 안전합니다. 디렉토리에서 연결이 해제되었음에도 불구하고 프로그램은 이를 계속 사용합니다. OS는 fifo가 더 이상 사용되지 않을 때만 실제로 fifo를 파괴합니다. 이름이 지정된 새 파일
myfifo
(만약 생성된 경우)은 이전 파일이 아직 사용 중이더라도 이전 파일(이름 제외)과 아무 관련이 없습니다.이름이 지정된 파일이
myfifo
이미 현재 작업 디렉토리에 있고(스크립트의 다른 인스턴스가 병렬로 실행되거나 어떤 이유로든) 사용 중인 경우 스크립트가 오작동할 수 있습니다. 올바른 방법은 임시 디렉터리를 만들고mktemp -d
거기에 fifo를 배치하는 것입니다.mktemp
휴대용이 아닙니다.이 방법을 사용하면 PID를 저장할 수 있습니다.
MyCoolCommand
그리고독립적으로tail
.