Welcome, Guest. Please login or register.
Did you miss your activation email?

Author Topic: [DE] [gelöst] Werte in Array schreiben  (Read 8882 times)

Offline bluelupo

  • User
  • Posts: 2.068
    • BluelupoMe
[DE] [gelöst] Werte in Array schreiben
« on: 2014/11/06, 21:33:54 »
Hallo zusammen,
ich bin auf der Fehlersuche in diesem Shellscript. Leider komm ich nicht drauf ;-)

Aufruf: ./run_onlinetime.sh -s "2014-11-01 00:00:00" -u "2014-11-02 23:59:59"
Option -s ($SINCE )
Option -u ($UNTIL)

Code: [Select]
do_create_timestamps()
{
   # In Array Index, Datum, Zeit und absoluten Sekundenwert der Onlinezeiten schreiben
   journalctl --since="$SINCE" --until="$UNTIL" --output=short-iso --no-pager | egrep '(command line: BOOT_IMAGE|Journal stopped)' | while read JOURNAL_ROW
      do
      # ersten Wert ueberspringen wenn dieser den Wert "Journal stopped" enthält
      SKIP=`expr match "$JOURNAL_ROW" '.*Journal stopped'`
     if [ $INDEX -eq 0 -a $SKIP -ne 0 ]
        then
        continue
     fi
      TS=$(echo $JOURNAL_ROW | cut -d" " -f1|awk -F"T" '{print $1"#"$2}' | awk -F"+" '{print $1}')
      TMP=$(echo ${TS//#/ })
      TIME_IN_SEC=$(date --utc --date "$TMP" +%s)
      #echo "$INDEX"#"$TS"#"$TIME_IN_SEC"
      ARRAY_TIMESTAMP[$INDEX]=$INDEX"#"$TS"#"$TIME_IN_SEC
      INDEX=$(($INDEX + 1))
   done

for X in ${ARRAY_TIMESTAMP[@]}
   do
   echo $X
done

#Werte ausgeben
echo "Werte:"${#ARRAY_TIMESTAMP[@]}

# Anzahl der Zeilen ausgeben
echo "Anzahl der Werte:"${ARRAY_TIMESTAMP[0]}
}

Ausgabe des Scripts:
Code: [Select]
Werte:
Anzahl der Werte:0

Leider wird hier nichts in das Array "ARRAY_TIMESTAMP" geschrieben und deshalb kann auch nichts ausgegeben werden. Wieso klappt das nicht?

Kommentiere ich hingegen die Zeile ein..
Code: [Select]
echo "$INDEX"#"$TS"#"$TIME_IN_SEC"
...so werden Werte ausgegeben aber das Array ist natürlich immer noch leer. Hmmm!

Ausgabe:
Code: [Select]
0#2014-11-01#22:18:46#1414880326
1#2014-11-02#17:49:00#1414950540
2#2014-11-02#17:53:31#1414950811
3#2014-11-02#17:53:54#1414950834
4#2014-11-02#21:54:52#1414965292
Werte:
Anzahl der Werte:0

Die Zuweisung der Werte ins Array dürfte wohl fehlerhaft sein - aber ich komm nicht drauf wo der Fehler steckt.
Code: [Select]
ARRAY_TIMESTAMP[$INDEX]=$INDEX"#"$TS"#"$TIME_IN_SEC
« Last Edit: 2014/11/07, 19:21:59 by bluelupo »

Offline bluelupo

  • User
  • Posts: 2.068
    • BluelupoMe
Re: Werte in Array schreiben
« Reply #1 on: 2014/11/07, 19:21:42 »
Ich gebe mir selbst eine Antwort, da ich das Scriptproblem gelöst habe. Evtl. ist das für euch interessant wo die Probleme lagen.

Die Problematik lag bei der internen Bash-Variable IFS (internal field separator). IFS erkennt Felder- oder Wortgrenzen in der Bash.

So sieht die Funktion jetzt aus.
Code: [Select]
[...]
do_create_timestamps()
{
# Ausgabe aus dem Journal aufbereiten. Letzter awk-Befehl mit #-Trennzeichen aufbereitet, da sonst die einzelnen Spalten untereinander ausgegeben werden
for TS in $(journalctl --since="$SINCE" --until="$UNTIL" --output=short-iso --no-pager | egrep '(Kernel command line|Shutting down)' | cut -d" " -f1,4,5 | awk -F"T" '{print $1,$2}' | sed -e 's/+[0-9]\{4\}//' -e 's/\.//' | awk '{printf("%s#%s#%s%s\n",$1,$2,$3,$4)}')
do
# Wenn der erste Eintrag ein Shuttingdown ist, gehe zum nächsten Eintrag
SKIP=`expr match "$TS" '.*Shuttingdown'`
if [ $INDEX -eq 0 -a $SKIP -ne 0 ]
then
continue
fi
# einzelne Felder erzeugen und dem Array hinzufuegen
DATE=$(echo $TS | cut -d"#" -f1)
TIME=$(echo $TS | cut -d"#" -f2)
TMP=$(echo $TS | awk -F"#" '{print $1,$2}')
TIME_IN_SEC=$(date --utc --date "$TMP" +%s)
TRIGGER=$(echo $TS | cut -d"#" -f3)
ARRAY_TIMESTAMP[$INDEX]=$INDEX"#"$DATE"#"$TIME"#"$TIME_IN_SEC"#"$TRIGGER
INDEX=$(( $INDEX + 1 ))
done
}
[...]

Das Array wird dann so ausgegeben wie ich es haben will. Spaltentrenner ist der "#" mit den Feldern Index, Datum, Uhrzeit, Zeit in Sekunden seit dem 1.1.1970, Trigger für Hochfahren bzw. Herunterfahren und die Differenz-Zeiten zwischen Hoch- und Runterfahren des PC.
Code: [Select]
for ROW in ${ARRAY_TIMESTAMP[@]}
   do
   echo $ROW
done

0#2014-11-02#17:49:00#1414950540#Kernelcommand#0
1#2014-11-02#17:53:31#1414950811#Shuttingdown#271
2#2014-11-02#17:53:54#1414950834#Kernelcommand#0
3#2014-11-02#21:54:52#1414965292#Shuttingdown#14458

Der Knackpunkt liegt in der FOR-Schleife beim awk-Kommando, der mit den Feldtrenner "#" versehen werden muss ansonsten erfolgt ein falscher Zeilenumbruch und das Array wird nicht richtig aufgebaut (Spaltertrenner ist diesem Fall das Leerzeichen).

Code: [Select]
awk '{printf("%s#%s#%s%s\n",$1,$2,$3,$4)}'