ทำความเข้าใจกับ `echo $ ((0x63)) '


18

echo $((0x63))ผมกำลังมองหาวิธีการแปลงเลขฐานสิบหกผ่านบรรทัดคำสั่งและพบว่ามีวิธีที่ง่ายมาก

มันใช้งานได้ดี แต่ฉันสับสนเล็กน้อยกับสิ่งที่เกิดขึ้นที่นี่

ฉันรู้ว่า$(...)ปกติจะเป็น sub-shell โดยที่เนื้อหาจะถูกประเมินก่อนคำสั่ง outer

มันยังเป็น sub-shell ในสถานการณ์นี้หรือไม่? ฉันไม่คิดว่าจะหมายถึงว่า sub-shell นั้นเพิ่งจะประเมิน(0x63)ว่าไม่ใช่คำสั่ง

บางคนสามารถทำลายคำสั่งให้ฉันได้หรือไม่?

คำตอบ:


27

$(...)เป็นการทดแทนคำสั่ง (ไม่ใช่แค่ subshell) แต่$((...))เป็นการขยายเลขคณิต

เมื่อคุณใช้$((...))ที่...จะตีความได้ว่าการแสดงออกทางคณิตศาสตร์ ซึ่งหมายความว่าในกรณีอื่น ๆ ที่สตริงเลขฐานสิบหกจะถูกตีความว่าเป็นตัวเลขและแปลงเป็นทศนิยม นิพจน์ทั้งหมดจะถูกแทนที่ด้วยค่าตัวเลขที่นิพจน์ประเมิน

เช่นเดียวกับการขยายพารามิเตอร์และการแทนที่คำสั่งคุณ$((...))ควรอ้างว่าไม่ได้รับผลกระทบจากการแยกคำและเชลล์ของชื่อไฟล์

echo "$(( 0x63 ))"

จากบันทึกด้านข้างตัวแปรที่เกิดขึ้นในนิพจน์ทางคณิตศาสตร์ไม่จำเป็นต้องใช้$:

$ x=030; y=30; z=0x30
$ echo "$(( x + y +x ))"
78

2
นอกจากนี้โปรดทราบว่าเนื่องจาก$((...))ความขัดแย้งกับการทดแทนคำสั่งเราต้องจำไว้ว่าต้องเขียนecho "$( (echo x; echo y) | tr xy yx)"แทนecho "$((echo x; echo y) | tr xy yx)"(แม้ว่าเชลล์บางเชลล์จะยังคงยอมรับ YMMV หลัง)
Stéphane Chazelas

@ StéphaneChazelasและคุณ$(( ))สร้างผลผลิตที่ได้รับผลกระทบจากการแยกคำหรือการโค้งเป็นอย่างไร
Hauke ​​Laging

3
IFS=9; echo $((0x63))@HaukeLaging, ดูเพิ่มเติมนัยยะด้านความปลอดภัยของการลืมอ้างตัวแปรใน bash / POSIX shells ( What about [ $# -gt 1 ]ส่วน)
Stéphane Chazelas

3

นี่ไม่ใช่ subshell แต่เป็นการประเมินทางคณิตศาสตร์ จากman bash:

((expression))

การแสดงออกที่ถูกประเมินตามกฎที่ระบุไว้ด้านล่างภายใต้การทางคณิตศาสตร์การประเมินผล หากค่าของนิพจน์ไม่ใช่ศูนย์สถานะการส่งคืนจะเป็น 0 มิฉะนั้นสถานะการส่งคืนคือ 1 ซึ่งเทียบเท่ากับให้ "expression"


9
((...))ไม่เหมือนกัน$((...))มาก ทั้งสองทำการประเมินทางคณิตศาสตร์ แต่ตัวหลังจะถูกแทนที่ด้วยค่าผลลัพธ์เป็นสตริง
Kusalananda
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.