• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Identifizieren und killen eines Prozesses anhand Startparam.

Hi, ich bin neu hier und hoffe, dass ich im richtigen Forum gelandet bin.
Es geht hier um ein script (.sh), welches ich benutze um einen gameserver (cod4) zu beenden. Der root gehört einem Kumpel und läuft auf Debian/linux. Ich habe leider noch nicht so viel Ahnung/Erfahrung mit Linux und Shellscripten (kann nur ein bisschen perl).

Das Problem:
Auf dem root laufen mehrere gameserver, die per script gestartet und gestoppt werden. Das stoppen geht etwas rabiat mit:
Code:
killall cod4_lnxded-bin > /dev/null 2>&1
Das script beendet aber logischerweise alle cod4 server, da es alle Prozesse cod4_lnxded-bin killt.

ps aux liefert:

Code:
                      TIME  COMMAND
25130 ?        S     14:28 ./cod4_lnxded-bin +set loc_language 2 +set net_ip XXXXX.XXX.XX +set net_port 28400 +seta ui_maxclients 20...
25139 ?        S     14:25 ./cod4_lnxded-bin +set loc_language 2 +set net_ip XXXXX.XXX.XX +set net_port 29960 +seta ui_maxclients 20...

Wie schaffe ich es, dass ich nur den Prozess kille, der mit dem COMMAND ./cod4_lnxded-bin +set loc_language 2 +set net_ip XXXXX.XXX.XX +set net_port 28400 aufgerufen wurde (sprich nur den Server mit einem bestimmten Port)?

Geht das nur über das Herausfiltern per grep? (kann ich leider noch nicht :???: )

Oder gibt es einen Parameter für kill, der auf COMMAND abzielt (kill -c?)?

mfg Markus
 

K4m1K4tz3

Advanced Hacker
Du könntest deine ps ausgabe mit grep filtern und mit awk die Spalte zeigen lassen, in der die pid steht. Diese kannst du dann kill übergeben.

Z.B. so:
Code:
ps ax | grep cod4_lnxded-bin | grep 28400 | awk '{print $1}'
 
OP
M

markus.obi

Newbie
Danke für die schnellen Anworten.
Ich hab da noch ein paar Fragen dazu:

1.
ps ax | grep cod4_lnxded-bin | grep 28400 | awk '{print $1}'

Wie kann ich die Variable $1 NUR an eine andere Variable weiterleiten? (anstatt sie zu printen, awk '{(PID=$1}' klappt nicht)
Ich weiß leider nicht wie ich die "print $1" Textausgabe weiterverwerten oder verbergen kann.

2.
Was passiert bei den beiden Vorschlägen, wenn der Befehl doppelt ausgeführt wird?
Also kein passender Eintrag gefunden wird. Dann wird doch z.B.
Code:
kill $PID
ausgeführt, wobei $PID leer oder nicht definiert ist.
Wird dann eventuell ein anderer Prozss gekillt?

3.
Code:
kill `ps -C cod4_lnxded-bin | grep 28880 | cut -d " " -f2`
liefert
Code:
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

der Prozess läuft weiter

€: Ich sehe grad, dass ich bei meinem testscript das #!/bin/bash vergessen habe (#!/bin/bash ist im serverrestart script drin) macht das nen unterschied?
€³: mit #!/bin/bash gehts auch net
 

K4m1K4tz3

Advanced Hacker
markus.obi schrieb:
1.
ps ax | grep cod4_lnxded-bin | grep 28400 | awk '{print $1}'

Wie kann ich die Variable $1 NUR an eine andere Variable weiterleiten? (anstatt sie zu printen, awk '{(PID=$1}' klappt nicht)
Ich weiß leider nicht wie ich die "print $1" Textausgabe weiterverwerten oder verbergen kann.

Ich interpretiere deine Frage so, dass du gerne die pid in einer Variablen speichern möchtest. Das kannst du so machen:
Code:
codpid=$(ps ax | grep cod4_lnxded-bin | grep 28400 | awk '{print $1}')

markus.obi schrieb:
2.
Was passiert bei den beiden Vorschlägen, wenn der Befehl doppelt ausgeführt wird?
Also kein passender Eintrag gefunden wird. Dann wird doch z.B.
Code:
kill $PID
ausgeführt, wobei $PID leer oder nicht definiert ist.
Wird dann eventuell ein anderer Prozss gekillt?

Wie lOtz1009 schon geschrieben hat: Nein. Es wird eine Fehlermeldung geben. Am besten wäre, wenn du vorher prüfen würdest, ob die Variable (hier codpid) leer ist oder nicht. Evtl. auch noch ob sie numerisch ist.

markus.obi schrieb:
€: Ich sehe grad, dass ich bei meinem testscript das #!/bin/bash vergessen habe (#!/bin/bash ist im serverrestart script drin) macht das nen unterschied?

Ja. Linux muss wissen mit was für einer Shell er das Script interpretieren muss.
 
OP
M

markus.obi

Newbie
Danke für die Tipps und Special Thanks an K4m1K4tz3!
kiss.gif


Die Lösung von lOtz1009 kann leider nicht funktionieren, da je nach Stellen der ProzessID unterschiedlich viele Leerzeichen am Anfang stehen. (nach langem probieren rausgefunden)

Die Lösung von K4m1K4tz3 funzt einwandfrei - die Spaltenauswahlfunktion mit awk ist genial (Leider hab ich kein plan von AWK, ich hatte am Anfang ja nicht mal einen Schimmer von BASH).
Trotzdem danke an alle, habe viel dazu gelernt, z.B. was ein pipe ist :D .




Für die Nachwelt:
Nach einigem rumprobieren hab ichs hinbekommen, dass er sogar nur dann die PID killt, wenn eine gefunden wurde und falls mehrere PIDs gefunden wurden, werden alle gekillt.
Passiert schon mal, dass ein server 2 mal gestartet wird, wenn 3 Leute dran rumfummeln.

Code:
#!/bin/bash

SRVNAME="Test"
PARAMETERS="+set loc_language 2 +set net_ip XX.XXX.XXX.XX +set net_port XXXXX +seta ui_maxclients 20 +set dedicated 2 +set sv_punkbuster 1 +set fs_game mods/promodlive210 +exec ssvpubserver.cfg +map_rotate"

while [ -n "$(ps ax | grep cod4_lnxded-bin | grep -m 1 "$PARAMETERS" | awk '{print $1}')" ];
do
echo "Server \"$SRVNAME\" mit ProzessID \"$(ps ax | grep cod4_lnxded-bin | grep -m 1 "$PARAMETERS" | awk '{print $1}')\" wird gekillt"
kill $(ps ax | grep cod4_lnxded-bin | grep -m 1 "$PARAMETERS" | awk '{print $1}')
done





ansonsten kann hier ZU (falls ihr die threads closed)
 

K4m1K4tz3

Advanced Hacker
Etwas Schönheitchirurgie:

Ich würde die PID in eine Variable speichern und dann jeweils nur diese Variable in der Schleife, bei echo und bei kill abrufen. Das sollte den Code leserlicher machen.

Außerdem würde ich schon beim Aufrufen des Servers überprüfen, ob einer mit den gleichen Einstellungen läuft. So würde es garnicht erst zu einem Chaos kommen.
 
Oben