ฉันกำลังอ่านสคริปต์ทุบตีฉันไม่เข้าใจว่าเกิดอะไรขึ้น
#!/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 ]
เป็นจริงถ้า$1
unset / 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 ]
ผิดและไม่สมเหตุสมผล