รหัสต่อไปนี้ออกพร้อมกับข้อผิดพลาดตัวแปร unbound จะแก้ไขได้อย่างไรในขณะที่ยังใช้set -o
ตัวเลือก nounset อยู่
#!/bin/bash
set -o nounset
if [ ! -z ${WHATEVER} ];
then echo "yo"
fi
echo "whatever"
รหัสต่อไปนี้ออกพร้อมกับข้อผิดพลาดตัวแปร unbound จะแก้ไขได้อย่างไรในขณะที่ยังใช้set -o
ตัวเลือก nounset อยู่
#!/bin/bash
set -o nounset
if [ ! -z ${WHATEVER} ];
then echo "yo"
fi
echo "whatever"
คำตอบ:
#!/bin/bash
set -o nounset
VALUE=${WHATEVER:-}
if [ ! -z ${VALUE} ];
then echo "yo"
fi
echo "whatever"
ในกรณีนี้VALUE
จะกลายเป็นสตริงว่างหากWHATEVER
ไม่ได้ตั้งค่าไว้ เรากำลังใช้ส่วน{parameter:-word}
ขยายซึ่งคุณสามารถค้นหาได้ในman bash
"การขยายพารามิเตอร์"
:-
ตรวจสอบว่าตัวแปรไม่ได้ตั้งค่าหรือว่างเปล่า หากคุณต้องการที่จะตรวจสอบเฉพาะไม่ว่าจะเป็นไม่มีการตั้งค่าการใช้งาน:-
VALUE=${WHATEVER-}
นอกจากนี้วิธีตรวจสอบว่าตัวแปรว่างเปล่า:if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
$WHATEVER
มีเพียงช่องว่าง - ดูคำตอบของฉัน
! -z
" แทน just " -n
" หรือไม่?
คุณต้องอ้างตัวแปรหากคุณต้องการได้ผลลัพธ์ที่คุณคาดหวัง:
check() {
if [ -n "${WHATEVER-}" ]
then
echo 'not empty'
elif [ "${WHATEVER+defined}" = defined ]
then
echo 'empty but defined'
else
echo 'unset'
fi
}
ทดสอบ:
$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER=' '
$ check
not empty
"info bash"
, "${WHATEVER-}"
ควรมี":"
(ลำไส้ใหญ่) ก่อน"-"
(เส้นประ) ที่ชอบ: "${WHATEVER:-}"
และ"${WHATEVER+defined}"
ควรจะมีลำไส้ใหญ่ก่อน"+"
(บวก) "${WHATEVER:+defined}"
เช่น: สำหรับฉันมันได้ผลทั้งสองวิธีโดยมีหรือไม่มีลำไส้ใหญ่ ในบางเวอร์ชันของ 'nix อาจใช้ไม่ได้หากไม่มีเครื่องหมายจุดคู่ดังนั้นจึงควรเพิ่มเข้าไป
-
, +
, :+
และ:-
ได้รับการสนับสนุนทั้งหมด อดีตตรวจสอบว่าตัวแปรที่มีการตั้งค่าและหลังตรวจสอบไม่ว่าจะเป็นการตั้งค่าหรือเปล่า From man bash
: "การละเว้นลำไส้ใหญ่จะส่งผลให้เกิดการทดสอบเฉพาะสำหรับพารามิเตอร์ที่ไม่ได้ตั้งค่า"
แล้ว oneliner ล่ะ?
[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
-z
ตรวจสอบทั้งตัวแปรว่างหรือไม่ได้ตั้งค่า
-z
ตรวจสอบเฉพาะว่าพารามิเตอร์ถัดไปว่างเปล่า -z
เป็นเพียงข้อโต้แย้งของ[
คำสั่ง การขยายตัวแปรเกิดขึ้นก่อนที่[ -z
จะทำอะไรได้
สมมติฐาน:
$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset
หากคุณต้องการให้สคริปต์ที่ไม่ใช่แบบโต้ตอบพิมพ์ข้อผิดพลาดและออกหากตัวแปรเป็นโมฆะหรือไม่ได้ตั้งค่า:
$ [[ "${HOME:?}" ]]
$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set
$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set
หากคุณไม่ต้องการให้สคริปต์ออก:
$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."
$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
คุณยังสามารถใช้[
และ]
แทน[[
และ]]
สูงกว่าได้ แต่แบบหลังจะดีกว่าใน Bash
สังเกตสิ่งที่ลำไส้ใหญ่ทำข้างต้น จากเอกสาร :
อีกวิธีหนึ่งถ้ารวมโคลอนตัวดำเนินการจะทดสอบการมีอยู่ของพารามิเตอร์ทั้งสองและค่าของมันไม่เป็นโมฆะ ถ้าไม่ใส่เครื่องหมายทวิภาคตัวดำเนินการจะทดสอบเฉพาะการมีอยู่
เห็นได้ชัดว่าไม่มีความจำเป็นสำหรับ -n
-z
หรือ
โดยสรุปฉันมักจะใช้แค่[[ "${VAR:?}" ]]
. ตามตัวอย่างนี้จะพิมพ์ข้อผิดพลาดและออกหากตัวแปรเป็นโมฆะหรือไม่ได้ตั้งค่า
คุณสามารถใช้ได้
if [[ ${WHATEVER:+$WHATEVER} ]]; then
แต่
if [[ "${WHATEVER:+isset}" == "isset" ]]; then
อาจจะอ่านได้มากขึ้น
=
ไม่ใช่==
เพื่อช่วยในการพกพาและ[
แทนที่จะใช้[[
ถ้าเป็นไปได้
set -o nounset
การทุบตีโดยเฉพาะ หากคุณใส่ไว้#!/bin/bash
ที่ด้านบนสุดของสคริปต์ควรใช้การปรับปรุงของ bash
ขณะนี้ไม่ว่ากรณีการใช้งานถามข้างต้นผมได้พบว่าถ้าคุณต้องการที่จะใช้nounset
(หรือ-u
) พฤติกรรมเริ่มต้นคือคนที่คุณต้องการที่จะออกจากการเป็นศูนย์ที่มีข้อความที่สื่อความหมาย
ฉันใช้เวลานานพอที่จะตระหนักได้ว่าฉันคิดว่ามันคุ้มค่าที่จะโพสต์เป็นวิธีแก้
หากสิ่งที่คุณต้องการคือการสะท้อนอย่างอื่นเมื่อออกหรือทำการล้างข้อมูลคุณสามารถใช้กับดัก
ตัว:-
ดำเนินการอาจเป็นสิ่งที่คุณต้องการเป็นอย่างอื่น