이런 식으로 프로세스의 PID를 시작하려면 어떻게 해야 합니까?

이런 식으로 프로세스의 PID를 시작하려면 어떻게 해야 합니까?
#!/bin/bash

mkfifo /var/run/out
while true
do
    cat /var/run/out | nc -l 8080 > >(
        while read line
        do
            do some stuff
        done
    )
done

nc합계의 pid를 어떻게 얻을 수 있습니까 cat? $!을 사용하면 작동하지 않습니다. pid 파일에 쓰고 싶습니다.

답변1

원하는 것을 수행하는 더 우아한 방법이 있을 수 있지만 다음과 같이 작동합니다.

do
    (cat /var/run/out& echo $! > cat_pid; wait) |
                            (nc -l 8080 <&0 & echo $! > nc_pid; wait) > >(

(가독성을 위해 끝부분을 별도의 줄로 나눴습니다 |.) 작동 방식은 서브셸에서 원하는 PID로 각 명령을 래핑하고, 해당 서브셸에서 비동기적으로 실행하고, 해당 PID를 캡처하고, 명령이 완료될 때까지 기다리는 것입니다. (실제로 이는 명령을 다시 전경으로 가져옵니다.)스콧의 <&0비동기 프로세스가 스크립트에서 올바른 표준 입력을 읽도록 하기 위한 팁입니다.

하지만왜 "고양이"를 사용하나요?? 그리고> >(…)단순 파이프 대신 왜 사용했나요??

이를 다음과 같이 단순화할 수 있습니다.

사실이긴 하지만
하다
    (nc -l 8080 < /var/run/out & echo $! > nc_pid; 대기) |
                행을 읽을 때
                하다
                    뭔가를 해라
                완벽한
완벽한

nc직접 읽도록 하고 /var/run/out프로세스 대체 대신 간단한 파이프를 사용하십시오.

답변2

내가 생각할 수 있는 가장 간단한 방법은 프로세스를 시작하기 전에 pid를 얻는 것입니다.

예를 들어 (Bash에서):

pidfile() { (
    echo $BASHPID > "$1"
    shift
    exec "$@"
) }

mkfifo /var/run/out
while true
do
    pidfile /tmp/cat.pid cat /var/run/out | pidfile /tmp/nc.pid nc -l 8080 > >(
        while read line
        do
            do some stuff
        done
    )
done

pidfile그러면 현재 PID를 지정된 파일에 기록한 다음 나머지 매개변수를 사용하여 실행하는 함수가 생성됩니다 exec. 이렇게 exec하면 방금 파일을 작성한 쉘과 동일한 pid로 명령이 실행됩니다.

서브셸에서 실행되도록 pidfile()전체 함수를 괄호로 묶습니다 . ()파이프라인에 없는 명령을 실행할 때 이는 매우 중요합니다. 예를 들어:

pidfile /tmp/foo some command here

이렇게 하면 pidfile()스크립트의 나머지 부분과 동일한 프로세스에서 실행되므로 호출되면 exec실행 중인 명령이 PID를 인수하고 스크립트는 더 이상 실행되지 않습니다.

또한 위의 내용은 bash용으로 작성되었습니다. $BASHPIDbash 특정 변수입니다. $$이는 서브쉘을 사용할 때 변경되지 않으므로 이 값은 우리가 사용하기에 적합하지 않습니다.

답변3

cat또는 PID를 얻을 수 없습니다.nc 그 스크립트에서너가 아니라면백스테이지 과정그리고 &. 백그라운드에 포함되지 않은 모든 프로세스는 백그라운드에 포함되어야 합니다.마치다스크립트가 계속되기 전에.

이것Bash 위키 프로세스 관리 기사이러한 일을 현명하게 수행하는 방법이 설명되어 있습니다.

관련 정보