Script-Problem (While)

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von worker, 27.05.2009.

  1. worker

    worker König

    Dabei seit:
    29.03.2007
    Beiträge:
    848
    Zustimmungen:
    0
    Hi Leute,

    habe hier nen prob. mit nem Script und komme seit Stunden nicht mehr weiter...

    Code:
    BEFEHL="cat $QUELLE | tail -n \"$ZEILEN\" | grep -i \""
    
    if [ "$#" -ne "0" ]; then
    
     declare -i x=1
    
     while [ $x -le $# ]
     do
    
      case "$1" in
        "fail")	BEFEHL_TMP="$BEFEHL""fail"
    		BEFEHL=$BEFEHL_TMP
    		;;
    
        "error")	BEFEHL_TMP="$BEFEHL""error"
    		BEFEHL="$BEFEHL_TMP"
    		;;
    
        *)		BEFEHL_TMP="$BEFEHL""$1"
    		BEFEHL="$BEFEHL_TMP"
    		;;
      esac
    
      if [ $x -le $# ]; then
       BEFEHL_TMP="$BEFEHL"
       BEFEHL="$BEFEHL_TMP\|"
      fi
    
      shift
    
      x=x+1
    
     done
    
     BEFEHL_TMP="$BEFEHL"
     BEFEHL="$BEFEHL_TMP\""
    
     echo "Schreibe: $BEFEHL nach $ZIEL_DATEI ..."
    
    Terminal Eingabe:
    "./syslog_output.sh fail error irgendwas"

    Ausgabe ist:
    "Schreibe: cat /var/log | tail -n "100" | grep -i "fail\|error\|" nach ./syslog_temp.txt ..."

    Frage: Warum ignoriert CASE den dritten Parameter ?

    Wenn ich insgesammt 5 Parameter übergebe, so bekomme ich in der Ausgabe, alle Parameter bis einsch. "irgendetwas" ausgegeben - die zwei restlichen Parameter werden ebenfalls "verschluckt".

    Bitte um Erleuchtung, ich bin mit meinem Latein am Ende :).

    Thx & Gruß
    W.
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 bytepool, 27.05.2009
    bytepool

    bytepool Code Monkey

    Dabei seit:
    12.07.2003
    Beiträge:
    791
    Zustimmungen:
    0
    Ort:
    /home/sweden/göteborg
    Hi,

    nach stundenlangem Nachdenken bist du nicht auf die Idee gekommen dir mal die Variablen ausgeben zu lassen? ;)

    Der blosse Quelltext hat mir zum Fehlerfinden auch nicht gereicht, aber wenn du dir mal die Variablen ausgeben laesst, ist die Sache ziemlich eindeutig: shift dekrementiert auch $#, d.h. du musst einfach am Anfang noch ein "declare -i count=$#" hinzufuegen, und die zwei if statements entsprechend anpassen, und dein Problem hat sich gegessen. ;)

    mfg,
    bytepool
     
  4. worker

    worker König

    Dabei seit:
    29.03.2007
    Beiträge:
    848
    Zustimmungen:
    0
    Ach!
    Ich bin ja ein Hirnochse !!!
    Ja, danke Dir ;-)

    Gruß
    W.
     
  5. #4 worker, 28.05.2009
    Zuletzt bearbeitet: 28.05.2009
    worker

    worker König

    Dabei seit:
    29.03.2007
    Beiträge:
    848
    Zustimmungen:
    0
    Muss nochmal wegen dem Script, aber anderem Problem nachhacken ...

    Hier das komplette Script:
    Code:
    #!/bin/bash
    
    # Syslog-Output:
    # --------------
    
    QUELLE="/var/log/syslog"
    ZIEL_DATEI="./syslog_temp.txt"
    ZEILEN="100" # Letzten n-Zeilen ausgeben
    
    BEFEHL="/bin/cat $QUELLE | tail -n $ZEILEN | grep -i \""
    
    # Wenn Parameter angegeben:
    if [ "$#" -ne "0" ]; then
    
     declare -i x=$#
    
     # Solange Parameter vorhanden, dann in Variable "BEFEHL" speichern:
     while [ "$x" -ne "0" ]
     do
    
      case "$1" in
        *)		BEFEHL_TMP="$BEFEHL""$1"
    		BEFEHL="$BEFEHL_TMP"
    		;;
      esac
    
      if [ "$x" -ne "1" ]; then
       BEFEHL_TMP="$BEFEHL"
       BEFEHL="$BEFEHL_TMP\|"
      fi
    
      shift
    
      x=x-1
    
     done
    
     # Variable "BEFEHL" abschliessen:
     BEFEHL_TMP="$BEFEHL\""
     BEFEHL="$BEFEHL_TMP > $ZIEL_DATEI"
    
     # Variable "BEFEHL" 'ausführbar' machen:
     #BEFEHL_TMP="$BEFEHL"
     #BEFEHL="\`$BEFEHL_TMP\`"
     
     echo "Schreibe: $BEFEHL ..." 
     `$BEFEHL`
    
    else
     #Wenn keine Parameter angegeben:
     cat "$QUELLE" | tail -n "$ZEILEN" > "$ZIEL_DATEI"
    fi
    
    exit
    Ich erhalte ich als Ausgabe:
    Code:
    Schreibe: /bin/cat /var/log/syslog | tail -n 100 | grep -i "fail\|error\|sonstwas" > ./syslog_temp.txt ...
    /bin/cat: Ungültige Option -- i
    „/bin/cat --help“ gibt weitere Informationen.
    
    Leider bringt das "back quoten" nicht viel. Auch nicht, wenn ich die Dinger
    in die Variable mit eingebe (escaped). Bei nicht-escaped back quotas, meckert
    bash, dass kein Abschluss da ist. Es er aber, aber halt erst nach dem kompletten
    IF-Block, nur das merkt bash nicht.

    Woran liegt das ? Wie kann ich das Problem lösen ?

    Thx
    W.

    EDIT: Auch mit $(Variable) klappt es nich, weil sie "zerstückelt" ist (IF-Block).
     
  6. #5 HeadCrash, 28.05.2009
    HeadCrash

    HeadCrash Routinier

    Dabei seit:
    16.05.2009
    Beiträge:
    482
    Zustimmungen:
    1
    Ort:
    Bayern
    Hi

    ich habe das mal ein bisschen umgeschreiben, wirklich verstehn tu ichs allerdings auch nicht.

    Sieht so aus als aktzeptiert die pipe nciht und will das "-i" cat zuordnen


    Code:
    #!/bin/bash
    
    # Syslog-Output:
    # --------------
    
    QUELLE="/var/log/syslog"
    ZIEL_DATEI="./syslog_temp.txt"
    ZEILEN="100" # Letzten n-Zeilen ausgeben
    
    #BEFEHL="/bin/cat $QUELLE | tail -n $ZEILEN | grep -i \""
    BEFEHL_help="/usr/bin/tail -n $ZEILEN $QUELLE"
    BEFEHL="grep -i \""
    
    # Wenn Parameter angegeben:
    if [ "$#" -ne "0" ]; then
    
     declare -i x=$#
    
     # Solange Parameter vorhanden, dann in Variable "BEFEHL" speichern:
     while [ "$x" -ne "0" ]
     do
    
      case "$1" in
        *)          BEFEHL_TMP="$BEFEHL""$1"
                    BEFEHL="$BEFEHL_TMP"
                    ;;
      esac
    
      if [ "$x" -ne "1" ]; then
       BEFEHL_TMP="$BEFEHL"
       BEFEHL="$BEFEHL_TMP\|"
      fi
    
      shift
    
      x=x-1
    
     done
    
     # Variable "BEFEHL" abschliessen:
     BEFEHL_TMP="$BEFEHL\""
     BEFEHL="$BEFEHL_TMP"
    
     # Variable "BEFEHL" 'ausführbar' machen:
     #BEFEHL_TMP="$BEFEHL"
     #BEFEHL="\`$BEFEHL_TMP\`"
    
     echo "Schreibe: ${BEFEHL_help} | ${BEFEHL} > $ZIEL_DATEI "
     ${BEFEHL_help} | ${BEFEHL} > $ZIEL_DATEI
    
    else
     #Wenn keine Parameter angegeben:
     cat "$QUELLE" | tail -n "$ZEILEN" > "$ZIEL_DATEI"
    fi
    
    exit
    
    
     
  7. worker

    worker König

    Dabei seit:
    29.03.2007
    Beiträge:
    848
    Zustimmungen:
    0
    Ok,

    vielen Dank HeadCrash.
    ... verstehen tue ich das auch nicht.

    Gruß
    W.
     
  8. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  9. #7 floyd62, 28.05.2009
    Zuletzt bearbeitet: 28.05.2009
    floyd62

    floyd62 Routinier

    Dabei seit:
    01.05.2007
    Beiträge:
    309
    Zustimmungen:
    0
    Hi worker,

    wenn ich das richtig verstehe, willst du die letzten 100 Zeilen vom syslog lesen, und die entweder komplett ausgeben, oder, falls Argumente übergeben werden, davon nur die Zeilen ausfiltern, in denen (ohne Berücksichtigung von Gross-/Kleinschreibung) irgendeines der angegebenen Schlüsselwörter enthalten ist.

    WENN das so stimmt, dann könnte man das ganz einfach etwa so lösen:
    Code:
    #!/bin/bash
    
    
    QUELLE="/var/log/syslog"
    ZIEL="syslog_temp.txt"
    ZEILEN=100
    
    FILTER=""
    while [ "$1" ]; do
            FILTER="${FILTER:+$FILTER|}$1"
            # echo "$FILTER"
            shift
    done
    
    eval "tail -n $ZEILEN $QUELLE | ( [ \"$FILTER\" ] && egrep -i \"$FILTER\" || cat - ) >$ZIEL"
    
    Das Problem in deinem Code ist relativ einfach zu sehen, wenn du das ganze mal mit "bash -x ..." ausführst: da kommt dann irgendetwas raus wie
    Code:
    + echo 'Schreibe: /bin/cat /var/log/syslog | tail -n 100 | grep -i "zzz" > ./syslog_temp.txt ...'
    Schreibe: /bin/cat /var/log/syslog | tail -n 100 | grep -i "zzz" > ./syslog_temp.txt ...
    ++ /bin/cat /var/log/syslog '|' tail -n 100 '|' grep -i '"zzz"' '>' ./syslog_temp.txt
    /bin/cat: invalid option -- i
    Try `/bin/cat --help' for more information.
    + exit
    
    In der Zeile, in der der /bin/cat ausgeführt wird, werden die '|'-Zeichen in Quotes angezeigt. Das heisst, dass die eben nicht als Pipes von der Shell ausgewertet, sondern (wegen der überflüssigen Backslashes beim Zusammenbau) als Argumente (Strings) an den cat übergeben werden. Damit bekommt cat auch alles andere als Argument übergeben, eben auch das "-i", das ja eigentlich an den grep gehen sollte ...

    Noch zwei abschliessende Bemerkungen am Rande:

    - die backticks bei der Ausführung gehören weg; ein einfaches $BEFEHL (oder ggf. 'eval "$BEFEHL"') sollte reichen, da sonst $BEFEHL einmal ausgeführt wird, und der String, den dieser Befehl evtl. zurückliefert, dann nochmal als Kommando ausgewertet würde.

    - bei mir funktioniert "grep" nur mit fixen Strings; wenn ich also eine Liste von Patterns, die durch Pipes getrennt sind, angeben will, muss ich "egrep" verwenden.

    HTH; Grüsse,
    A.
     
  10. worker

    worker König

    Dabei seit:
    29.03.2007
    Beiträge:
    848
    Zustimmungen:
    0
    Hallo floyd62,

    Klasse Code & klasse Erklärung!!
    Ein "heavyges" Dankeschön für beides :-) !

    Gruß
    W.
     
Thema:

Script-Problem (While)

Die Seite wird geladen...

Script-Problem (While) - Ähnliche Themen

  1. [Gelöst] PostScript-Probleme

    [Gelöst] PostScript-Probleme: Drucker: Kyocera Mita FS-1010 Cups: 2.1 PPD: Kyocera Mita FS-1010 (German) Fehlerausgabe beim Drucken der Testseite (Druckausgabe): ERROR:...
  2. Denkfehler, oder was? iptables Script-Problem

    Denkfehler, oder was? iptables Script-Problem: Hi Leute, Ich möchte gern einen Rechner mit ner Firewall schützen. Ich selbst möchte aber alle Port nach aussen offen haben. Führe ich das...
  3. Miniscript-Problem

    Miniscript-Problem: Hallo ich habe mir mehrere kleien Scripte (sind im prinzip nur Dar Kommandos) zum Sichern von mehreren / geschrieben. Hier mal ein...