2014-01-11 3 views
72

У меня проблема с Bash, и я не знаю почему.
Под оболочкой, я ввожу:получить pid в shell (bash)

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

"GETPID" представляет собой программу C, чтобы получить текущий идентификатор процесса, как:

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

Что меня смущает, что:

  1. Я думаю, что «(команда)» является подпроцессом (я прав?), И я думаю, что его pid должен отличаться своим parent pid, но они одинаковы, почему ...
  2. Когда я использую свою программу для отображения pid между круглыми скобками, pid, который он показывает, отличается, правильно?
  3. «$$» что-то вроде макроса?

Помогите мне?

+5

Обратите внимание, что 'getpid' будет показывать другой идентификатор процесса, даже если он не был запущен в подоболочке. – chepner

+0

Независимо от других объяснений, относящихся к странице руководства bash и т. Д. Я бы поспорил, что '(xx)' фактически не вызывает отдельный процесс Linux (ни поток). Они были бы глупы, чтобы реализовать его таким неэффективным способом. – Marian

ответ

102

$$ предназначен для возврата идентификатора процесса родительского элемента в подоболочку; от страницы руководства в разделе «Специальные параметры»:

$ Расширяет идентификатор процесса оболочки. В() подоболочке она расширяется до идентификатора процесса текущей оболочки, а не подоболочки.

В bash 4 вы можете получить идентификатор процесса ребенка с BASHPID.

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

«parent» немного вводит в заблуждение (по крайней мере, это было для меня), это на самом деле оболочка «верхнего уровня». Например: 'echo $$; (echo $$; (echo $$)) 'повторяет один и тот же pid три раза –

+0

Вправо; Я должен был сказать, что значение наследуется от родительской оболочки (которая унаследовала его значение от * своего родителя и т. Д.). Оболочка верхнего уровня сначала устанавливает ее, а не наследует от родительского процесса (без оболочки). – chepner

15
  1. Скобки ссылаются на subshell in Bash. Поскольку это только подоболочка, она может иметь один и тот же PID - зависит от реализации.
  2. Программа C, которую вы вызываете, представляет собой отдельный процесс, который имеет свой собственный уникальный PID - не имеет значения, находится ли он в подоболочке или нет.
  3. $$ - это псевдоним в Bash до the current script PID. См. differences between $$ and $BASHPID here, а справа - дополнительную переменную $BASH_SUBSHELL, которая содержит уровень вложенности.
3

Попробуйте getppid(), если вы хотите, чтобы ваша программа C печатала PID вашей раковины.

46

Вы можете использовать один из следующих вариантов.

  • $! является ПИД-регулятором последнего процесса.
  • kill -0 $PID проверяет, все еще работает.
  • $$ - ПИД-код текущей оболочки.