Вы можете использовать sh -cи, execчтобы получить PID команды еще до ее запуска.
Для начала myCommand, чтобы его PID печатался до его запуска, вы можете использовать:
sh -c 'echo $$; exec myCommand'
Как это устроено:
Это запустит новую оболочку, напечатает PID этой оболочки, а затем использует execвстроенную функцию для замены оболочки вашей командой, убедившись, что она имеет тот же PID. Когда ваша оболочка запускает команду со execвстроенной функцией, ваша оболочка фактически становится этой командой , а не более распространенным поведением создания новой собственной копии, которая имеет свой собственный отдельный PID и которая затем становится командой.
Я считаю, что это намного проще, чем альтернативы, включающие асинхронное выполнение (с &), управление заданиями или поиск с помощью ps. Эти подходы хороши, но если у вас нет конкретной причины их использовать - например, возможно, команда уже запущена, и в этом случае поиск ее PID или использование управления заданиями имеет смысл - я предлагаю сначала рассмотреть этот способ. (И я бы, конечно, не подумал о написании сложного сценария или другой программы для достижения этой цели).
Этот ответ включает в себя пример этой техники.
Части этой команды иногда могут быть опущены, но не всегда.
Даже если используемая вами оболочка выполнена в стиле Борна и, следовательно, поддерживает execвстроенную функцию с этой семантикой, вам, как правило, не следует пытаться избегать использования sh -c(или его эквивалента) для создания нового отдельного процесса оболочки для этой цели, поскольку:
- Как только оболочка стала
myCommand, нет оболочки, ожидающей запуска следующих команд. sh -c 'echo $$; exec myCommand; fooне сможет попытаться запустить fooпосле замены себя myCommand. Если вы не пишете скрипт, который запускает это как последнюю команду, вы не можете просто использовать echo $$; exec myCommandв оболочке, где вы выполняете другие команды.
- Вы не можете использовать подоболочку для этого.
(echo $$; exec myCommand)может быть синтаксически лучше, чем sh -c 'echo $$; exec myCommand', но когда вы запускаете $$внутри ( ), он дает PID родительской оболочки, а не самой подоболочки. Но PID подоболочки будет PID новой команды. Некоторые оболочки предоставляют свои собственные непереносимые механизмы для нахождения PID подоболочки, которые вы можете использовать для этого. В частности, в Bash 4 , (echo $BASHPID; exec myCommand)работает.
Наконец, обратите внимание, что некоторые оболочки выполняют оптимизацию, когда они запускают команду, как если бы exec(то есть сначала отказываются от разветвления), когда известно, что оболочке не нужно будет ничего делать позже. Некоторые оболочки пытаются сделать это в любое время, когда выполняется последняя команда, в то время как другие будут делать это только тогда, когда нет других команд до или после команды, а другие вообще не будут делать это. В результате, если вы забудете написать execи просто использовать, sh -c 'echo $$; myCommand'это иногда даст вам правильный PID в некоторых системах с некоторыми оболочками. Я рекомендую никогда не полагаться на такое поведение , а вместо этого всегда включать, execкогда это то, что вам нужно.