이전 PID입니다. 백그라운드 파이프라인의 명령

이전 PID입니다. 백그라운드 파이프라인의 명령

스크립트 조각이 있습니다.

MyCoolCommand 2>&1 | tail -n 256 > "report.out" &
cool_pid=$!  # FIXME

버그가 있습니다. cool_pidPID는 입니다 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.

관련 정보