Script-Problem (While)

worker

worker

König
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.
 
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
 
Ach!
Ich bin ja ein Hirnochse !!!
Ja, danke Dir ;-)

Gruß
W.
 
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).
 
Zuletzt bearbeitet:
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
 
Ok,

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

Gruß
W.
 
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.
 
Zuletzt bearbeitet:
Hallo floyd62,

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

Gruß
W.
 

Ähnliche Themen

Switche abfragen über Script

script sshpass

Verschlüsseltes Backup-Script mit rsync

Crontab und Scripts - Problem

Port generieren, wenn nicht dann

Zurück
Oben