2012-06-19 2 views
5

Redis: 2.0.4, 2.4.1, ...Redis: Wer isst mein Feld, wenn Piping llen Ergebnisse durch awk?

Ich werde ein Nagios-Plugin schreiben, um die Länge einer Liste zu überprüfen. Hier mein Skript ist:

#!/bin/sh 

help() 
{ 
    echo "Usage: $0 <host> <port> <key> -w <warning> -c <critical>" 
} 

case "$1" in 
    --help) 
     help 
     exit 
     ;; 
esac 

if [ $# -eq 0 ]; then 
    help 
    exit 3 
fi 
if [ $# -ne "7" ]; then 
    help 
    exit 4 
fi 
if [ $4 !="-w" -o $6 !="-c" ]; then 
    help 
    exit 5 
fi 

REDIS_CLI="/usr/local/redis/bin/redis-cli" 
LLEN=`$REDIS_CLI -h $1 -p $2 llen $3 | awk '{ print $2 }'` 
if [ $LLEN -lt $5 ]; then 
    echo "$3.llen:$2 OK - $LLEN | $3.llen:$2=$LLEN;$5;$7" 
    exit 0 
elif [ $LLEN -ge $5 -a $LLEN -lt $7 ]; then 
    echo "$3.llen:$2 WARNING - $LLEN | $3.llen:$2=$LLEN;$5;$7" 
    exit 1 
elif [ $LLEN -ge "$7" ]; then 
    echo "$3.llen:$2 CRITICAL - $LLEN | $3.llen:$2=$LLEN;$5;$7" 
    exit 2 
fi 

aber ich bekam die folgende Fehlermeldung, wenn /usr/lib64/nagios/plugins/redis_llen.sh 192.168.5.201 2468 -w 90000 -c 100000 ausgeführt wird:

/usr/lib64/nagios/plugins/redis_llen.sh: line 31: [: -lt: unary operator expected 
/usr/lib64/nagios/plugins/redis_llen.sh: line 34: [: too many arguments 
/usr/lib64/nagios/plugins/redis_llen.sh: line 37: [: -ge: unary operator expected 

es im Debug-Modus ausgeführt wird, fand ich, dass die LLEN ‚s-Wert ist ... leer. Da die llen queue_1 kehrt das richtige Ergebnis:

# /usr/local/redis/bin/redis-cli -h 192.168.5.201 -p 2468 llen queue_1 
(integer) 965 

warum die Pipeline meine Felder schlucken? (Nicht nur auf awk sondern auch echo, tee, ...):

# /usr/local/redis/bin/redis-cli -h 192.168.5.201 -p 2468 llen queue_1 | \ 
awk '{ print $0 }' 
961 

ich die Anzahl der Felder überprüfen und die entsprechenden als Behelfslösung drucken:

| awk '{ if (NF == 2) print $2; else print $1 }'` 

aber ich möchte wirklich Wissen warum passiert das? Gibt es ein Null- oder Sonderzeichen zwischen (interger) und der Nummer?

PS: es scheint, dass einige andere Redis-Version (für e.x: 1.3.7) dieses Problem nicht bekommen.

+0

Sie scheinen, wie Sie weiß über Shell-Debugging, hast du "-vx" gesetzt, ja? Ist dies nicht der Fall, fügen Sie den Befehl in der Nähe des Skriptanfangs hinzu, um die Ausführungsverfolgung und die Werte der Variablen nach der Auswertung anzuzeigen. AUCH können Sie '| verwenden cat -vet wird bei Bedarf angehängt, um einige der in Ihrer Pipeline enthaltenen Ctrl-Zeichen zu sehen (nur als Hilfestellung für das Debugging einzelner Code-Hunderter, wie Sie am Ende Ihrer Frage zeigen). Ein möglicher Verdächtiger, '^ M' das DOS '\ r'CR-Zeichen. Viel Glück. – shellter

+0

Wie ich oben sagte, sehe ich den Wert von LLEN leer ist, wenn im Debug-Modus ausgeführt wird. '| cat -vet gibt auch nur die Nummer zurück. Ich bin sicher, dass es in meiner Datei kein '^ M' gibt (weil es auf dem Linux-Rechner geschrieben wurde). Sie können nur den Befehl "redis-cli" auf Ihrer eigenen Maschine testen, um zu sehen, was passiert. – quanta

Antwort

8

Was passiert, ist redis-cli Auswahl verschiedener Ausgänge je nachdem, was STDOUT ist. Wenn STDOUT ein TTY ist, wird redis-cli mit seiner "Standard" -Formatierung ausgegeben. Andernfalls wird die „rohe“ Formatierung ist die Standardeinstellung:

--raw   Use raw formatting for replies (default when STDOUT is not a tty) 

Wie Sie aus der Hilfe zu sehen, oder die oben können Sie --raw angeben, immer es ausgegeben haben das „rohe“ Format (ohne Typ-Qualifikation, etc.) . Was ich dabei herausgefunden habe, ist, dass es auch einen CSV-Modus gibt, der redis-cli --csv verwendet.

Edit: Um den "Standard" Ausgabe zu erzwingen, auch wenn STDOUT kein TTY ist, können Sie die Umgebungsvariable FAKETTY:

FAKETTY=1 redis-cli llen some_list | awk '{ print $2 }' 

Oder

redis-cli --raw llen some_list | awk '{ print $1 }' 
+0

+1 für FAKETTY. – quanta