เหตุใด $ {$ #} จึงให้ผลลัพธ์แบบเดียวกันกับ $$ ในเชลล์


18

ขณะที่พยายามที่จะได้รับที่ผ่านมาชุดพารามิเตอร์ตำแหน่งในฉันได้พยายาม/bin/dash echo ${$#}น่าแปลกที่นี่ไม่ได้ส่งผลให้เกิดข้อผิดพลาด แต่เป็น PID ซึ่งเหมือนกับ$$เนื้อหาตัวแปร คำถามทำไมไวยากรณ์นั้นถึงใช้ได้? กฎไวยากรณ์ที่เชลล์ใช้ในที่นี้คืออะไร

โดยทั่วไปสิ่งที่ฉันทำคือ

$ set 1 2 3 4 5
$ echo ${$#}
13819
$ echo $$
13819

เห็นได้ชัดว่า%ตัวละครยังได้รับการละเว้นในโครงสร้างดังกล่าว

$ echo ${$%}
13819

แต่*และ@ส่งผลให้เกิดข้อผิดพลาดในการทดแทนที่ไม่ดี:

$ echo ${$*}
sh: 10: Bad substitution
$ echo ${$@}
sh: 11: Bad substitution

3
คุณคาดหวัง${$*}และ${$@}ผลิตอะไร
Kusalananda

2
@ Kusalananda ไม่มีความคาดหวัง ฉันลองตัวละครอื่นข้าง ๆ#และ%พฤติกรรมอะไรที่เป็นผลมาจากสิ่งเหล่านั้น
Sergiy Kolodyazhnyy

1
ทำจริงร้ายใน Dash, การใช้งานเช่นeval dash -c 'set 1 2 3 4 5; eval "echo \$$#"'ที่มา: Ubuntu Wiki
wjandrea

1
@wjandrea ใช่แล้วทราบถึงสิ่งนั้นแล้ว มีคำถามจริงเกี่ยวกับเรื่องนี้แล้ว: stackoverflow.com/questions/1853946/… ฉันพยายามหาวิธีด้วยตัวเองโดยไม่อ่านคำถามก่อน (และฉันรู้แล้วว่าfor i; do true; doneจะนำสิ่งของชิ้นสุดท้ายเข้าไป$i) แต่มองหาอะไรที่หรูหรากว่า evalแน่นอนสามารถมีปัญหาที่อาจเกิดขึ้นคิดว่าขอบเขต - นั่นเป็นหัวข้ออื่น แต่ใช่มันเป็นตัวเลือก
Sergiy Kolodyazhnyy

คำตอบ:


35

นี่คือ$$ การลบคำนำหน้าว่างเปล่า :

${parameter#[word]}

นำรูปแบบขนาดเล็กที่สุดในคำนำหน้า คำจะได้รับการขยายการผลิตรูปแบบ จากนั้นการขยายพารามิเตอร์จะส่งผลให้เกิดพารามิเตอร์โดยส่วนที่เล็กที่สุดของคำนำหน้าตรงกับรูปแบบที่ถูกลบ หากมีอยู่คำจะไม่เริ่มต้นด้วยคำที่ไม่ได้ยก#มา

เช่นเดียวกับ%(ต่อท้าย) @และ*ไม่ใช่ตัวดัดแปลงส่วนขยายพารามิเตอร์ดังนั้นจึงเป็นข้อผิดพลาด มันจะเกิดขึ้น$?, $-หรือสมมุติ$=เช่นกัน ${$+}เป็นการขยายที่ว่างเปล่า


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