Pertanyaan Tidak dapat menangkap keluaran menjadi variabel dalam Bash


Kesulitan dengan redis-cli. Saya ingin memeriksa apakah koneksi ke redis ditolak (server down), melalui BASH.

Tes sederhana

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

Saya harapkan Could not connect to Redis at 127.0.0.1:6379: Connection refused untuk disimpan dalam $ test, tetapi teks ini dikeluarkan ke konsol sebagai gantinya.

Saya tidak yakin apa yang terjadi. Ada yang punya ide?

(Ubuntu 14.04.1)


14
2017-08-16 13:37


asal


Perhatikan itu if [[ -z $test ]] hampir pasti akan memperluas ke if [[ -z ]] kapan $test menjadi kosong, yang tampaknya akan merusak kondisional. Untuk melindungi terhadap ini, cukup cantumkan variabel dalam tanda kutip: if [[ -z "$test" ]] ; then. - Michael Kjörling
Saya benar-benar berpikir bahwa versi terbaru dari bash menangani itu. Tampaknya bekerja di tes saya juga. - DarkNeuron
Kalau begitu, baik untukmu. :-) Saya cenderung menyukai jaring pengaman tambahan, jika tidak ada yang lain untuk menjaga kewarasan saya ketika melihat kode nanti ... - Michael Kjörling


Jawaban:


Itu karena pesan kesalahan sedang dikirim ke aliran STDERR (file descriptor 2), bukan STDOUT (file descriptor 1) yang Anda ambil dengan substitusi perintah $().

Hanya berfokus pada mendapatkan string, baik pada STDOUT atau STDERR:

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

dalam hal ini [ -z "$test" ] tes akan menghasilkan kesalahan positif karena pesan kesalahan akan disimpan dalam variabel. Sebagai gantinya Anda dapat melakukan:

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

Juga saya pikir, ini harus mendapatkan apa yang Anda inginkan karena status keluarnya sepele:

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

18
2017-08-16 13:47



Ah, tentu saja. Itu kesalahan! :) - DarkNeuron
Juga, itu meminta masalah (jika hanya sedikit) untuk menggunakan nama perintah built-in (dan dapat dieksekusi) - "test" untuk nama variabel, jadi hanya menguji status keluar seperti pada solusi kedua lebih baik untuk alasan itu juga. - Joe