GNU/Linux >> Znalost Linux >  >> Linux

Jak získat PID právě zahájeného procesu

Řešení 1:

Co může být jednodušší než echo $! ? Jako jeden řádek:

myCommand & echo $!

Řešení 2:

Můžete použít sh -c a exec získat PID příkazu ještě před běží.

Chcete-li spustit myCommand , takže jeho PID bude vytištěno před spuštěním, můžete použít:

sh -c 'echo $$; exec myCommand'

Jak to funguje:

Tím se spustí nový shell, vypíše se PID tohoto shellu a pak se použije exec vestavěný k nahrazení shell s vaším příkazem a ujistěte se, že má stejné PID. Když váš shell spustí příkaz s exec vestavěný, váš shell se ve skutečnosti stává tento příkaz, spíše než běžnější chování při vytváření nové kopie sebe sama, která má své vlastní samostatné PID a která se pak stává příkazem.

Považuji to za mnohem jednodušší než alternativy zahrnující asynchronní provádění (s & ), ovládání úlohy nebo vyhledávání pomocí ps . Tyto přístupy jsou v pořádku, ale pokud nemáte konkrétní důvod je použít – například, možná, že příkaz již běží, v takovém případě by hledání jeho PID nebo použití řízení úlohy dávalo smysl – navrhuji nejprve zvážit tento způsob. (A určitě bych neuvažoval o psaní složitého skriptu nebo jiného programu, abych toho dosáhl).

Tato odpověď obsahuje příklad této techniky.

Části tohoto příkazu mohou být občas vynechány, ale ne obvykle.

I když shell, který používáte, je Bourneův styl, a proto podporuje exec Díky této sémantice byste se obecně neměli snažit vyhýbat použití sh -c (nebo ekvivalentní) k vytvoření nového, samostatného shell pro tento účel, protože:

  • Jakmile se shell stane myCommand , žádný shell nečeká na spuštění následujících příkazů. sh -c 'echo $$; exec myCommand; foo by se nemohl pokusit spustit foo poté, co sám sebe nahradí myCommand . Pokud nepíšete skript, který toto spouští jako poslední příkaz, nemůžete jednoduše použít echo $$; exec myCommand v shellu, kde spouštíte další příkazy.
  • Nemůžete k tomu použít subshell. (echo $$; exec myCommand) může být syntakticky hezčí než sh -c 'echo $$; exec myCommand' , ale když spustíte $$ uvnitř ( ) , udává PID nadřazeného shellu, nikoli samotného podshellu. Ale je to PID podshell, který bude PID nového příkazu. Některé shelly poskytují své vlastní nepřenosné mechanismy pro nalezení PID podshell, které byste mohli použít k tomu. Konkrétně v Bash 4, (echo $BASHPID; exec myCommand) funguje.

Nakonec si všimněte, že některé shelly provedou optimalizaci, kde spustí příkaz jakoby pomocí exec (tj. nejprve se vzdají rozvětvení), když je známo, že skořápka nebude muset poté nic dělat. Některé shelly se o to pokoušejí, kdykoli je to poslední příkaz, který se má spustit, zatímco jiné to udělají pouze tehdy, když před nebo za příkazem nejsou žádné další příkazy, a jiné to neudělají vůbec. Výsledkem je, že pokud zapomenete napsat exec a stačí použít sh -c 'echo $$; myCommand' pak to bude někdy u některých vám poskytne správné PID systémy s některými skořápky. Nedoporučuji nikdy spoléhat na takové chování a místo toho vždy zahrnout exec když to potřebujete.

Řešení 3:

Zabalte příkaz do malého skriptu

#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file

Řešení 4:

Neznám žádné jednodušší řešení, ale nepoužívám $! dostatečně dobrý? Hodnotu můžete vždy přiřadit nějaké jiné proměnné, pokud ji později budete potřebovat, jak řekli ostatní.

Jako vedlejší poznámku, místo potrubí z ps můžete použít pgrep nebo pidof .

Řešení 5:

použijte exec ze skriptu bash po registraci pid do souboru:

příklad:

předpokládejme, že máte skript s názvem „forever.sh“, který chcete spustit s args p1,p2,p3

zdrojový kód forever.sh:

#!/bin/sh

while [ 1 -lt 2 ] ; do
    logger "$0 running with parameters \"[email protected]\""
    sleep 5
done

vytvořit reaper.sh:

#!/bin/sh

echo $$ > /var/run/$1.pid
exec "[email protected]"

spustit forever.sh přes reaper.sh:

./reaper.sh ./forever.sh p1 p2 p3 p4 &

forever.sh nedělá nic jiného, ​​než že každých 5 sekund zaznamená řádek do syslog

nyní máte pid v /var/run/forever.sh.pid

cat /var/run/forever.sh.pid 
5780

a forever.sh běží dobře. syslog grep:

Nov 24 16:07:17 pinkpony cia: ./forever.sh running with parameters "p1 p2 p3 p4"

můžete to vidět v tabulce procesů:

ps axuwww|grep 'forever.sh p1' |grep -v grep
root      5780  0.0  0.0   4148   624 pts/7    S    16:07   0:00 /bin/sh ./forever.sh p1 p2 p3 p4

Linux
  1. Programově získat nadřazené pid jiného procesu?

  2. Jak získat ID procesu pro ukončení procesu nohup?

  3. Jak získat PID z rozvětveného podřízeného procesu ve skriptu shellu

  1. Jak identifikovat proces, který nemá PID?

  2. Jak začít s Juju?

  3. Jak získat pid procesu a vyvolat na něj kill -9 ve skriptu shellu?

  1. Jak začít s cloudovým serverem FreeBSD

  2. Jak najdu ID procesu v Ubuntu?

  3. Jak získám cestu k procesu v Unixu / Linuxu