Ausgabe in Variable in Bash kann nicht erfasst werden

15

Probleme mit redis-cli. Ich möchte redisüber BASH prüfen, ob die Verbindung zu abgelehnt wurde (Server nicht erreichbar).

Einfacher Test

#!/bin/bash
test=$(redis-cli exit) #exit out of the "not connected console"
if [[ -z $test ]] ; then
    echo "I'm empty :("
fi

Ich würde erwarten Could not connect to Redis at 127.0.0.1:6379: Connection refused, in $ test gespeichert zu werden, aber dieser Text wird stattdessen auf der Konsole ausgegeben.

Ich bin nicht sicher, was los ist. Hat jemand irgendwelche Ideen?

(Ubuntu 14.04.1)

DarkNeuron
quelle
Beachten Sie, dass if [[ -z $test ]]an Sicherheit grenzender Wahrscheinlichkeit erweitern wird , if [[ -z ]]wenn $testleer wird, was die Bedingung wahrscheinlich zu brechen scheint. Zum Schutz gegen diese, setzen Sie einfach die Variable in Anführungszeichen: if [[ -z "$test" ]] ; then.
einen Lebenslauf vom
Ich denke tatsächlich, dass neuere Versionen von bash damit umgehen. Scheint in meinen Tests trotzdem zu funktionieren.
DarkNeuron
Na dann gut für dich. :-) Ich mag normalerweise das zusätzliche Sicherheitsnetz, wenn auch nichts anderes, um meinen Verstand beim späteren Betrachten des Codes zu bewahren ...
ein Lebenslauf vom

Antworten:

20

Dies liegt daran, dass die Fehlermeldung an den STDERR-Stream (Dateideskriptor 2) und nicht an STDOUT (Dateideskriptor 1) gesendet wird, den Sie mit der Befehlsersetzung erfassen $().

Konzentriere dich nur darauf, den String zu bekommen, entweder auf STDOUT oder STDERR:

test="$(redis-cli exit 2>&1)"

In diesem Fall führt der [ -z "$test" ]Test zu falsch positiven Ergebnissen, da die Fehlermeldung in der Variablen gespeichert wird. Stattdessen können Sie Folgendes tun:

#!/bin/bash
test="$(redis-cli exit 2>/dev/null)"
if [[ -z $test ]] ; then
    echo "I'm empty :("
fi

Auch ich denke, dies sollte bekommen, was Sie wollen, da der Exit-Status trivial ist:

if redis-cli exit &>/dev/null; then
    echo 'Succeeded!!'
else
    echo 'Failed!!'
fi
heemayl
quelle
Ah, natürlich. Es ist ein Fehler! :)
DarkNeuron
Es ist auch problematisch (wenn auch nur ein bisschen), den Namen eines eingebauten Befehls (und einer ausführbaren Datei) zu verwenden - "test" für einen Variablennamen, daher ist es besser, nur den Exit-Status wie in der zweiten Lösung zu testen dieser Grund auch.
Joe