BASH: Befehlsausgabe in Vektor bekommen, wie?

  • Hallo zusammen,


    hab da ein kleines BASH Problemchen:


    Ich will die mehrzeilige Ausgabe aus einem Befehl z.B. ps -lC nameAnwendung in einen Vektor bekommen. Dann will ich mit einer for Schleife für jede Zeile eine andere Aktion starten:


    Also so gehts noch NICHT:


    Code
    pids[ ]=`ps -lC $pfad`  
    for pid in $pids[@]  
           echo $pid  
    done


    Ach ja und die erste Zeile, also das erste Vektor-Element sollte noch weggeworfen werden, bzw. nicht abgearbeitet werden.


    Wer hat Tips?


    Danke


    Gruß
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

    Einmal editiert, zuletzt von Fux ()

  • Was spricht gegen

    Code
    for pid in $(ps -lC $pfad); do
           echo $pid  
    done

    ?

    Godzilla [Low Budget Record-Only]: AMD K6/2(400), Gigabyte GA-5AX, 192MB, ATI RagePro (Mach64GT) mit TV-Out, Technisat Skystar2 rev 2.6b, IBM DTLA 40GB, Ensoniq ESS-Solo1 (es1935), Pioneer DVR 108

  • Hallo,


    weil dann in pid alle durch Leerzeichen getrennten Tokens einzeln reinkommen. Besser ist


    Code
    ps -lC $pfad | while read pid ; do
        echo $pid
    done


    Gruß,
    Armin

    VDR
    ASUS A7N8X-X, AMD 2600+, 2 GB, 320 GB HD, Hauppauge DVB-S 1.3, Hauppauge Nova-S-Plus, Funktastatur
    Debian 4.0/Etch-Kernel 2.6.18-5-486
    c't-VDR 6.1 mit e-tobi 1.6.0 (neu gepatched ohne sortrecordings), acpi, vdradmin-am, burn, osdteletext, ffnetdev, audiorecorder, infosatepg, ...
    Client
    dbox2 (Sagem 2xI_C) mit Neutrino-Derivat

  • Bei dem Skript von metahawk wird nach Leerzeichen getrennt wie von Armin gesagt. Das andere von Armin funktioniert. Mein Fehler lag ferner darin, daß ich immer den ganzen Pfad zum Programm angegeben hab. Wenn ich nur noch den Anwendungsnamen angebe dann gehts einwandfrei.


    Hier noch das fertige Skript:


    Was mir nicht ganz klar ist warum bekomme ich die Ausgabe:
    kill PID 1234 1235 1236
    und nicht
    kill PID 1234
    kill PID 1235
    kill PID 1236


    Gruß
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

  • Wenn du das erreichen willst, warum nimmst du dann nicht einfach pkill?



    pkill $NAME


    und fertig.


    Oder wenn du magst auch auch die böse Art: pkill -9 $NAME

  • Jetzt bin ichs nochmal ;)
    Will eine Java Anwendung killen. Weil ich mehrere Java-Anwendungen laufen hab, kann ich nicht einfach alles killen.


    Die Java Anwendung wird duch ein Runtime Skript geöffnet und wird dadurch identifizierbar:


    server:/daten # pstree -p | grep S20pim
    |-S20pim(1465)---su(1469)---bash(1476)---bash(1520)---java(1527)---java(1545)-+-java(1547)


    Jetzt wollte ich eben die PIDs daraus extrahieren, kriegs aber nicht hin :(
    Hier mein Ansatz:

    Code
    server:/daten # pstree -p | grep S20pim | sed -e 's|.*\([0-9]{4,5}\).*| \1 |'
    Resultat:
            |-S20pim(1465)---su(1469)---bash(1476)---bash(1520)---java(1527)---java(1545)-+-java(1547)


    Folgendes brachte zumindest schon mal den letzten PID zurück:

    Code
    pstree -p | grep S20pim | perl -p -e 's|.*([0-9]{4,5}).*|\1 |'
    Resultat: 1547


    Nur wie krieg ich alle schön nacheinander? Bzw. das muß doch mit sed auch gehen und ohne Perl.


    EDIT:
    So, hab ichs doch noch geschafft zumindest die erste Zahl zu extrahieren:

    Code
    pstree -p | grep S20pim | sed -e 's|.*\([[:digit:]]\{4,5\}\).*|\1|'


    Bleibt immer noch die Frage wie ich die anderen kriege?


    Gruß
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

    Einmal editiert, zuletzt von Fux ()

  • Mit awk:

    Code
    pstree -p |awk -F"(" '/S20pim/ {for (i=2;i<=NF;i++)print $i + 0}'


    Mit perl:

    Code
    pstree -p |perl -F'\(' -ane 'if(/S20pim/){for ($i=1; $i<=$#F;$i++){print $F[$i] + 0,"\n"}}'


    Beide arbeiten nach dem gleichen Prinzip:
    1. Es werden nur die Zeilen bearbeitet, die S20pim enthalten.
    2. Diese Zeile wird an der öffnenden runden Klammer aufgebrochen.
    3. Der erste Teil wird überlesen.
    3. Durch Addition von 0 zu jedem weiteren Teil wird nur der Zahlwert verarbeitet und danach ausgegeben.


    Bis demnächst,
    Armin

    VDR
    ASUS A7N8X-X, AMD 2600+, 2 GB, 320 GB HD, Hauppauge DVB-S 1.3, Hauppauge Nova-S-Plus, Funktastatur
    Debian 4.0/Etch-Kernel 2.6.18-5-486
    c't-VDR 6.1 mit e-tobi 1.6.0 (neu gepatched ohne sortrecordings), acpi, vdradmin-am, burn, osdteletext, ffnetdev, audiorecorder, infosatepg, ...
    Client
    dbox2 (Sagem 2xI_C) mit Neutrino-Derivat

  • Ohh,
    Das mit der Variable i ist mir nicht ganz klar, die geht ja quasi immer von "(" zu "(" oder? Wieso hat sie als Inhalt plötzlich den Text, das ist ja dann quasi ein Zeiger der inkrementiert wird, oder?
    Und das +0 ist ein Trick um alle Buchstaben rauszukicken?


    Danke Dir!


    Grüße
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

  • Zitat

    Original von Fux

    Code
    pids[ ]=`ps -lC $pfad`  
    for pid in $pids[@]  
           echo $pid  
    done


    Wer hat Tips?


    Mit einer echten bash als bash aufgerufen eventuell so:


    Code
    declare -i n=0
    while read F S U P PP C PRI NI ADDR SZ WCHAN TTY TIME CMD; do
        test $((n++)) -eq 0 && continue
        echo $P
    done <  <(ps -lC buffer)


    Wobei PID durch P und PPID durch PP ersetzt wurden, weil
    das readonly Variablen der bash sind. Wenn Du ganze Zeilen
    haben willst, dann nur einer Variable dem bash-builtin ``read''
    angeben oder Du verwendest IFS, allerdings solltest Du vorher
    immer den alten Wert sichern und nach dem Parsen
    zurücksetzen.


    Btw: Unter einer SuSE Linux sollte auch


    Code
    killproc /path/to/your/program


    funktionieren.


    Werner

  • Hallo Fux,


    Zitat

    Das mit der Variable i ist mir nicht ganz klar, die geht ja quasi immer von "(" zu "(" oder? Wieso hat sie als Inhalt plötzlich den Text, das ist ja dann quasi ein Zeiger der inkrementiert wird, oder?


    Meine awk-Lösung:
    i zählt die Teile einer Zeile durch, wobei NF die Gesamtzahl der Teile ist. Also bei
    |-S20pim(1465)---su(1469)---bash(1476)---bash(1520)---java(1527)---java(1545)-+-java(1547)
    ist NF=7 und i läuft von 2 bis 7. $i ist der Inhalt eines Teiles, also $2="1465)---su".


    Meine perl-Lösung:
    $i zählt die Teile einer Zeile durch, wobei $#F die Gesamtzahl der Teile minus eins ist. Also bei
    |-S20pim(1465)---su(1469)---bash(1476)---bash(1520)---java(1527)---java(1545)-+-java(1547)
    ist $#F=6 und $i läuft von 1 bis 6. $F[$i] ist der Inhalt eines Teiles, also $F[2]='"1465)---su".


    Zitat

    Und das +0 ist ein Trick um alle Buchstaben rauszukicken?


    Der Trick funktioniert bei beiden Parsern: Wenn ich zu einer Zeichenkette "1465)---su" eine Zahl addiere, dann werden nur Zahlen interpretiert. Bei +0 kommt dadurch 1465 heraus.


    Ich hoffe, ich hab's verständlich erklärt,
    Armin

    VDR
    ASUS A7N8X-X, AMD 2600+, 2 GB, 320 GB HD, Hauppauge DVB-S 1.3, Hauppauge Nova-S-Plus, Funktastatur
    Debian 4.0/Etch-Kernel 2.6.18-5-486
    c't-VDR 6.1 mit e-tobi 1.6.0 (neu gepatched ohne sortrecordings), acpi, vdradmin-am, burn, osdteletext, ffnetdev, audiorecorder, infosatepg, ...
    Client
    dbox2 (Sagem 2xI_C) mit Neutrino-Derivat

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!