Nie można przechwycić danych wyjściowych do zmiennej w Bash


15

Kłopoty z redis-cli. Chcę sprawdzić, czy połączenie redisjest odrzucone (serwer nie działa), przez BASH.

Prosty test

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

Oczekiwałbym, Could not connect to Redis at 127.0.0.1:6379: Connection refusedże będę przechowywany w teście $, ale ten tekst jest zamiast tego wysyłany do konsoli.

Nie jestem pewien, co się dzieje. Czy ktoś ma jakieś pomysły?

(Ubuntu 14.04.1)


Zauważ, że if [[ -z $test ]]prawie na pewno rozszerzy się, if [[ -z ]]kiedy stanie $testsię pusty, co wydaje się prawdopodobnie złamać warunek. Aby zabezpieczyć się przed tym, po prostu umieścić zmienną w cudzysłowie: if [[ -z "$test" ]] ; then.
CVn

Właściwie myślę, że nowsze wersje bash sobie z tym radzą. W każdym razie wydaje się, że zadziała w moich testach.
DarkNeuron

Dobrze więc dla ciebie. :-) Zwykle podoba mi się dodatkowa siatka bezpieczeństwa, jeśli nic innego, aby zachować moje zdrowie psychiczne, gdy patrzę na kod później ...
CVn

Odpowiedzi:


20

Jest tak, ponieważ komunikat o błędzie jest wysyłany do strumienia STDERR (deskryptor pliku 2), a nie STDOUT (deskryptor pliku 1), który przechwytujesz za pomocą podstawiania poleceń $().

Skupiając się na pobieraniu ciągu, albo na STDOUT, albo na STDERR:

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

w takim przypadku wynik [ -z "$test" ]testu będzie fałszywie dodatni, ponieważ komunikat o błędzie zostanie zapisany w zmiennej. Zamiast tego możesz:

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

Myślę też, że powinno to uzyskać to, czego oczekujesz, ponieważ status wyjścia jest trywialny:

if redis-cli exit &>/dev/null; then
    echo 'Succeeded!!'
else
    echo 'Failed!!'
fi

Ach, oczywiście. To błąd! :)
DarkNeuron

Prosi także o kłopoty (choćby trochę) z użyciem nazwy wbudowanej komendy (i pliku wykonywalnego) - „test” dla nazwy zmiennej, więc po prostu testowanie statusu wyjścia, jak w drugim rozwiązaniu, jest lepsze dla także z tego powodu.
Joe,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.