$$가 부모 프로세스와 동일한 ID를 반환하는 이유는 무엇입니까?


160

Bash에 문제가 있으며 이유를 모르겠습니다.
쉘 아래에 다음을 입력합니다.

echo $$    ## print 2433
(echo $$)  ## also print 2433
(./getpid) ## print 2602

"getpid"는 다음과 같이 현재 pid를 얻는 C 프로그램입니다.

   int main() {
    printf("%d", (int)getpid());
    return 0;
   }

나를 혼란스럽게하는 것은 :

  1. "(명령)"은 하위 프로세스라고 생각합니다. (내가 맞습니까?) 부모의 pid와 pid가 달라야한다고 생각하지만, 같은 이유는 무엇입니까?
  2. 내 프로그램을 사용하여 괄호 사이에 pid를 표시하면 표시되는 pid가 다릅니다. 맞습니까?
  3. '$$'는 매크로와 같은 것입니까?

도와주세요?


8
참고 getpid이 서브 쉘에서 실행되지 않은 경우에도 다른 프로세스 ID를 표시합니다.
chepner

1
@Marian이 echo $$ $BASHPID ; ( echo $$ $BASHPID )그 사실을 보여줍니다. 둥근 괄호는 서브 쉘을 작성합니다. 명령문은 변수 값을 변경할 수 있으며 상위 쉘은 해당 변경 사항을 볼 수 없습니다. 이것은 작업으로 구현됩니다 fork().

답변:


223

$$서브 쉘에서 상위 프로세스 ID를 리턴하도록 정의됩니다. "특수 매개 변수"의 맨 페이지에서 :

$ 쉘의 프로세스 ID로 확장됩니다. () 서브 쉘에서는 서브 쉘이 아닌 현재 쉘의 프로세스 ID로 확장됩니다.

에서 bash4, 당신과 함께 아이의 프로세스 ID를 얻을 수 있습니다 BASHPID.

~ $ echo $$
17601
~ $ ( echo $$; echo $BASHPID )
17601
17634

16
"부모"는 약간 오해의 소지가 있지만 (적어도 나에게는 그랬습니다) 실제로 "최상위"셸입니다. 예를 들어 : echo $$; (echo $$; (echo $$))같은 pid를 세 번 에코합니다
Martin Bouladour

1
권리; 나는 값이 (에서 값 상속 부모 쉘에서 상속하고 있다고 말했다해야 부모 등). 최상위 쉘은 쉘이 아닌 상위 프로세스에서 상속하지 않고 처음에 설정합니다.
chepner

$ Expands to the process ID of the shell그것은 tho입니까? echo $리터럴 $를 에코합니다.
Alexander Mills

@AlexanderMills 글쎄요. $단독으로는 매개 변수 확장이 아닙니다. 매뉴얼 페이지는 특수 매개 변수 의 이름 을 나타냅니다 $. $혼자서 확장 한다고 주장하는 것은 아닙니다 .
chepner

좋아 솔직히 무슨 뜻인지 모르겠지만, echo $BASHPID(맥 OS에 있지만 버전 3.2.57) bash는 4, 5 일
알렉산더 밀스

81

다음 중 하나를 사용할 수 있습니다.

  • $! 마지막 백그라운드 프로세스의 PID입니다.
  • kill -0 $PID 여전히 실행 중인지 확인합니다.
  • $$ 현재 쉘의 PID입니다.

2
kill -0 $!백그라운드 프로세스에 대해 이야기하고 있다면 두 번째 글 머리 기호가 아니어야합니까 ? PID기본적으로 아무것도 설정되어 있지 않습니다.
Isaac Freeman

26
  1. 괄호 는 Bash 에서 서브 쉘을 호출합니다 . 그것은 단지 서브 쉘이기 때문에 동일한 PID를 가질 수 있습니다-구현에 달려 있습니다.
  2. 호출하는 C 프로그램은 별도의 프로세스이며 고유 한 PID를 가지고 있습니다. 서브 쉘에 있는지 여부는 중요하지 않습니다.
  3. $$Bash 에서 현재 스크립트 PID 에 대한 별명입니다 . 참조 의 차이 $$$BASHPID여기 , 오른쪽이 위의 추가 변수 $BASH_SUBSHELL중첩 수준이 포함되어 있습니다.

4

시도 getppid()당신이 당신의 쉘의 PID를 인쇄하여 C 프로그램을 원하는 경우.


2

알려진 명령의 PID를 얻는 방법을 묻는다면 다음과 유사합니다.

아래 명령을 발행 한 경우 # 발행 된 명령은 ***

dd if = / dev / diskx of = / dev / disky


그런 다음 다음을 사용합니다.

PIDs=$(ps | grep dd | grep if | cut -b 1-5)

여기서 필요한 것은 필요한 모든 고유 문자를 필드에 파이프하고 해당 필드를 사용하여 에코 할 수 있다는 것입니다.

에코 $ PID


2

올바른 pid를 얻는이 하나의 보편적 인 방법

pid=$(cut -d' ' -f4 < /proc/self/stat)

같은 좋은 하위에 일했다

SUB(){
    pid=$(cut -d' ' -f4 < /proc/self/stat)
    echo "$$ != $pid"
}

echo "pid = $$"

(SUB)

출력 확인

pid = 8099
8099 != 8100

좋은 생각이지만 껍질의 출력을 캡처하기 위해 쉘이 실행 한 포크의 pid를 얻지 못합니까? echo $ (...)를 사용하여 한 번, 두 번 실행하지 않으면 다른 답변을 얻습니다.
Martin Dorey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.