$ echo $(date)
Thu Jul 2 16:33:11 SGT 2015
$ echo ${date}
$ name=foo
$ echo $(name)
ksh: name: not found
$ echo ${name}
foo
ดูเหมือนว่า $ {variable} จะเหมือนกับ $ variable ในขณะที่ $ () คือการดำเนินการคำสั่ง เหตุใดจึงใช้ $ {} จากนั้น
$ echo $(date)
Thu Jul 2 16:33:11 SGT 2015
$ echo ${date}
$ name=foo
$ echo $(name)
ksh: name: not found
$ echo ${name}
foo
ดูเหมือนว่า $ {variable} จะเหมือนกับ $ variable ในขณะที่ $ () คือการดำเนินการคำสั่ง เหตุใดจึงใช้ $ {} จากนั้น
คำตอบ:
$(command)
คือ "การทดแทนคำสั่ง" ในขณะที่คุณดูเหมือนจะเข้าใจมันรันcommand
, จับเอาท์พุทและแทรกเข้าไปในบรรทัดคำสั่งที่มี$(…)
; เช่น,
$ ls -ld $(date +%B).txt
-rwxr-xr-x 1 Noob Noob 867 Jul 2 11:09 July.txt
${parameter}
คือ“ การทดแทนพารามิเตอร์” ข้อมูลจำนวนมากสามารถพบได้ในหน้า man ของ shell, bash (1) , ภายใต้หัวข้อ“ Parameter Expansion ”:
${parameter}
ค่าของพารามิเตอร์ถูกแทนที่ วงเล็บปีกกาจำเป็นเมื่อพารามิเตอร์เป็นพารามิเตอร์ตำแหน่งที่มีมากกว่าหนึ่งหลักหรือเมื่อพารามิเตอร์ตามด้วยอักขระที่ไม่ควรตีความว่าเป็นส่วนหนึ่งของชื่อ
สำหรับพารามิเตอร์ตำแหน่งดู“ พารามิเตอร์ตำแหน่ง ” ด้านล่าง ในการใช้งานทั่วไปดังที่แสดงในคำตอบอื่น ๆ
parameter
เป็นชื่อตัวแปร ${…}
รูปแบบตามที่ระบุไว้ในตอนท้ายของย่อหน้าข้างต้นจะช่วยให้คุณได้รับค่าของตัวแปร (เช่น) และปฏิบัติตามได้ทันทีด้วยตัวอักษรตัวเลขหรือขีด:$variable_name
$ animal = cat $ echo $ สัตว์ # ไม่มีตัวแปรเช่น "สัตว์" $ echo $ {animal} s แมว $ echo $ animal_food # ไม่มีตัวแปรเช่น "animal_food" $ echo $ {animal} _food อาหารแมว
คุณสามารถทำสิ่งนี้ด้วยเครื่องหมายคำพูด:
$ echo "$ animal" s แมว
หรือเป็นแบบฝึกหัดในตัวเลือกคุณสามารถใช้ตัวแปรตัวที่สอง:
$ plural = s $ echo $ สัตว์ $ plural แมว
แต่นี่เป็นเพียงขั้นตอนที่ 1 ย่อหน้าถัดไปในหน้า man นั้นน่าสนใจแม้ว่าจะเป็นความลับเล็กน้อย:
หากอักขระตัวแรกของพารามิเตอร์
เป็นเครื่องหมายอัศเจรีย์ ( !
) จะมีการแนะนำระดับการเปลี่ยนทิศทางของตัวแปร Bash ใช้ค่าของตัวแปรที่เกิดขึ้นจากพารามิเตอร์ที่เหลือ
เป็นชื่อของตัวแปร จากนั้นตัวแปรนี้จะถูกขยายและค่านั้นจะถูกใช้ในการทดแทนที่เหลือแทนที่จะเป็นค่าพารามิเตอร์เอง นี้เรียกว่าการขยายตัวทางอ้อม
… (ข้อยกเว้น) …
เครื่องหมายอัศเจรีย์ต้องทำตามวงเล็บปีกกาด้านซ้ายในทันทีเพื่อแนะนำการอ้อม
ฉันไม่แน่ใจว่าฉันจะทำให้ชัดเจนขึ้นได้อย่างไรยกเว้นด้วยตัวอย่าง:
$ animal = cat $ echo $ สัตว์ แมว $ cat = tabby $ echo $ cat แมวลาย $ echo $ {! animal} tabby # หาก $ animal คือ “ cat” ดังนั้น $ {! animal} คือ $ cat นั่นคือ “ tabby”
ลองเรียกขั้นตอนที่1½กัน มีสิ่งที่น่าสนใจมากมายที่คุณสามารถทำได้ในขั้นตอนที่ 2:
$ animal = cat $ echo $ {# animal} 3 # ความยาวสตริง $ echo $ {สัตว์ / at / ow} การแทนที่วัว #
คุณไม่สามารถทำสิ่งใด ๆ เหล่านี้หากไม่มีเครื่องหมายปีกกา{
...}
พารามิเตอร์ตำแหน่ง
ลองพิจารณาตัวอย่างเทียมนี้:
$ cat myecho.sh echo $ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 $ 11 $ 12 $ 13 $ 13 $ 14 $ 15 $ ./myecho.sh เฮ้ดอดเดิลแมวและซอตัวผู้วัวกระโดดข้ามดวงจันทร์ เฮ้ด็ดด็อลแมวและซอ, เฮ้เฮ้เฮ้เฮ้เฮ้เฮ้
เพราะเปลือกไม่เข้าใจ$10
, $11
ฯลฯ ให้การปฏิบัติราวกับว่ามันเป็น$10
${1}0
แต่มันก็เข้าใจ${10}
, ${11}
ฯลฯ , ตามที่กล่าวไว้ใน man page (“ พารามิเตอร์ตำแหน่งที่มีมากกว่าหนึ่งหลัก”)
แต่อย่าเขียนสคริปต์แบบนั้นจริงๆ มีวิธีที่ดีกว่าในการจัดการกับรายการอาร์กิวเมนต์ที่ยาวนาน
ดังกล่าวข้างต้น (พร้อมกับรูปแบบอื่น ๆ อีกมากมายของโครงสร้าง) จะกล่าวถึงที่มีความยาวมากขึ้นในหน้าคนของเปลือก, ทุบตี (1)${parameter…something_else}
หมายเหตุเกี่ยวกับคำคม
โปรดทราบว่าคุณควรอ้างอิงตัวแปรเชลล์เสมอยกเว้นว่าคุณไม่มีเหตุผลที่ดีและคุณแน่ใจว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่ ในขณะที่การจัดฟันอาจมีความสำคัญ แต่ก็ไม่สำคัญเท่าคำพูด
$ filename = "สถานรับเลี้ยงเด็ก rhyme.txt" $ ls -ld $ {filename} ls: ไม่สามารถเข้าถึงสถานรับเลี้ยงเด็ก: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว ls: ไม่สามารถเข้าถึง rhyme.txt: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว $ ls -ld "$ filename" -rwxr-xr-x 1 Noob Noob 5309 ก.ค. 2 11:09 สถานรับเลี้ยงเด็ก rhyme.txt
ที่ยังใช้กับพารามิเตอร์ตำแหน่ง (เช่นอาร์กิวเมนต์บรรทัดคำสั่ง; เช่น"$1"
) และการทดแทนคำสั่ง:
$ ls -ld $ (วันที่ "+% B% Y"). txt ls: ไม่สามารถเข้าถึงกรกฎาคม: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว ls: ไม่สามารถเข้าถึง 2015.txt: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว $ ls -ld "$ (วันที่" +% B% Y "). txt" -rwxr-xr-x 1 Noob Noob 687 ก.ค. 2 11:09 กรกฎาคม 2558.txt
ดูทุบตีคำพูดที่ไม่ใช้ Escape บนแทนคำสั่ง
สำหรับตำราสั้น ๆ เกี่ยวกับการมีปฏิสัมพันธ์ระหว่างคำพูดและ...$(
)
!
ตกลงฉันเนื้อหาเกี่ยวกับการใช้งานของ
${!animal}
หมายถึงตัวแปร$cat
แทนค่า cat” จริง ๆ แล้วนั่นคือประเด็น “ / กลายเป็น“ c” ใน echo $ {สัตว์ / at / ow} อย่างไร” Huh? / at ไม่กลายเป็น "c"; “ cat” กลายเป็น“ cow” เมื่อ“ at” ถูกแทนที่ด้วย“ ow”
ในตัวอย่างของคุณ $ var และ $ {var} เหมือนกัน อย่างไรก็ตามวงเล็บปีกกาจะมีประโยชน์เมื่อคุณต้องการขยายตัวแปรในสตริง:
$ string=foo
$ echo ${string}bar
foobar
$ echo $stringbar
$
ดังนั้นวงเล็บปีกกาจึงเป็นวิธีการแทนตัวแปรเพื่อให้ได้ชื่อของตัวแปรใหม่
ฉันมักจะเห็นมันเป็นปกติในสตริง สิ่งนี้จะไม่ทำงาน:
var="a"
echo "$varRAW_STRING"
แต่จะ:
var="a"
echo "${var}RAW_STRING"
อย่างที่คุณพูดถูกต้อง$()
ใช้เพื่อรันคำสั่ง:
dir_contents=$(ls)
คุณสามารถใช้ backticks ได้ด้วย แต่ฉันพบว่ามีประโยชน์$()
หลายอย่างมากกว่า สำหรับสิ่งหนึ่ง backticks ไม่สามารถซ้อนกันได้ (ง่าย)
date_directory=`ls `date '+%Y-%m-%d'`` # Makes no sense
date_directory=$(ls $(date '+%Y-%m-%d')) # Much better
date_directory=`ls \`date '+%Y-%m-%d'\``
. แต่มันก็น่าเกลียดมาก $(…)
มีความชัดเจนและใช้งานง่ายกว่ามาก
`…`
เป็น(เท่านั้น) ไวยากรณ์สำหรับแทนคำสั่งสำหรับปีก่อนที่จะถูกคิดค้นเพื่อให้คุณไม่จำเป็นที่จะคิดอะไร - คนไม่ได้ $(…)
${
variable_name
}