ไม่สามารถดักจับเอาต์พุตเป็นตัวแปรใน Bash


15

redis-cliมีปัญหากับ ฉันต้องการตรวจสอบว่าการเชื่อมต่อกับredisถูกปฏิเสธ (เซิร์ฟเวอร์ดาวน์) ผ่าน BASH หรือไม่

ทดสอบอย่างง่าย

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

ฉันคาดว่าCould not connect to Redis at 127.0.0.1:6379: Connection refusedจะถูกเก็บไว้ในการทดสอบ $ แต่ข้อความนี้จะถูกส่งออกไปยังคอนโซลแทน

ฉันไม่แน่ใจว่าเกิดอะไรขึ้น ใครมีความคิดเห็นบ้าง

(Ubuntu 14.04.1)


โปรดทราบว่าif [[ -z $test ]]จะขยายเป็นเกือบแน่นอนif [[ -z ]]เมื่อ$testว่างเปล่าซึ่งดูเหมือนว่าจะทำให้เกิดเงื่อนไข if [[ -z "$test" ]] ; thenเพื่อป้องกันการนี้เพียงแค่ใส่ตัวแปรในคำพูด:
CVn

ฉันคิดว่าทุบตีรุ่นที่ใหม่กว่าจัดการที่ ดูเหมือนว่าจะทำงานในการทดสอบของฉันต่อไป
DarkNeuron

ถ้าอย่างนั้นดีสำหรับคุณ :-) ฉันมักจะชอบตาข่ายความปลอดภัยเพิ่มเติมถ้าไม่มีอะไรอื่นที่จะรักษาสติของฉันเมื่อดูรหัสในภายหลัง ...
CVn

คำตอบ:


20

นั่นเป็นเพราะเกิดข้อผิดพลาดจะถูกส่งไปยังกระแส STDERR ข้อมูล (ไฟล์อธิบาย 2) ไม่ STDOUT (ไฟล์อธิบาย 1) $()ที่คุณจะจับกับแทนคำสั่ง

เพียงมุ่งเน้นไปที่การรับสตริงไม่ว่าจะเป็น STDOUT หรือ STDERR:

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

ในกรณีนั้น[ -z "$test" ]การทดสอบจะส่งผลให้เกิดการบวกเท็จเนื่องจากข้อผิดพลาดจะถูกเก็บไว้ในตัวแปร แต่คุณสามารถทำได้:

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

นอกจากนี้ฉันคิดว่าสิ่งนี้ควรได้รับสิ่งที่คุณต้องการเนื่องจากสถานะการออกนั้นไม่สำคัญ:

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

อ่าแน่นอน มันเป็นข้อผิดพลาด! :)
DarkNeuron

นอกจากนี้ยังขอปัญหา (ถ้าเพียงเล็กน้อย) เพื่อใช้ชื่อคำสั่งในตัว (และปฏิบัติการ) - "ทดสอบ" สำหรับชื่อตัวแปรดังนั้นเพียงทดสอบสถานะทางออกเช่นเดียวกับวิธีแก้ปัญหาที่สองจะดีกว่าสำหรับ เหตุผลนั้นเช่นกัน
โจ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.