ฉันกำลังอ่านสคริปต์ทุบตีฉันไม่เข้าใจว่าเกิดอะไรขึ้น
#!/bin/sh
[ x$1 = x ]
เกิดอะไรขึ้นกับบรรทัดที่สองและ[ x$1 = x ] หมายถึงอะไร
ฉันกำลังอ่านสคริปต์ทุบตีฉันไม่เข้าใจว่าเกิดอะไรขึ้น
#!/bin/sh
[ x$1 = x ]
เกิดอะไรขึ้นกับบรรทัดที่สองและ[ x$1 = x ] หมายถึงอะไร
คำตอบ:
การตรวจสอบนั้น$1ว่างเปล่าแม้ว่ามันควรจะยกมา (เหมือนกัน[ -z "$1" ]) เชลล์ที่เก่ามากบางตัวไม่ได้จัดการกับสตริงว่างอย่างถูกต้องดังนั้นผู้เขียนสคริปต์แบบพกพาจึงใช้การตรวจสอบรูปแบบนี้ มันไม่จำเป็นสำหรับทศวรรษ แต่คนยังคงทำเช่นนั้นเพราะคนยังคงทำเช่นนั้น
[ x$1 = x ]ยังคงไม่ถูกต้อง แต่[ "x$1" = x ]จะใช้สำหรับเชลล์ที่มีปัญหาซึ่ง$1อยู่!หรือ(หรือ-n.... [ "" = "$1" ]และcase $1 in "")ก็อาจใช้ได้เช่นกัน
[ -z "$1" ]และ[ "$1" = "" ]ยังไม่สามารถใช้งานได้กับ / bin / sh ของ Solaris 10 ซึ่งเป็นรุ่นเดิมที่มีเส้นประ -5.4
[ "$1" = "" ]ยังไม่สามารถใช้งานได้/bin/sh(แม้ว่าคุณต้องการใช้งานที่/usr/xpg4/bin/shนั่นไม่ใช่/bin/sh) เส้นประได้รับการแก้ไขในเรื่องนั้นในเดือนมกราคม 2009
วงเล็บเหลี่ยมบ่งบอกถึงการทดสอบดังนั้น[ x$1 = x]โดยไม่มีifหรือสิ่งที่คล้ายกันนั้นไม่มีความหมาย
มันหมายถึงการประเมินว่าเป็นจริงหากx$1ขยายไปxและผิดเป็นอย่างอื่น แต่เนื่องจากไม่ได้ระบุไว้หาก$1เป็น (เช่น) "เฮ้ x" เชลล์จะเห็นx = xดังนั้นการก่อสร้างนี้จึงไม่ปลอดภัย
วัตถุประสงค์ของการx = xตรวจสอบคือการตรวจสอบว่าตัวแปรว่างเปล่า วิธีทั่วไปในการทำเช่นนี้คือเพียงใช้เครื่องหมายคำพูด:
if [ "$1" = "" ]; then
ผู้ประกอบการทดสอบทุบตี-zและ-nยังสามารถนำมาใช้ แต่พวกเขาจะน้อยพกพาไปยังเปลือกประเภทอื่น ๆ 1
เหตุผลของราคาหรือx$1คือเพื่อให้ด้านซ้ายไม่ขยายไปเป็นอะไรซึ่งจะเป็นข้อผิดพลาดทางไวยากรณ์:
if [ = x ] # No good!
if [ "" = "" ] # Okay.
if [ x = x ] # Also okay.
1. จริงๆแล้วtestสามารถเป็นยูทิลิตี้แบบสแตนด์อโลน แต่เชลล์ส่วนใหญ่จะใช้มันเป็นแบบในตัว ตรวจสอบความแตกต่างระหว่างและwhich test type testบน GNU / Linux man testการเรียกร้องในการอ้างถึงในตัว แต่ถ้าคุณโทร (เช่น) /usr/bin/test, ยูทิลิตี้ที่ดูเหมือนว่าจะดำเนินการมีการบันทึกไว้ในหน้าคนรวมทั้งและ-z-n
[ x$1 = x ]จะประเมินผลเป็นจริง$1เช่น" -o x"กัน ลองsh -xc '[ x$1 = x ] && echo yes' sh ' -o x'ดู [ x$1 = x ]ผิดและไม่สมเหตุสมผล
ifไปใช้งานที่testคุณสามารถใช้มันก่อน &&, ||หรือหลังwhileหรือตรวจสอบผลการใช้$?
[ x$1 = x ]
เข้าท่าzshเท่านั้น ที่เปรียบเทียบเรียงต่อกันของกับอาร์กิวเมนต์แรกของสคริปต์เพื่อx xดังนั้น[คำสั่งจะคืนค่าจริงถ้า$1ว่างหรือไม่ได้จัดเตรียมไว้
[ $1 = "" ]
จะไม่ทำงานเพราะในzshเมื่อตัวแปรว่างไม่ได้ถูกยกมาในบริบทรายการมันจะขยายเป็นไม่มีอาร์กิวเมนต์เลยแทนที่จะเป็นอาร์กิวเมนต์ว่างดังนั้นถ้าไม่$1ได้ตั้งค่าหรือว่างเปล่า[คำสั่งจะได้รับเป็นอาร์กิวเมนต์[เท่านั้น=สตริงว่าง และ]สิ่งที่มันไม่สมเหตุสมผล [ -z "$1" ]หรือ[ "$1" = "" ]จะโอเคเหมือนใน POSIX เชลล์
ในกระสุน Bourne-like / POSIX [ x$1 = x ]ไม่สมเหตุสมผล นั่นคือตัวดำเนินการแยก + glob นำไปใช้กับการต่อกันxและอาร์กิวเมนต์แรกของสคริปต์โดยหวังว่าผลลัพธ์และ=และxและ]ทำนิพจน์ทดสอบที่ถูกต้องสำหรับ[คำสั่ง
ตัวอย่างเช่นถ้าสคริปต์ที่ถูกส่งผ่านไปหนึ่ง" = x -o x ="อาร์กิวเมนต์[จะได้รับข้อโต้แย้งเหล่านั้น[, x, =, x, -o, x, =, x, ]ซึ่ง[จะเข้าใจเปรียบเทียบxกับxและxมีxและกลับจริง
ถ้า$1เป็น"* *"เช่นนั้นเชลล์จะส่งรายการ[คำสั่งของไฟล์ในไดเรกทอรีปัจจุบันที่ชื่อขึ้นต้นด้วยx(การขยายตัวกลมของx*) จากนั้นรายการของไฟล์ที่ไม่ซ่อน (การขยาย*) ... ซึ่ง[ไม่น่าจะสามารถทำได้ เพื่อทำให้ความรู้สึกใด ๆ ออกมาจาก กรณีเดียวที่จะทำทุกอย่างที่เหมาะสมคือถ้า$1ไม่มีอักขระตัวแทนหรืออักขระว่าง
ตอนนี้สิ่งที่คุณพบบางครั้งก็คือรหัสเช่น:
[ "x$1" = x ]
ที่ใช้ในการทดสอบว่า$1ว่างเปล่าหรือไม่มีการตั้งค่า
วิธีปกติในการทดสอบตัวแปรว่างหรือไม่ได้ตั้งค่าคือ:
[ -z "$1" ]
แต่ที่ล้มเหลวสำหรับบางค่า$1ชอบ=ในการใช้งานบางอย่าง (ไม่ใช่ POSIX) [เช่น builtin หนึ่งในเชลล์เป้าหมายที่พบ/bin/shใน Solaris 10 และก่อนหน้านี้หรือบางรุ่นเก่าdash(สูงถึง 0.5.4) หรือ BSD shบางรุ่น
นั่นเป็นเพราะ[เห็น[, -z, =, ]และบ่นเกี่ยวกับข้อโต้แย้งไปยัง=ผู้ประกอบการไบนารีแทนของการทำความเข้าใจว่ามันเป็น-zผู้ประกอบการเอกนำไปใช้กับ=สตริง
ในทำนองเดียวกัน[ "$1" = "" ]ล้มเหลวสำหรับการใช้งานบางอย่าง[ถ้า$1เป็นหรือ!(
ในเชลล์ / [การนำไปใช้งาน:
[ "x$1" = x ]
เป็นการทดสอบที่ถูกต้องเสมอโดยไม่คำนึงถึงค่าของ$1เช่น:
[ "" = "$1" ]
และ:
[ -z "${1:+x}" ]
และ
case $1 in "") ...; esac
แน่นอนถ้าคุณต้องการตรวจสอบว่าไม่มีการโต้แย้งใด ๆ คุณต้อง:
[ "$#" -eq 0 ]
นั่นคือคุณตรวจสอบจำนวนข้อโต้แย้งที่ส่งผ่านไปยังสคริปต์
โปรดทราบว่าในปัจจุบัน[ -z "$var" ]มีการระบุอย่างชัดเจนโดย POSIX และไม่สามารถล้มเหลวในการที่สอดคล้องกับ[การใช้งาน (และbashก็[เป็นและได้รับมานานหลายทศวรรษ) ดังนั้นคุณควรจะbashเชื่อถือได้ใน POSIX sh หรือสคริปต์
x$1กำลังเชื่อมโยงสองสตริงxและ$1และถ้า $ 1 ว่างเปล่า x $ 1 เท่ากับ x และ [x $ 1 = x] จะเป็นจริงตามผลลัพธ์ x = yใช้ในการเปรียบเทียบสตริงใน sh
x$1อ้างถึงดังนั้นการแยกและการโค้งจะทำกับสิ่งเหล่านั้น
[ x$1 = x ]เป็นจริงถ้า$1unset / null / ว่างเปล่าหรือไม่
ลองด้วยตัวคุณเอง:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
และ
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"
[ x$1 = x ]ก็เป็นความจริง$1เช่น" -o x"กัน ลองsh -xc '[ x$1 = x ] && echo yes' sh ' -o x'ดู [ x$1 = x ]ผิดและไม่สมเหตุสมผล