Назад | Перейти на главную страницу

В чем разница между $$ и $! при использовании / bin / bash -c

Я пытаюсь понять "единственную строчку" в этот комментарий автор @sysfault:

/bin/sh -c 'echo $$>/tmp/my.pid && exec program args' &

Я пробовал следующие варианты ...

Разные $$ внутри и снаружи:

/bin/bash -c 'echo $$ && exec sleep 5' ; echo $$
14408
29700

Тот же идентификатор (но в фоновом режиме):

$ /bin/bash -c 'echo $$ && exec sleep 5' & echo $! 
[1] 8309
8309
$ 8309

[ 1 ]+  Done  /bin/bash -c 'echo $$ && exec sleep 5'

Другой pid для $$ & $! :

/bin/bash -c 'echo $$ && exec sleep 5 & echo $!'                                 
6504
6503

Убить не удалось: / bin / bash -c 'echo $$ && (sleep 15; echo done)'
19063 Убил $ done (после убийства появилось эхо)

Тот же pid с доступом к pid процесса переднего плана:

$ /bin/bash -c 'echo > tmp.pid ; sleep 10 ; echo $$ ; echo done ; echo $$;'      
28415 (instantly)
28415 (10 seconds later)
done
28415
$ cat tmp.pid 
28415

С помощью этой команды я смог убить pid в другом окне до завершения сна, предотвратив появление последних трех эхо:

$ /bin/bash -c 'echo $$ ; sleep 30 ; echo $$ ; echo done ; echo $$;'               
23236
Killed

Контекст: в конечном итоге я хочу запустить процессы bash через php exec () и дождаться результата, прежде чем продолжить и сохраните pid, чтобы я мог очистить его в случае нажатия кнопки ручной отмены. Я буду иметь дело с двумя дорогостоящими процессами: одним rsync и одним git commit & push.

Каков наилучший способ надежно получить pid сценария bash переднего плана, который включает несколько команд (с;> | или &&)?

$$ это PID текущая оболочка. Когда вы используете $$ в bash -c тело скрипта, вы получите идентификатор Эта порожденная оболочка

$ echo $$; bash -c 'echo $$'; echo $$
6872
6987
6872

$! это PID последний фоновый процесс

$ sleep 5 & echo $!; sleep 5 & echo $!; echo ===; pgrep -l sleep
[1] 7118
7118
[2] 7119
7119
===
7118 sleep
7119 sleep

Когда ты делаешь bash -c 'echo $$' & echo $!, вы получите один и тот же идентификатор pid дважды, потому что для вашей текущей оболочки $! - это pid фонового процесса bash, а внутри тела скрипта $$ - текущий pid того же фонового процесса bash.

Когда ты делаешь /bin/bash -c 'echo $$ && exec sleep 5 & echo $!', вы получите два разных идентификатора pid: $$ - идентификатор процесса bash и $! это идентификатор процесса сна.

  • Мне это кажется странным, потому что вы используете exec поэтому это должен быть тот же PID (процесс сна, заменяющий процесс bash)
  • Однако вы используете exec ... & поэтому bash должен сначала создать вилку подоболочка для запуска фоновой задачи, а затем exec заменяет эта подоболочка со сном.

На ваш актуальный вопрос лучше всего ответит специалист по php, а я нет. Вы должны передать этот вопрос модератору и попросить переместить его в Stack Overflow, где обязательно будет тусоваться больше php-людей.