Je to na Linuxu?
Ve skutečnosti existuje několik jemně odlišných verzí názvu příkazu, které používá ps
, killall
, atd.
Dvě hlavní varianty jsou:1) dlouhý název příkazu, který získáte, když spustíte ps u
; a 2) krátký název příkazu, který získáte, když spustíte ps
bez jakýchkoli příznaků.
Pravděpodobně největší rozdíl nastane, pokud je vaším programem shell skript nebo cokoli, co vyžaduje interpret, např. Python, Java atd.
Zde je opravdu triviální skript, který demonstruje rozdíl. Nazval jsem to mycat
:
#!/bin/sh
cat
Po spuštění jsou zde dva různé typy ps
.
Za prvé, bez u
:
$ ps -p 5290
PID TTY ... CMD
5290 pts/6 ... mycat
Za druhé, s u
:
$ ps u 5290
USER PID ... COMMAND
mikel 5290 ... /bin/sh /home/mikel/bin/mycat
Všimněte si, jak druhá verze začíná /bin/sh
?
Nyní, pokud mohu říci, killall
ve skutečnosti čte /proc/<pid>/stat
a vezme si druhé slovo mezi závorkami jako název příkazu, takže to je opravdu to, co musíte zadat, když spustíte killall
. Logicky by to mělo být stejné jako ps
bez u
flag říká, ale bylo by dobré to zkontrolovat.
Co je třeba zkontrolovat:
- co znamená
cat /proc/<pid>/stat
řekněme, že název příkazu je? - co znamená
ps -e | grep db2
řekněme, že název příkazu je? - proveďte
ps -e | grep db2
aps au | grep db2
zobrazit stejný název příkazu?
Poznámky
Pokud používáte i jiné příznaky ps, může být jednodušší použít ps -o comm
zobrazí se krátký název a ps -o cmd
abyste viděli dlouhý název.
Můžete také najít pkill
lepší alternativa. Konkrétně pkill -f
pokusí se o shodu pomocí úplného názvu příkazu, tj. názvu příkazu vytištěného pomocí ps u
nebo ps -o cmd
.
killall se pokouší porovnat název procesu (ale ve skutečnosti není tak dobrý v odpovídající části).
A protože "ps | grep" a "ps | grep | kill" odvádí mnohem lepší práci, někdo to zjednodušil a vytvořil pgrep a pkill. Přečtěte si, že příkazy jako "ps grep" a "ps kill", protože tento příkaz nejprve ps, pak grep a pokud chcete, zabije.
Měl jsem podobný problém, ale /proc/<pid>/stat
obsahoval očekávaný řetězec. Pomocí strace jsem viděl, že killall také přistupoval na /proc/<pid>/cmdline
.
Pokračoval jsem ve vyšetřování pomocí gdb, abych zjistil, že v mém případě selhalo při kontrole mého příkazu na úplný příkaz včetně všech argumentů nalezených v /proc/<pid>/cmdline
. Zdálo se, že se cesta kódu spustila kvůli názvu souboru delšímu než 15 znaků (což je pevně zakódovaná hodnota ve zdroji killall). Plně jsem nezkoumal, jestli bych to mohl nějak dostat do práce s killall.
Ale jak bylo zmíněno v jiných komentářích zde, pkill je lepší alternativa, která nemá stejné problémy.
Zdrojový kód pkill
pro zájemce lze nalézt zde https://github.com/acg/psmisc.