ในเชลล์สคริปต์ถ้าฉันกำหนดตัวแปรเช่นFOO=25
มีความแตกต่างระหว่างการอ้างอิงเป็น$FOO$
และ${FOO}$
?
ในเชลล์สคริปต์ถ้าฉันกำหนดตัวแปรเช่นFOO=25
มีความแตกต่างระหว่างการอ้างอิงเป็น$FOO$
และ${FOO}$
?
คำตอบ:
ในสถานการณ์ส่วนใหญ่ทั้งสอง$var
และ${var}
เหมือนกัน (โปรดทราบว่าคุณจะต้องไม่ใช้$
ท้าย!)
ตัวอย่างหนึ่งที่คุณต้องการวงเล็บปีกกาคือเมื่อคุณต้องการใส่ตัวแปรในสายอักขระต่อเนื่อง
ตัวอย่าง:
var=hel
echo ${var}lo
hello
ออกจะ
ที่จะตอบคำถามหลักของคุณ${foo}
เรียกว่า"การขยายตัวพารามิเตอร์" เพื่อความแม่นยำ$
ตัวเองจะเริ่มการขยายตัวของพารามิเตอร์ตัว{ }
เลือกจริงตามข้อกำหนด POSIXแต่มีประโยชน์ในการระบุจุดสิ้นสุดของชื่อตัวแปร:
$ foo="bar"
$ echo $fooBaz ## fails, no variable named $fooBaz exists
$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz
โดยทั่วไป$foo
และ${foo}
เหมือนกัน นอกเหนือจากกรณีเช่นข้างต้นหรือเมื่อคุณทำการจัดการสตริงพวกเขาจะเทียบเท่าอย่างสมบูรณ์
อย่างไรก็ตามคุณไม่ควรใช้อย่างใดอย่างหนึ่ง กฎของหัวแม่มือคือว่ามีข้อยกเว้นน้อยมากที่คุณควรเสมอใช้"$foo"
หรือ"${foo}"
และไม่เคยหรือ$foo
${foo}
คุณควรอ้างอิงตัวแปรของคุณเสมอเพื่อหลีกเลี่ยงการเรียกใช้ตัวดำเนินการแยก + glob (เพิ่มเติมในภายหลัง) $foo$
แน่นอนคุณไม่ต้องการ รอบชิงชนะเลิศ$
ไม่เกี่ยวข้อง:
$ foo="bar"
$ echo "$foo$"
bar$
ดังนั้นในขณะที่ตัวแปร unquote บางครั้งก็โอเค:
$ echo $foo
bar
พวกเขามักจะไม่และควรหลีกเลี่ยงจริง ๆ :
$ if [ -n $foo ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "$foo" ]; then echo empty; else echo "not empty"; fi ## works
not empty
โปรดทราบว่าวงเล็บไม่ได้ช่วยที่นี่:
$ if [ -n ${foo} ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "${foo}" ]; then echo empty; else echo "not empty"; fi ## works
not empty
เมื่อคุณใช้$foo
หรือ${foo}
เชลล์จะแบ่งค่าที่บันทึกไว้ในตัวแปรในช่องว่าง (ซึ่งสามารถเปลี่ยนแปลงได้โดยการตั้งค่าIFS
ตัวแปรเป็นอย่างอื่น) ลงในรายการจากนั้นแต่ละองค์ประกอบของรายการจะถือว่าเป็นรูปแบบกลมและขยายเป็น ไฟล์หรือไดเรกทอรีที่ตรงกัน นี้เป็นที่รู้จักกันแยก + globผู้ประกอบการ หากต้องการแสดงตัวอย่างให้พิจารณาไดเร็กทอรีที่มีสองไฟล์:
$ ls -l
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file1
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file2
ตอนนี้เรามาตั้งค่าตัวแปรเป็นfoo *
:
$ foo="foo *"
จะเกิดอะไรขึ้นถ้าเราพยายามตรวจสอบว่ามีไฟล์ชื่อนั้นอยู่หรือไม่?
$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists
ตัวแปรถูกแบ่งออกเป็นfoo
และ*
เนื่องจาก*
เป็น wildcard ที่ตรงกับสตริงใด ๆ เชลล์จะบอกคุณว่าไฟล์ชื่อfoo *
exxists อย่างไรก็ตามหากเราพูดอย่างถูกต้องสิ่งนี้จะไม่เกิดขึ้น:
$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file
นั่นเป็นตัวอย่างเล็กน้อยเพื่อแสดงจุด ลองคิดดูหากผมใช้rm
แทนecho
แม้ว่า
ดังนั้นกฎข้อแรก: อ้างอิงตัวแปรของคุณเสมอ คุณสามารถใช้อย่างใดอย่างหนึ่ง"$foo"
หรือ"${foo}"
แต่อ้างอิงมันด้วยวิธีใดวิธีหนึ่ง สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการใช้ตัวแปรอย่างปลอดภัยดูที่โพสต์เหล่านี้:
$ var="foo *"
จะเป็น$ foo="foo *"
? คุณไม่ได้ใช้var
ทุกที่
$
ในที่สุด! มันจะถือว่าเป็นตัวอักษรปกติและไม่เป็นส่วนหนึ่งของชื่อตัวแปร