Anzeige:
Seite 3 von 6 ErsteErste 12345 ... LetzteLetzte
Ergebnis 31 bis 45 von 76

Thema: Syntax-Problem mit bash-Script

  1. #31
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    Ja genau, so ähnlich möchte ich es.
    Standardmäßig ist für den Benuzter shoutcast und ebenfalls in meinem Fall zwar kein Passwort festgelegt, aber um die Sicherheit in meinem Script zu erhöhen, möchte ich den Befehl gerne unter der Benutzerebene shoutcast killen, somit kann ich auch verhindern, dass andere Prozesse aus Versehen gekillt werden.

    Eig. sollte das mit dem Befehl su -c COMMAND USER gehen, oder stimmt das nicht ganz?

    MfG
    Michael

  2. #32
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.859
    Moin moin,
    versuch es mal mit
    Code:
    su -c 'pkill -f ".."' shoutcast
    d. h., wenn der zu killende Prozess sowieso shoutcast gehört (und Du das darfst) vllt auch einfach
    Code:
    pkill -u shoutcast -f ".."
    MfG,
    Rainer
    There's nothing a good whack with a hammer won't fix!

  3. #33
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    Vielen Dank, genau so würde es funktionieren, allerdings sind die Pfade und der Benutzername ja variabel, und durch die Hochkomma werden die Variablen nicht mehr aufgelöst, siehe:

    Code:
    su -c `pkill -f "${path_shoutcast}/sc_serv"` "${username}"
    Zudem finde ich die Idee, den User-Parameter direkt in pkill einzubauen nicht schlecht, aber aus Sicherheitsgründen ist es eher evtl. doch vllt. sicherer, wenn man direkt den ganzen Befehl mit einem niedrigeren User-Level ausführt.

    Lässt sich da vllt. eine Möglichkeit finden?

    MfG
    Michael

  4. #34
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.859
    Moin moin,
    Zitat Zitat von Fireball22 Beitrag anzeigen
    Vielen Dank, genau so würde es funktionieren, allerdings sind die Pfade und der Benutzername ja variabel, und durch die Hochkomma werden die Variablen nicht mehr aufgelöst, siehe:

    Code:
    su -c `pkill -f "${path_shoutcast}/sc_serv"` "${username}"
    warum -- schon wieder -- Backticks (`) und keine Hochkommata (')?
    Ich hab das mal eben durchgespielt -- da ich sc_serv nicht hab, hab ich einfach stellvertretend xterm genommen und Testuser `bar' startet:
    Code:
    /usr/bin/xterm &
    nun komm ich daher:
    Code:
    x=/usr/bin
    su -c 'pkill -f "$x/xterm"' bar
    und bars xterm verabschiedet sich.
    MfG,
    Rainer
    There's nothing a good whack with a hammer won't fix!

  5. #35
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von rais Beitrag anzeigen
    warum -- schon wieder -- Backticks (`) und keine Hochkommata (')?
    1. - ja, warum? Da hab ich doch extra einen (hoffentlich verständlichen) Satz zu geschrieben. Anmerkung: Das Hochkomma ist <SHIFT>#, der Backtick ist <SHIFT>´ (die Taste links neben dem <BACKSPACE> oben rechts).

    2. Und warum Hochkommata? Die Variablen werden darin NICHT aufgelöst - hatte ich auch schon geschrieben!

    Zitat Zitat von rais Beitrag anzeigen
    Ich hab das mal eben durchgespielt -- da ich sc_serv nicht hab, hab ich einfach stellvertretend xterm genommen und Testuser `bar' startet:
    Code:
    /usr/bin/xterm &
    nun komm ich daher:
    Code:
    x=/usr/bin
    su -c 'pkill -f "$x/xterm"' bar
    und bars xterm verabschiedet sich.
    Das funktioniert nur deshalb, weil die -f-Option ein Pattern definiert, in Deinem pkill kommt nämlich 'pkill -f "/xterm"' an, das matcht eben auch auf "/usr/bin/xterm". Probiers aus:
    Code:
     su -c 'echo pkill -f "$x/xterm"' bar
    @Fireball22: Mach Dir doch das Leben nicht unnötig schwer. Du versiehst alles, was länger als eine halbe Sekunde stillhält, ohne Not mit ', ", {} oder ` - offenbar ohne Dir über die Auswirkungen im Klaren zu sein.

    Ich versuche nochmal eine kleine Erklärung:

    1. Eine Variable in der Shell wird mit variable=... definiert. Für den Teil nach dem = sind die Besonderheiten lt. 2. - 6. zu beachten.

    2. Eine Variable in der Shell wird mit $variable abgefragt. Nur in den Fällen, in denen NACH dem VariablenNAMEN ein Zeichen folgt, das als Teil eines Variablennamens interpretiert werden könnte, muss die Schreibweise ${variable} verwendet werden. Ein Leerzeichen oder "" gehören definitiv nicht dazu, also reicht "$username".

    3. Eine Variable in der Shell wird mit $variable abgefragt. Nur in den Fällen, in denen der VariablenINHALT einen Whitespace (Leer-, Tabulatorzeichen) oder Zeilenumbruch enthalten kann, der als Argument-Trenner interpretiert werden kann, muss die Variable mit "" umschlossen werden. Das trifft auf Benutzernamen definitiv nicht zu, also reicht ein $username.

    4. Ein mit "" umschlossenes Argument entwertet z. B. Whitespaces, aber z. B. keine $-Zeichen, die die Shell als Beginn eines Variablen-Namens oder ``, die als auszuführender Befehl interpretiert werden. Variablen oder `...`-Kommandos innerhalb von "" werden also aufgelöst / ausgeführt.

    5. Ein mit '' umschlossenes Argument entwertet ALLES, also auch $-Zeichen - es wird nix ausgewertet.

    Das führt im o. a. Beispiel z. B. dazu, dass der su -c 'pkill -f "$x/xterm"' an die durch "su -c" gestartete Subshell das Kommando pkill -f "$x/xterm" durchreicht. In dieser Subshell ist $x aber gar nicht bekannt - sie wird folglich durch nix ersetzt, heraus kommt pkill -f /xterm. Wenn man das verhindern will, gibt es 2 Möglichkeiten: Entweder man exportiert die Variable x oder man ruft das Kommando so auf: su -c "pkill -f '$x/xterm'".

    6. Die Backticks `` haben eine völlig andere Bedeutung. Alles, was innerhalb dieser Backticks steht, wird von der aufrufenden Shell als Kommando betrachtet und ausgeführt. Das, was dieses Kommando auf stdout ausgibt, wird an die Stelle des `..`-Blocks gesetzt. Auch hier gelten wieder die unter 4. und 5. genannten Besonderheiten.

    7. Ein su $username -c kommando mag sicherer sein wegen der fehlenden Berechtigungen, aber rais hat auch eine bessere Variante beschrieben, nämlich stattdessen pkill -u $username -f "..." zu nutzen. Damit sparst Du eine Subshell. Ein Blick in die man-Page von pkill hätte Dir das auch verraten. Der su-Befehl würde Dir nämlich unnötige Fehlermeldungen bringen, wenn er sc_serv-Prozesse von anderen Benutzern killen will und nicht kann. die -u-Option des pkill schränkt die zu killenden Prozesse dagegen von vornherein auf die des angegebenen Benutzers ein und versucht gar nicht erst, in fremden Revieren zu wildern. Und ganz nebenbei: UserNAMEN sind Schall und Rauch, es kommt allein auf die UserID an. Wenn Dein shoutcast-Benutzer die UID 0 hat, würde der pkill trotzdem die sc_serv-Prozesse aller Benutzer killen.

    Jan

    P.S.: Das Verhalten der Shell in Bezug auf die o. g. Punkte ist in der (zugegebenermaßen ziemlich umfangreichen) man-Page der Shell ausführlich beschrieben. Ich hab sie mir vor ganz langer Zeit einfach mal ausgedruckt ...

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

    Also ich habe mich darauf nur auf die Antwort #12 von jan61 bezogen:
    In einfache Hochkommata eingeschlossener Text wird durch die Shell nicht ausgewertet, die Variable ${path_shoutcast} wird also nicht durch den Inhalt ersetzt.
    Aber du hast echt recht, ich habe es gerade selber ausprobiert, es funktioniert tatsächlich! =)
    Vielen Dank nochmals!

    Aber wann nimmt man dann die Backsticks, die Hochkommata und wann die normalen Anführungszeichen?

    MfG
    Michael

    EDIT:
    @jan61
    Hab mein Posting leider währenddessen verfasst, als du mir schon zurück geschrieben hast =)
    Vielen Dank für deine ausführliche Erklärung!
    Dass das ganze dann natürlich als Pattern interpretiert wird, erklärt alles

    Ich werd mich dann jetzt naher aufjedenfall auch nochmals deine Definitionen ganz genau durchlesen, dass ich in Bezug auf das ganze keine Fehler mehr in Zukunft machen werde!

    Vielen Dank nochmals! =)
    Geändert von Fireball22 (19-01-2008 um 20:51 Uhr)

  7. #37
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    4 Minuten vor Deiner Antwort hab ich meine abgeschickt - da steht (hoffentlich ,-) alles drin. Das hat sich offenbar überschnitten.

    Jan

  8. #38
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Zitat Zitat von Fireball22 Beitrag anzeigen
    ...@jan61
    Hab mein Posting leider währenddessen verfasst, als du mir schon zurück geschrieben hast =)...
    So kanns eben kommen Während Du das EDIT verfasst hast, hab ich meine nächste Antwort geschrieben - ist eben asynchrone Kommunikation hier. Manchmal ist ein IRC doch nicht zu verachten ;-), aber da kann man nicht mehr korrigieren, wenn man Mist verzapft hat

    Zitat Zitat von Fireball22 Beitrag anzeigen
    Ich werd mich dann jetzt naher aufjedenfall auch nochmals deine Definitionen ganz genau durchlesen, dass ich in Bezug auf das ganze keine Fehler mehr in Zukunft machen werde!
    Fehler passieren jedem - sonst wäre hier ja gar nix los ;-) - und solche Sachen wie Hochkomma, Backtick oder Anführungszeichen erschließen sich nun mal nicht sofort. Da hilft nur üben, üben, üben (und lesen, lesen, lesen) und da bist Du ja auf dem richtigen Weg.

    Jan

    P.S.: Hatte ich schon erwähnt, dass ein "set -x" am Anfang des Scripts wahre Wunder wirkt, wenn man dahinter steigen will, was die Shell wirklich veranstaltet?

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

    Also das set -x steht seit einem deiner vorherigen Postings in meinem Script, das ist in der Tat echt sehr hilfreich!

    Jetzt hätte ich allerdings noch ein paar Fragen:

    1) Damit das Script weiß, ob bereits ein SHOUTCAST-Server läuft, legt das Script nach erfolgreichem starten eine leere PID-File an, welche dann beim nächsten Startversuch abgefragt wird, ob diese bereits existiert.
    Allerdings wäre es etwas umständlicher auch möglich eine art Realtime-Abfrage unter den Prozessen zu machen, ob dieser in der Realität auch läuft und dieser nicht währenddessen manuell gekillt wurde, die PID-File aber allerdings nicht gelöscht wurde.
    Meine Frage wäre jetzt, ob es ausreichend ist, diese Prüfung mit einer PID-File durchzuführen?

    2) Um das Script möglichst klein zu halten, gilt für die Funktionen mit und ohne User der gleiche PID-File-Löschbefehl.
    Code:
    rm -f PFAD/ZUR/PID-FILE
    Sollte ich aber auch speziell noch eine Methode anbieten, bei der auch die PID-File nur mit den Rechten des angegeben Users gelöscht wird, oder muss man da mit keinen Sicherheitsrisiken rechnen?

    3) Mein Script bietet ja auch eine Restart-Funktion.
    Gerne würde ich dort nicht den ganzen Code neu aufrollen um das Script so klein wie möglich zu halten.
    Nur wie kann ich den Dateinamen des gerade laufenden Scripts ermitteln, da ich diesem ja im Script nicht fest definieren kann, falls dieser Dateiname mal geändert wird.

    4) Es soll auch eine SCREEN-Methode geben, die unter einem bestimmten Benutzer läuft, da SCREEN aber leider selber keine Parameter dafür anbietet, würde ich das ganze gerne so realisieren:
    Code:
    screen -dmS sc1 'su -c "${path_shoutcast}/sc_serv" $username'
    Das Script wird erfolgreich ohne Fehlermeldungen ausgeführt, allerdings wird trotzdem kein Server gestartet, was die Ausgabe von ps aux und ps -ef bestätigt.
    Kann das mit dem exportieren der Variablen zusammenhängen?

    MfG
    Michael

  10. #40
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Zitat Zitat von Fireball22 Beitrag anzeigen
    ...1) Damit das Script weiß, ob bereits ein SHOUTCAST-Server läuft, legt das Script nach erfolgreichem starten eine leere PID-File an, welche dann beim nächsten Startversuch abgefragt wird, ob diese bereits existiert.
    Allerdings wäre es etwas umständlicher auch möglich eine art Realtime-Abfrage unter den Prozessen zu machen, ob dieser in der Realität auch läuft und dieser nicht währenddessen manuell gekillt wurde, die PID-File aber allerdings nicht gelöscht wurde.
    Meine Frage wäre jetzt, ob es ausreichend ist, diese Prüfung mit einer PID-File durchzuführen?
    Zur Realtime-Abfrage kannst Du eigentlich auf PID-Files verzichten und stattdessen das schon erwähnte pgrep benutzen (ist mit in der Man-Page von pkill beschrieben und versteht die gleichen Parameter). PID-Files haben den Nachteil, den Du ja schon erkannt hast: Wenn der Prozess von außen beendet wurde, kann er es nicht mehr abräumen. Eine andere Variante wäre es, die PID des Shoutcast-Servers in die Datei zu schreiben und diese dann zu prüfen. Macht aber mehr Aufwand.

    Zitat Zitat von Fireball22 Beitrag anzeigen
    2) Um das Script möglichst klein zu halten, gilt für die Funktionen mit und ohne User der gleiche PID-File-Löschbefehl.
    Code:
    rm -f PFAD/ZUR/PID-FILE
    Sollte ich aber auch speziell noch eine Methode anbieten, bei der auch die PID-File nur mit den Rechten des angegeben Users gelöscht wird, oder muss man da mit keinen Sicherheitsrisiken rechnen?
    Hängt davon ab, was Du willst. Wenn es verschiedene Shoutcast-Prozesse geben soll, die unter verschiedenen Benutzern gleichzeitig laufen, dann musst Du Dir sowieso um die Benennung der Dateien Gedanken machen. Wenn die Datei nur zur Markierung "hier läuft ein sc_serv" gedacht ist, dann sollte sie auch immer weggeputzt werden, wenn der Server gestoppt ist. Dann handelst Du Dir nur Probleme ein, wenn die Datei bei Stop nicht gelöscht wird.

    Zitat Zitat von Fireball22 Beitrag anzeigen
    3) Mein Script bietet ja auch eine Restart-Funktion.
    Gerne würde ich dort nicht den ganzen Code neu aufrollen um das Script so klein wie möglich zu halten.
    Nur wie kann ich den Dateinamen des gerade laufenden Scripts ermitteln, da ich diesem ja im Script nicht fest definieren kann, falls dieser Dateiname mal geändert wird.
    Wenn ich mich recht erinnere, rufst Du doch immer das gleiche Script auf, nur mit anderen Parametern (start, stop, restart)? In dem Fall ist der effektivste Weg, die Funktionalität für "start" und "stop" in Funktionen auszulagern, dann brauchst Du für "restart" nur nacheinander die stop- und start-Funktion aufzurufen. Der Dateiname des Scripts steht in $0.

    Zitat Zitat von Fireball22 Beitrag anzeigen
    4) Es soll auch eine SCREEN-Methode geben, die unter einem bestimmten Benutzer läuft, da SCREEN aber leider selber keine Parameter dafür anbietet, würde ich das ganze gerne so realisieren:
    Code:
    screen -dmS sc1 'su -c "${path_shoutcast}/sc_serv" $username'
    Das Script wird erfolgreich ohne Fehlermeldungen ausgeführt, allerdings wird trotzdem kein Server gestartet, was die Ausgabe von ps aux und ps -ef bestätigt.
    Kann das mit dem exportieren der Variablen zusammenhängen?
    Ja, da bist Du wieder in die '' / ""-Falle getappt. Mit Deiner Syntax kommt der Befehl im su -c unverändert an (ohne die Variablen zu ersetzen) und damit wirkt er nur dann, wenn $path_shoutcast und $username exportiert wurden. Letztendlich will su -c ausführen: "/sc_serv", weil beide Variablen in dieser Subshell nicht bekannt sind und damit leer ersetzt werden. Nimm die andere Reihenfolge:
    Code:
     screen -dmS sc1 "su -c '${path_shoutcast}/sc_serv' $username"
    Den Unterschied müsstest Du eigentlich bei set -x in der Ausgabe sehen.

    Jan

  11. #41
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    Vielen Dank für deine Antworten!

    Dann werde ich das auch mit der Restart-Funktion alles so umsetzten und das ganze einfach kompakter halten!

    Und mit dem Status-Check, ob der Server bereits gestartet ist oder nicht, werde ich es dann wohl so in der Art machen:

    Code:
    if [ 'pgrep -f "${path_shoutcast}/sc_serv"' -eq 0 ]; then
    #CODE CODE CODE
    fi
    Und bezüglich des Exports:
    Ich bekomme hier beim exportieren immer diesen Fehler:

    Code:
    h852677:~# ./DeinScript_new start
    + path_shoutcast=/home/shoutcast
    + use_screen=1
    + use_user=1
    + username=shoutcast
    + '[' '!' -e /home/shoutcast/server.pid ']'
    + '[' 1 -eq 1 ']'
    + '[' 1 -eq 1 ']'
    + export /home/shoutcast
    ./DeinScript_new: line 29: export: `/home/shoutcast': not a valid identifier
    + export shoutcast
    + screen -dmS sc1 'su -c '\''/home/shoutcast/sc_serv'\'' shoutcast'
    + '[' 0 -eq 0 ']'
    + echo 11694
    + echo -ne '\033[0;32mDONE\033[0m Server wurde gestartet\n\033[0;32mDONE\033[0m PID-File wurde erfolgreich angelegt\n'
    DONE Server wurde gestartet
    DONE PID-File wurde erfolgreich angelegt
    + exit 0
    Der Code sieht so aus:

    Code:
    export $path_shoutcast
    export $username
    screen -dmS sc1 "su -c '${path_shoutcast}/sc_serv' $username"
    Ich dachte am Anfang, dass sich das mit Anführungszeichen sämtlicher Art beheben lässt, aber leider ging es auch dann noch nicht.
    Und der Server wird leider nach wie vor noch nicht gestartet... hmmm...

    MfG
    Michael

    EDIT:
    So, jetzt habe ich geradeeben den Restart-Bereich zusammengeschrieben und ausführlich getestet und das ist jetzt dabei rausgekommen. Es klappt alles perfekt, allerdings wollte ich doch nochmals Fragen, ob man noch etwas daran verbessern könnte. Z. B. gibt es bei PHP die Möglichkeit Code zu includieren, ist das in der Art unter Linux auch möglich, dass man nur eine bestimmte Code-Passage herausnimmt und nicht z .B. Variablen beim Aufruf des Parameters start nochmals setzt? (Das spielt hier natürlich keine Rolle auf das Script, aber vllt. gibt es ja so eine Möglichkeit wie unter PHP).
    Code:
    restart)
                    if [ -e "${path_shoutcast}/server.pid" ]; then
                            ${0} stop
                            if [ $? -eq 0 ]; then
                                    stop=1
                            fi
                            sleep 5
                            ${0} start
                            if [ $? -eq 0 ]; then
                                    start=1
                            fi
                            if [ $stop -eq 1 -a $start -eq 1 ]; then
                                    echo -ne "\033[0;32mDONE\033[0m Server wurde erfolgreich neugestartet\n"
                            else
                                    echo -ne "\033[0;31mERROR\033[0m Beim Neustarten des Servers ist ein Fehler aufgetreten...\nBitte Debug-Modus starten...\n"
                            fi
                    else
                            echo -ne "\033[0;31mERROR\033[0m Server scheint nicht online zu sein...\nBitte zuerst starten...\n"
                    fi
            ;;
    Und dann wollte ich euch noch Fragen, was ihr von der Idee hält, dass ich das Script wenn es komplett fertig ist, hier veröffentliche, denn wenn ihr mir alle schon so sehr damit behilflich seit, dann würde ich das Script auch gerne der ganzen Welt zur Verfügung stellen, dann haben auch andere was davon, wenn sie genau solch ein Script suchen =)
    Geändert von Fireball22 (20-01-2008 um 21:25 Uhr)

  12. #42
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.859
    Zitat Zitat von jan61 Beitrag anzeigen
    2. Und warum Hochkommata? Die Variablen werden darin NICHT aufgelöst - hatte ich auch schon geschrieben!
    uups
    Zitat Zitat von jan61 Beitrag anzeigen
    Das funktioniert nur deshalb, weil die -f-Option ein Pattern definiert, in Deinem pkill kommt nämlich 'pkill -f "/xterm"' an, das matcht eben auch auf "/usr/bin/xterm". Probiers aus:
    Code:
     su -c 'echo pkill -f "$x/xterm"' bar
    ...und check -- und Danke;-)
    Zitat Zitat von jan61 Beitrag anzeigen
    5. Ein mit '' umschlossenes Argument entwertet ALLES, also auch $-Zeichen - es wird nix ausgewertet.

    Das führt im o. a. Beispiel z. B. dazu, dass der su -c 'pkill -f "$x/xterm"' an die durch "su -c" gestartete Subshell das Kommando pkill -f "$x/xterm" durchreicht. In dieser Subshell ist $x aber gar nicht bekannt - sie wird folglich durch nix ersetzt, heraus kommt pkill -f /xterm. Wenn man das verhindern will, gibt es 2 Möglichkeiten: Entweder man exportiert die Variable x oder man ruft das Kommando so auf: su -c "pkill -f '$x/xterm'".
    Damit hab ich gerade ein Verständnisproblem: bedeutet das, daß die umliegenden ".." die inneren '..' entwerten oder bin ich (schon wieder) auf dem Holzweg?

    Zitat Zitat von Fireball22 Beitrag anzeigen
    Code:
    if [ 'pgrep -f "${path_shoutcast}/sc_serv"' -eq 0 ]; then
    #CODE CODE CODE
    fi
    wenn ich Jan und Dich richtig verstanden hab: wolltest Du vielleicht ein
    Code:
    if [ -n `pgrep -f "${path_shoutcast}/sc_serv"` ]; then
    ?
    Soweit ich das bisher verstanden hab, ist die Ausgabe von pgrep die entsprechende PID (so es nur um eine geht), aber Du vergleichst auf dessen Rückgabewert (0 für da gibt's was, 1 für nix passt etc.), wie es z. B. in $? direkt nach einem pgrep steht...
    Aber in bezug auf die Shell hab ich mich schon öfter vertan;-)

    MfG,
    Rainer
    There's nothing a good whack with a hammer won't fix!

  13. #43
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Zitat Zitat von rais Beitrag anzeigen
    ..Damit hab ich gerade ein Verständnisproblem: bedeutet das, daß die umliegenden ".." die inneren '..' entwerten oder bin ich (schon wieder) auf dem Holzweg?
    Nö, da liegst Du richtig.

    Zitat Zitat von rais Beitrag anzeigen
    wenn ich Jan und Dich richtig verstanden hab: wolltest Du vielleicht ein
    Code:
    if [ -n `pgrep -f "${path_shoutcast}/sc_serv"` ]; then
    ?
    Soweit ich das bisher verstanden hab, ist die Ausgabe von pgrep die entsprechende PID (so es nur um eine geht), aber Du vergleichst auf dessen Rückgabewert (0 für da gibt's was, 1 für nix passt etc.), wie es z. B. in $? direkt nach einem pgrep steht...
    Naja, fast ;-) Bei Fireball22's Code wird verglichen, ob die Zeichenkette 'pgrep ...' numerisch gleich 0 ist - isse natürlich nie. Da hier '' und nicht `` verwendet werden, wird 1. nichts von der Shell expandiert und 2. nichts ausgeführt. Um den Returncode abzufragen, verwendet man entweder:
    Code:
    pgrep ...
    if [ $? -eq 0 ]; then # Erfolg
    ...
    oder kurz:
    Code:
    if pgrep ...; then
    Die 2. Variante klappt deshalb, weil die if-Abfrage der Shell ja nur wissen will, ob der übergebene Ausdruck = 0 = OK ist (der test macht auch nix anderes - er liefert 0 zurück, wenn die Bedingung erfüllt ist). So kann Fireball22 auch vorgehen, da pgrep 1 als Returncode liefert, wenn kein Prozess die Bedingung matcht (siehe Abschnitt "EXIT STATUS" im Manual).

    Man kann natürlich auch wie von Dir vorgeschlagen vorgehen und prüfen, ob der pgrep eine PID (oder mehrere) zurückliefert. Und da liegt in Deinem Code eine Falle: Es können nämlich keine oder auch mehrere werden, und dann kriegst Du einen Syntax-Error, weil aus
    Code:
     if [ -n `pgrep -f "${path_shoutcast}/sc_serv"` ]; then
    dann sowas wird:
    Code:
    # kein Prozess gefunden
    if [ -n  ]; then
    # mehrere Prozesse gefunden
    if [ -n  0815 4711 ]; then
    Man muss also wieder tarnen:
    Code:
    # Variante 1
    if [ -n "`pgrep -f '${path_shoutcast}/sc_serv'`" ]; then
    # Variante 2
    if [ -n "`pgrep -f \"${path_shoutcast}/sc_serv\"`" ]; then
    In Variante 2 habe ich einfach die "" stehen lassen und sie nur vor der Shell versteckt, die das Teilchen zwischen den `` auswertet. Dann wird daraus nach Ausführen des in `` gepackten Kommandos:
    Code:
    # nix gefunden
    if [ -n "" ]; then
    # mehrere Treffer
    if [ -n "0815 4711" ]; then
    und die Shell (bzw. deren Vertreter test) ist zufrieden.

    Jan

  14. #44
    Registrierter Benutzer Avatar von rais
    Registriert seit
    18.07.2005
    Beiträge
    5.859
    Moin Jan,
    Danke!

    Zitat Zitat von jan61 Beitrag anzeigen
    Man kann natürlich auch wie von Dir vorgeschlagen vorgehen und prüfen, ob der pgrep eine PID (oder mehrere) zurückliefert. Und da liegt in Deinem Code eine Falle: Es können nämlich keine oder auch mehrere werden, und dann kriegst Du einen Syntax-Error, weil aus
    Code:
     if [ -n `pgrep -f "${path_shoutcast}/sc_serv"` ]; then
    dann sowas wird:
    Code:
    # kein Prozess gefunden
    if [ -n  ]; then
    # mehrere Prozesse gefunden
    if [ -n  0815 4711 ]; then
    es ist auf dieser Kiste (OpenSuSE10.2) sogar noch schlimmer: Im Fall "kein Prozess gefunden" gibt es noch nicht einmal eine Fehlermeldung... und bei beiden Fällen (kein Prozess/mehrere Prozesse gefunden) ergibt sich der falsche Status.
    Oha, da kann man sich selbst ganz schön mit reinlegen

    Das zeigt doch wieder einmal wie wichtig es beim Testen ist, wirklich alle denkbaren Szenarien durchzuspielen.

    @Fireball22: Apropos denkbare Szenarien: sollte man hier dem pgrep nicht auch die -u-Option mitgeben, damit nicht mit auf den Prozess eines anderen Benutzers gematcht wird?

    MfG,
    Rainer
    There's nothing a good whack with a hammer won't fix!

  15. #45
    Registrierter Benutzer
    Registriert seit
    17.12.2007
    Beiträge
    40
    Vielen Dank für eure ganzen Tipps und Hilfe zu meinem Problem!

    Dann wäre glaub die einzigste Methode, dass ich das ganze so prüfe, denn bei mir gibt es ja auch die Möglichkeit einen User anzugeben.

    Code:
    if [ [ `pgrep -f "${path_shoutcast}/sc_serv"` -a $use_user -eq 0 ] -o [ `pgrep -u $username -f "${path_shoutcast}/sc_serv"` -a $use_user -eq 1 ] ]; then
    #...
    fi
    So müsste ich doch dann alles in einem Abfragen könne, ob ein Prozess läuft, wenn ein bestimmter User im Script festgelegt ist, mit dem Parameter -u und ansonsten ohne bestimmte User-Angabe.
    Trifft keines der beiden Tests zu, dann wird die Fehlermeldung ausgegeben, dass der Server noch nicht gestartet ist, kann man das ganze so in der Art realisieren?

    Und leider bin ich mit diesem Problem noch nicht weitergekommen, ich komm einfach nicht drauf, wo hier das Problem eig. liegt:
    Und bezüglich des Exports:
    Ich bekomme hier beim exportieren immer diesen Fehler:

    Code:

    h852677:~# ./DeinScript_new start
    + path_shoutcast=/home/shoutcast
    + use_screen=1
    + use_user=1
    + username=shoutcast
    + '[' '!' -e /home/shoutcast/server.pid ']'
    + '[' 1 -eq 1 ']'
    + '[' 1 -eq 1 ']'
    + export /home/shoutcast
    ./DeinScript_new: line 29: export: `/home/shoutcast': not a valid identifier
    + export shoutcast
    + screen -dmS sc1 'su -c '\''/home/shoutcast/sc_serv'\'' shoutcast'
    + '[' 0 -eq 0 ']'
    + echo 11694
    + echo -ne '\033[0;32mDONE\033[0m Server wurde gestartet\n\033[0;32mDONE\033[0m PID-File wurde erfolgreich angelegt\n'
    DONE Server wurde gestartet
    DONE PID-File wurde erfolgreich angelegt
    + exit 0

    Der Code sieht so aus:

    Code:

    export $path_shoutcast
    export $username
    screen -dmS sc1 "su -c '${path_shoutcast}/sc_serv' $username"

    Ich dachte am Anfang, dass sich das mit Anführungszeichen sämtlicher Art beheben lässt, aber leider ging es auch dann noch nicht.
    Und der Server wird leider nach wie vor noch nicht gestartet... hmmm...
    MfG
    Michael

Lesezeichen

Berechtigungen

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