Hilfe bei einem Bash skript

OP #7595889
Lesenswert?

Hallo,

ich habe ein skript geschrieben welches ein speziellen prozess beendet allerdings recht kompliziert meiner meinung nach...wie kann ich es verbessern, so das die ausgabe nicht erst in eine datei umgeleitet werden muss

1
#! /bin/bash
2
ps ax | grep 'openvpn --daemon --log /var/log/openvpn.log --config /home/' | grep -v 'grep' | awk '{print $1}' > test.test
3
while read line 
4
do 
5
   echo "$line"
6
   kill $line
7
done < test.test
#7595958
Lesenswert?

Die besseren Befehle wurden ja schon genannt.

Allgemein kannst Du in der Shell die Ausgaben von Befehlen in Variablen schreiben lassen, so sparst Du Dir die temporäre Datei. Das läuft unter dem Stichwort "Command Substitution".

Im Deinem Beispiel hätte man also z.B. sowas machen können:

PIDS=$( ps ax | grep 'openvpn --daemon --log /var/log/openvpn.log --config /home/' | grep -v 'grep' | awk '{print $1}' )

Danach hätte die Variable PID die gefundenen PIDs.

Über diese könntest Du dann iterieren mit:

for PID in $PIDS ; do kill $PID done

Wenn man denn bei dem Konstrukt bleiben möchte, so hätte man es mit awk etwas einfacher bauen können, awk kann alles was Du brauchst.

Mit etwas vereinfachtem Pattern sieht das dann so aus:

PIDS=$( ps ax | awk '/[o]penvpn --daemon/ {print $1}' )

Die [] sorgen dafür, dass der awk Befehl selbst nicht matcht, da [o] im Pattern einem normalen "o" entspricht. Die Aktion in {} gibt die erste Spalte (PID) aus.

#7596020
Lesenswert?

Martin L. schrieb:

ich habe ein skript geschrieben welches ein speziellen prozess beendet allerdings recht kompliziert meiner meinung nach...wie kann ich es verbessern, so das die ausgabe nicht erst in eine datei umgeleitet werden muss

Andere Teilnehmer des Threads haben Dir ja schon IMHO sehr brauchbare Ideen und Anregungen beschrieben. Mein Ratschlag wäre allerdings, Dein OpenVPN mit systemd zu verwalten. Wenn es ein normaler Benutzer starten und stoppen soll, so kann dies über das "NOPASSWD"-Feature von sudo(8) eingerichtet werden.

Viel Spaß und Erfolg! :-)

(Firma: Hobbytheoretiker) #7596027
Lesenswert?

Klaus schrieb:

Die Aufgabe bestand aber nicht darin, es noch komplizierter zu machen.

Der TO wollte keine Pipe über eine Datei als erstes.

Vermeidet eine Variable und zu 90% kann die Befehlssequenz von Markus übernommen werden. Copy Paste, etwas editieren, fertig. Und lernt dabei einen neuen shell Befehl.

Markus M. schrieb:

z.B. sowas machen können:

OP #7596030
Lesenswert?

Hallo vielen Dank fuer Eure Hilfen...

ich habe versucht dasselbe in python zu realisieren und bin soweit gekommen, dass mir die Zeile ausgegeben wird.

1
import subprocess
2
ps = subprocess.Popen(('ps', 'cax'), stdout=subprocess.PIPE)
3
output = ps.communicate()[0]
4
i = 0
5
for line in str(output).split("\\n"):
6
        if 'openvpn' in line:
7
                print(i)
8
                print(str(output).split("\\n")[i])
9
        i += 1

Ergebnis

1
   7836 ?        Ss     0:00 openvpn

wie kann ich nun diese Zeile in python spliten, so dass ich am ende auf die PID 7836 komme?

Danke fuer die Hilfe

#7596118
Lesenswert?

Alexander schrieb:

Ich würde versuchen ein Shell Skript so zu schreiben dass es auch auf Systemen läuft wo weder Bash, Awk noch Python vorhanden ist.

sh only (außer ps und kill):

1
#!/bin/sh
2
ps axww | while read pid tty stat time cmd; do
3
    case "$cmd" in
4
        "openvpn --daemon"*) echo kill "$pid";;
5
    esac
6
done

Das "read"-Kommando, insb in Kombination mit "while", wird mMn viel zu selten benutzt. Ebenso "case" für's Pattern/String-matching. So eine Schleife in sh ist nicht allzu schnell (deswegen wurde ja awk entwickelt), in solch einem Fall aber akzeptabel. Der Kompatibilität abträglich ist der ps, der dummerweise ziemlich systemspezifisch ist. Da könnte man auf die Idee kommen, direkt /proc/<pid>/cmdline zu benutzen - es wird dadurch aber eher schlimmer.

PS: Eh, zum "scharfmachen" das "echo" entfernen.

Gast #7596203
Lesenswert?

Alexander schrieb:

ist auf jeden Fall leserlich und leicht auf das jeweilige ps zu adaptieren

Das ps macht mehr Ärger als es auf den ersten Blick aussieht, vor allem ist es völlig überflüssig. Dazu der Subprozess durch die pipe, auch immer ein lustiger Quell an dubiosem Verhalten wenn man nicht weiss was man da eigentlich macht und so ein Script später erweitert. So einen Schrott musste ich jahrelang von Kollegen geradebiegen. Das ganze Ding lässt sich auf einen Einzeiler eindampfen wenn man pgrep verwendet.

(Firma: Hobbytheoretiker) #7596223
Lesenswert?

Franko S. schrieb:

Das ganze Ding lässt sich auf einen Einzeiler eindampfen wenn man pgrep verwendet.

Das von Dir ist natuerlich kuerzer, von Klaus auch.

Franko S. schrieb:

ein lustiger Quell an dubiosem Verhalten

Wegen moeglicher Fehler verwende ich manchmal den Befehl eval um vorher den zusammengesetzten Befehl am Bildschirm ausgeben zu lassen.

#7596749
Lesenswert?

Martin L. schrieb:

ich habe versucht dasselbe in python zu realisieren und bin soweit gekommen, dass mir die Zeile ausgegeben wird.

Pythons "psutil" installieren (virtualenv oder Systempaket), dann:

1
#!/usr/bin/env python
2
import psutil
3

4
def main():
5
    for proc in psutil.process_iter():
6
        if 'openvpn' in proc.name():
7
            proc.kill()
8

9
if __name__ == '__main__':
10
    main()

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren