Anzeige:
Seite 2 von 6 ErsteErste 1234 ... LetzteLetzte
Ergebnis 16 bis 30 von 76

Thema: Syntax-Problem mit bash-Script

  1. #16
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    wenn da "screen" und nicht "SCREEN" gestartet wird, dann wäre das schon mal eine Variante zum Testen - für Unix ist nun mal ein kleiner fehltritt was anderes als ein grosses FETTNÄPPFCHEN. Da ich nicht vorhabe, einen Shoutcast-Server aufzubauen, kann ich auch nicht live testen (screen brauche ich im Allgemeinen auch nie, ich habe immer ca. 20 Shells offen - meine gültige Definition für eine grafische Oberfläche lautet: "Möglichkeit, mindestens 10 Terminalfenster gleichzeitig zu öffnen" ;-).

    Mach bitte mal vor dem kill-Kommando ein "ps -ef | grep sc_serv" und schau Dir das Ergebnis an. Dann siehst Du, wie die abzumurksenden Prozesse tatsächlich heissen.

    Jan

    P.S.: Was mir so beim Nachdenken auffällt - gibt es einen bestimmten Grund, warum Du den sc_serv über screen startest?

  2. #17
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    Hallo!

    So, nun habe ich mal weiter rumgetüftelt udn wieder mal herausgefunden, dass sich beim screen mit dem Parameter -X nicht einfach irgendwelche Befehle ausführen lassen.

    Dann bleibt mir wohl nichts anderes übrig, als die PID so zu beziehen und dies dann über kill zu beenden:

    Code:
    ps aux | grep 'SCREEN -dmS sc1 /home/shoutcast/sc_serv' | grep -v grep | cut -c9-16 | sed s/" "/""/g
    Leider bin ich aber im Moment überfragt, wieso er mir jetzt immer noch diese Fehlermeldung bringt:
    Code:
    h852677:~# kill "ps aux | grep 'SCREEN -dmS sc1 /home/shoutcast/sc_serv' | grep -v grep | cut -c9-16 | sed s/" "/""/g"
    -bash: kill: ps aux | grep 'SCREEN -dmS sc1 /home/shoutcast/sc_serv' | grep -v grep | cut -c9-16 | sed s/: no such pid
    -bash: kill: //g: no such pid
    Führe ich den Befehl manuell einzeln ebenfalls in der Konsole aus, erhalte ich jedoch die PID:

    Code:
    h852677:~# ps aux | grep 'SCREEN -dmS sc1 /home/shoutcast/sc_serv' | grep -v grep | cut -c9-16 | sed s/" "/""/g
    5349
    An was könnte das denn liegen?

    Und warum ich sc_serv in einem Screen starte hat eig. den Grund, dass man diesen dort besser beobachten kann.
    Mit einem kleinen Befehl screen -r sc1 kann man sofort sehen was der Server gerade treibt.

    Die Ausgabe von deinem Kommando ergibt übrigens folgendes:
    Code:
    h852677:~# ps -ef | grep sc_serv
    root      5349     1  0 14:20 ?        00:00:00 SCREEN -dmS sc1 /home/shoutcast/sc_serv
    root      5350  5349  0 14:20 pts/1    00:00:09 /home/shoutcast/sc_serv
    root     11450  3296  0 15:00 pts/0    00:00:00 grep sc_serv
    MfG
    Michael

  3. #18
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Zitat Zitat von Fireball22 Beitrag anzeigen
    ...Dann bleibt mir wohl nichts anderes übrig, als die PID so zu beziehen und dies dann über kill zu beenden:

    Code:
    ps aux | grep 'SCREEN -dmS sc1 /home/shoutcast/sc_serv' | grep -v grep | cut -c9-16 | sed s/" "/""/g
    Leider bin ich aber im Moment überfragt, wieso er mir jetzt immer noch diese Fehlermeldung bringt:
    Code:
    h852677:~# kill "ps aux | grep 'SCREEN -dmS sc1 /home/shoutcast/sc_serv' | grep -v grep | cut -c9-16 | sed s/" "/""/g"
    -bash: kill: ps aux | grep 'SCREEN -dmS sc1 /home/shoutcast/sc_serv' | grep -v grep | cut -c9-16 | sed s/: no such pid
    -bash: kill: //g: no such pid
    Führe ich den Befehl manuell einzeln ebenfalls in der Konsole aus, erhalte ich jedoch die PID...
    Das ist kein Wunder - Du übergibst dem kill ja nicht die Ausgabe des Befehls, sondern einfach die Zeichenfolge des Befehls (der Teil "ps ..." wird also nicht ausgeführt, sondern als Argument an kill verfüttert). Dazu musst Du Backticks benutzen:
    Code:
    kill `ps aux ...`
    Zu Deinem Befehlsmarathon für die Ermittlung der PID: Das geht einfacher:
    Code:
    ps -o pid= -C 'SCREEN -dmS sc1 /home/shoutcast/sc_serv'
    Noch ein kleiner Tipp unabhängig davon: Wenn man eine Prozessliste greppt und dabei den grep nicht sehen will (logo, will man meist nicht), dann kann man sich den 2. "grep -v" mit folgendem Trick sparen:
    Code:
    ps aux | grep '[S]CREEN -dmS sc1 /home/shoutcast/sc_serv'
    Die eckigen Klammern um den 1. Buchstaben bilden für grep einen regulären Ausdruck, nämlich eine Menge aus genau einem Buchstaben - er findet also nach wie vor den SCREEN, aber nicht mehr sich selbst, weil da ja "[S]CREEN" steht.

    Jan

    EDIT: Ausserdem hast Du in der Befehlszeile einen Syntaxfehler. Mit dem ersten " im sed beendest Du das Argument, das mit dem " vor ps anfängt, ab dem "/... wird alles als neues Argument betrachtet (deshalb auch 2 Fehlermeldungen). Merke - innerhalb eines per "..." begrenzten Blocks muss jedes " entwertet werden (\").
    Geändert von jan61 (07-01-2008 um 19:47 Uhr)

  4. #19
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    Vielen Dank für deine Antwort!

    Ich habe nun auch gleich mal deine Möglichkeit, die PID herauszufinden getestet, aber leider bringt mir der Befehl keine Ausgabe, obwohl das Kommando genau so in der Prozessliste steht.
    An was könnte das liegen?

    Die Ausgabe von ps aux:
    Code:
    root     28247  0.0  0.0  4348 1032 ?        Ss   16:14   0:00 SCREEN -dmS sc1 /home/shoutcast/sc_serv
    root     28248  0.2  0.0 37788 1764 pts/1    Ss+  16:14   0:00 /home/shoutcast/sc_serv
    Probier ich das ganze nun allerdings mit meinem "Befehlsmarathon", dann klappt das killen des screens zwar, nur beendet er dann nicht automatisch die Prozesse, die auf dem Screen laufen, was aber doch eig. der Fall sein möchte, oder nicht?
    Gibt es da noch einen Trick um diesen direkt mitzukillen, oder muss ich den dann wohl oder über mit einer zweiten kill-Anweisung extra beenden?

    Zudem bin ich gerade am überlegen, ob sich das ganze dann in so einem Prinzip verpacken lässt:

    kill PID || kill -9 PID

    Er würde dann so erstmal versuchen den Prozess BITTE beenden zu lassen, klappt das nicht, dann MUSS er eben den Prozess beenden?!
    Nur ich bin mir nicht sicher, ob kill auch den richtigen Return-Code dafür zurückgibt um diese ODER-Anweisung richtig zu Verarbeiten?
    Hast du damit vllt. schon Erfahrung?

    MfG
    Michael

    PS: Und noch vielen Dank für die geniale Idee mit dem Regulären Ausdruck!
    Da wär ich mal echt nicht drauf gekommen!

  5. #20
    Registrierter Benutzer
    Registriert seit
    08.01.2001
    Beiträge
    242

    Wink

    noch ein kleiner tip:

    wenn du mit pid's & co. spielst, schaue dir mal pkill und pgrep und in deinem fall auch mit der option "-f" an. Das erleichtert das Scriptleben enorm.

    der tom

  6. #21
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von Fireball22 Beitrag anzeigen
    ...Ich habe nun auch gleich mal deine Möglichkeit, die PID herauszufinden getestet, aber leider bringt mir der Befehl keine Ausgabe, obwohl das Kommando genau so in der Prozessliste steht.
    An was könnte das liegen?
    Schau Dir mal die Prozessliste mit einem "ps -ef" an. Der ps kann in 2 Modi laufen, nämlich dem "alten" UCB-Modus (das ist Dein "ps aux") und der heute eher gebräuchlichen SYSV-Syntax. Beide haben ihre Vorteile und Macken, aber die Ausgabe kann sich eben unterscheiden. Der Krieg ATT (aka SYSV-Unix) vs. UCB ist übrigens hier ganz nett beschrieben: http://www.livinginternet.com/i/iw_unix_war.htm - in der man-Page von ps findest Du beide Welten als "Linux" und "BSD" wieder. Aber das nur nebenbei.

    Zitat Zitat von Fireball22 Beitrag anzeigen
    Probier ich das ganze nun allerdings mit meinem "Befehlsmarathon", dann klappt das killen des screens zwar, nur beendet er dann nicht automatisch die Prozesse, die auf dem Screen laufen, was aber doch eig. der Fall sein möchte, oder nicht?
    Gibt es da noch einen Trick um diesen direkt mitzukillen, oder muss ich den dann wohl oder über mit einer zweiten kill-Anweisung extra beenden?
    Deshalb nutze ich immer die SYSV-Version des ps - damit kannst Du Dir z. B. alle Prozesse anzeigen lassen, die einer Session angehören (Option -s) und die dann in einem Rutsch killen. Es ist nicht zwingend so, dass die Kinder verrecken, wenn man den Papa abmurkst, das hängt davon ab, wie sie auf Signale des werten Erzeugers reagieren. Die Unix-Systeme gehen mit der Zeit - welches Kind hört heutzutage denn noch auf seine Eltern?

    Zitat Zitat von Fireball22 Beitrag anzeigen
    Zudem bin ich gerade am überlegen, ob sich das ganze dann in so einem Prinzip verpacken lässt:

    kill PID || kill -9 PID

    Er würde dann so erstmal versuchen den Prozess BITTE beenden zu lassen, klappt das nicht, dann MUSS er eben den Prozess beenden?!
    Nur ich bin mir nicht sicher, ob kill auch den richtigen Return-Code dafür zurückgibt um diese ODER-Anweisung richtig zu Verarbeiten?
    Hast du damit vllt. schon Erfahrung?
    Nach meiner Erfahrung geht das so nicht. kill ist damit zufrieden, wenn er das Signal erfolgreich absetzen konnte. Wie die Prozesse darauf reagieren (sie können es z. B. per sigprocmask() einfach ignorieren oder sie warten gerade auf die Rückkehr eines System-Calls, dann sind sie im Status "nicht unterbrechbar"), ist deren Sache oder die des Kernels. Am besten ist es hier, das Verhalten eines Unix-Systems beim Shutdown nachzuahmen: Schicke zuerst mal ein "normales" kill an den Prozess, warte ein wenig (es kann sein, dass der Prozess ein wenig braucht, um Caches zu leeren, temp. Dateien aufzuräumen, einen Brief an die Freundin zu schicken ;-) und dann schicke ihm SIGKILL (-9) - dieses Signal kann kein Prozess ignorieren (es ist deshalb so unwiderstehlich, weil ein SIGIGNORE für dieses Signal technisch nicht funktioniert).

    Jan

  7. #22
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    @meinereinerseiner
    Vielen Dank für den Klasse Tipp mit dem pgrep und pkill, habe damit zwar schon auch vor ein paar Tagen etwas probiert, aber leider bin ich nie auf den Paramter -f gekommen, aber jetzt funktioniert das ganze ohne Probleme!

    @jan61
    Vielen Dank auch hier nochmals für deine genauen Erläuterungen zu meinem doch etwas "komplexeren" Problem!
    Dann werde ich es einfach mal in diesem Stil versuchen:

    pkill [SERVER]
    wait
    pkill -9 [SERVER] //Wenn Server nicht mehr läuft, wird ein Fehler ausgegeben
    ---
    pkill [SCREEN]
    wait
    pkill -9 [SCREEN]

    Nur die Frage ist jetzt noch, wie ich das mit dem "wait" realisiere, dass er eine bestimmte Zeit wartet, bis alle arbeiten für das Beenden des Prozesses erledigt sind, gibt es dafür ein passendes Kommando?

    MfG
    Michael

  8. #23
    Registrierter Benutzer
    Registriert seit
    08.01.2001
    Beiträge
    242
    Zitat Zitat von Fireball22 Beitrag anzeigen

    Nur die Frage ist jetzt noch, wie ich das mit dem "wait" realisiere, dass er eine bestimmte Zeit wartet, bis alle arbeiten für das Beenden des Prozesses erledigt sind, gibt es dafür ein passendes Kommando?

    MfG
    Michael
    z.B.: 5 Sekunden nichts tun:
    Code:
    sleep 5
    tom
    Geändert von meinereinerseiner (14-01-2008 um 17:14 Uhr)

  9. #24
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    Vielen Dank für deine Antwort, habe jetzt geradeeben mal das ganze zusammengebaut und folgendes ist dabei rausgekommen:

    Code:
    ./DeinScript_new: line 125: syntax error near unexpected token `('
    ./DeinScript_new: line 125: `                                   if [ $? -eq (0|1) ]; then'
    Code:
    if [ ${use_user} -eq 1 ]; then
                                            su -c 'killall -9 "sc1" "${username}"'
                                    else
                                    ##      kill `ps aux | grep 'SCREEN -dmS sc1 /home/shoutcast/sc_serv' | grep -v grep | cut -c9-16 | sed s/" "/""/g`
                                            pkill -f "${path_shoutcast}/sc_serv"
                                            if [ $? -eq 0 ]; then
                                                    SUCCESS=1
                                            fi
                                            sleep 5
                                            pkill -9 -f "${path_shoutcast}/sc_serv"
                                            if [ $? -eq (0|1) ]; then
                                                    SUCCESS=1
                                            fi
                                    if [ ${success} -eq 1 ]; then
                                            echo "done"
                                            rm -f "${path_shoutcast}/server.pid"
                                    else
                                            echo "false"
                                    fi
    
                                    fi
    Leider bin ich mir nicht genau sicher, ob dieser Regulärer Ausdruck stimmt, allerdings habe ich so etwas in einigen Berichten bei google gefunden.

    MfG
    Michael

  10. #25
    Registrierter Benutzer Avatar von jeebee
    Registriert seit
    01.01.2005
    Ort
    Bern || Zürich
    Beiträge
    540
    test, also [] kann nur "einfache" Werte vergleichen, falls ich deinen Code richtig interpretiere willst du:
    Code:
    if [ $? -eq 0 -o $? -eq 1 ]; then
    also Rückgabewert 0 oder 1.
    my very own 128 bit integer
    C4 D3 B8 A8 9E A0 C6 EC 7D EC A8 15 28 D1 92 58
    more information

  11. #26
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    Vielen Dank, genau nach so etwas habe ich schon vergeblich gesucht, habe das ganze auch schon mit ||-Operatoren versucht, aber damit möchte die BASH ja leider nicht arbeiten, aber jetzt klappts perfekt, vielen Dank! =)

    MfG
    Michael

  12. #27
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Vorsicht mit der SUCCESS-Variablen. Wenn Du SUCCESS definierst, musst Du auch $SUCCESS abfragen, nicht $success.

    Jan

    P.S.: Die bash kann schon mit || arbeiten, aber der test nicht:
    Code:
    SUCCESS=1
    pkill ...
    [ $? -eq 0 -o $? -eq 1 ] || SUCCESS=0
    Die || signalisieren der bash: Wenn der vorhergehende Befehl einen Returncode ungleich 0 liefert, führe den danach folgenden Befehl aus. Analog mit &&:
    Code:
    SUCCESS=0
    pkill ...
    [ $? -eq 0 -o $? -eq 1 ] && SUCCESS=1
    Führt den 2. Befehl dann aus, wenn der davor mit Returncode 0 zurückkommt.

  13. #28
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    Vielen Dank, genau das habe ich gestern Abend auch noch herausgefunden, dass ich dort aus Versehen die Variable groß geschrieben habe, aber jetzt sollte auch das klappen =)

    Genau, stimmt, nur leider funktioniert dieser Operator in den Tests nicht

    Aber ich werde jetzt naher gleich mal alle Funktionen des Scripts durchtesten und euch bescheid geben ob soweit alles funktioniert =)

    MfG
    Michael

  14. #29
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    So, jetzt habe ich mein Script in allen Kategorien komplett weiterentwickelt, aber leider hindert mich daran immer dieser Fehler:

    Code:
    h852677:~# su -c `pkill -f "/home/shoutcast/sc_serv"` 'shoutcast'
    bash: line 1: shoutcast: command not found
    Ich habe es mehrmals mit anderen Syntaxen probiert, obwohl dass doch soweit alles stimmen sollte, oder?

    MfG
    Michael

  15. #30
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Zitat Zitat von Fireball22 Beitrag anzeigen
    So, jetzt habe ich mein Script in allen Kategorien komplett weiterentwickelt, aber leider hindert mich daran immer dieser Fehler:

    Code:
    h852677:~# su -c `pkill -f "/home/shoutcast/sc_serv"` 'shoutcast'
    bash: line 1: shoutcast: command not found
    Ich habe es mehrmals mit anderen Syntaxen probiert, obwohl dass doch soweit alles stimmen sollte, oder?

    MfG
    Michael
    Diese Syntax verstehe ich nicht. Was soll dieses 'shoutcast' am Ende? Und wieso übergibst Du die Standardausgabe des pkill-Kommandos an den "su -c" (das machst Du nämlich mit `..`)? pkill liefert auf stdout nichts zurück, wenn ich die man-Page richtig gelesen habe. Du willst doch alle Prozesse beenden, deren Kommandozeile auf "/home/shoutcast/sc_serv" matcht, oder? Dann sollte doch ein simples
    Code:
    pkill -f "/home/shoutcast/sc_serv"
    ausreichen, wenn Du das Script mit einem anderen Benutzer als root aufrufst, musst Du bei "su -c" dessen Passwort eingeben. Willst Du das?

    Jan

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •