ทดสอบว่าตัวแปรว่างในเชลล์สคริปต์หรือไม่


27

ฉันได้เห็นเทคนิคต่อไปนี้ใช้หลายครั้งในหลาย ๆ เชลล์เพื่อทดสอบว่าตัวแปรว่างเปล่าหรือไม่:

if [ "x$1" = "x" ]; then 
    # Variable is empty
fi

มีข้อได้เปรียบอะไรบ้างในการใช้สิ่งนี้มากกว่าที่ยอมรับมากกว่านี้if [ -z "$1" ]? มันอาจเป็นปัญหาการพกพาหรือไม่?

คำตอบ:


17

เชลล์เชิงประวัติบางตัวใช้ตัวแยกวิเคราะห์แบบง่าย ๆ ที่อาจสับสนโดยสิ่ง[ -n = "" ]ที่ตัวถูกดำเนินการตัวแรก=ดูเหมือนกับตัวดำเนินการและจะแยกวิเคราะห์สิ่งนี้เป็น[ -n = ]สาเหตุของข้อผิดพลาดทางไวยากรณ์ ใน[ "x$1" = x"" ]ที่xมั่นใจคำนำหน้าว่าx"$1"ไม่อาจมีลักษณะเช่นผู้ประกอบการและดังนั้นวิธีเดียวที่เปลือกสามารถแยกการทดสอบนี้คือการรักษา=เป็นผู้ประกอบการไบนารี

เชลล์ที่ทันสมัยทั้งหมดและแม้กระทั่งเชลล์ที่เก่าที่สุดส่วนใหญ่ยังทำงานอยู่ให้ปฏิบัติตามกฎ POSIXซึ่งกำหนดว่าการทดสอบการแสดงออกทั้งหมดถึง 4 คำจะถูกวิเคราะห์อย่างถูกต้อง ดังนั้น[ -z "$1" ]วิธีที่เหมาะสมในการทดสอบ$1คือถ้าว่างเปล่าและ[ "$x" = "$y" ]เป็นวิธีที่เหมาะสมในการทดสอบความเท่าเทียมกันของตัวแปรสองตัว

แม้บางหอยปัจจุบันสามารถทำให้เกิดความสับสนกับการแสดงออกอีกต่อไปและการแสดงออกไม่กี่คลุมเครือจริงเพื่อหลีกเลี่ยงการใช้-aและ-oผู้ประกอบการที่จะสร้างการทดสอบแบบบูลอีกต่อไปและใช้แทนสายที่แยกต่างหากเพื่อ[และเปลือกของตัวเอง&&และ||ผู้ประกอบการบูลีน


3
มันไม่ใช่แค่เปลือกหอยประวัติศาสตร์ ksh88 บางตัวอ้างอิงจากshUnices เชิงพาณิชย์บางส่วนที่ยังมีปัญหาอยู่ ดูรายละเอียดที่นี่
Stéphane Chazelas

คำสั่งนี้ไม่ถูกต้อง: [ -z "$1" ]เป็นวิธีการที่เหมาะสมของการทดสอบถ้า$1เป็นที่ว่างเปล่า sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'- ทั้งคู่คืนค่า 0 แต่ในกรณีที่สอง$1จะต้องไม่ว่างเปล่าเนื่องจากไม่มีอยู่
mikeserv


3

การทดสอบด้านบนจะทำให้เกิดข้อผิดพลาดหากคุณเรียกใช้ด้วย "set -u" หรือ "set -o nounset"

วิธีที่มีเสถียรภาพมากขึ้นในการตรวจสอบตัวแปรว่างเปล่าคือใช้การขยายพารามิเตอร์ :

MYVAR = $ {MYVAR: - "ราคาไม่ดี"}

วิธีนี้ใช้ได้กับเชลล์ bourne แบบดั้งเดิมรวมถึง ksh และ bash


2
ฉันเชื่อว่านี่ถูกเขียนเป็น -> M = $ {M: - "ราคาไม่ดี"}
Gyan

0
    function isBlank {
 valueNoSpaces=$(echo "$@" | tr -d ' ')

 if [  "$valueNoSpaces" == null ] || [ -z "$valueNoSpaces" ] 
 then
       echo true ;
 else
       echo ""  ;
 fi
}

#Test
if [ $(isBlank "      ") ] 
then
    echo "isBlank \"      \" : it's blank"
else
    echo " isBlank \"      \": it is not blank"
fi

if [ $(isBlank "abc") ] 

then
    echo "isBlank \"abc\" : it's blank"
else
    echo "isBlank \"abc\" :it is not blank"
fi

if [ $(isBlank null) ] 
then
      echo "isBlank null : it's blank"
else
    echo "isBlank null : it is not blank"
fi

if [ $(isBlank "") ] 
then
    echo "isBlank \"\" : it's blank"
else
    echo "isBlank \"\" : it is not blank"
fi

#Result
isBlank "      " : it's blank

isBlank "abc" :it is not blank

isBlank null : it's blank

isBlank "" : it's blank

3
Hi! ฉันไม่แน่ใจว่าวิธีนี้ตอบคำถามซึ่งถามว่าทำไมถึงใช้=กับ-zตอนนี้อย่างไร
dhag
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.