อักขระชื่อฟังก์ชันที่ถูกต้องของเชลล์


13

การใช้อักขระ Unicode แบบขยาย (ไม่มีข้อสงสัย) มีประโยชน์สำหรับผู้ใช้หลายคน

เชลล์ที่ง่ายกว่า (ash (busybox), dash) และ ksh ล้มเหลวด้วย:

tést() { echo 34; }

tést

แต่ , , และดูเหมือนจะอนุญาต

ฉันทราบว่าชื่อฟังก์ชันที่ถูกต้อง POSIX ใช้นิยามของชื่อนี้ นั่นหมายถึง regex นี้:

[a-zA-Z_][a-zA-Z0-9_]*

อย่างไรก็ตามในลิงค์แรกมันยังกล่าวว่า:

การใช้งานอาจอนุญาตให้ตัวละครอื่น ๆ ในชื่อฟังก์ชั่นเป็นส่วนขยาย

คำถามคือ:

  • สิ่งนี้ได้รับการยอมรับและจัดทำเป็นเอกสารหรือไม่?
  • ที่ไหน?
  • เปลือกหอยไหน (ถ้ามี)?

คำถามที่เกี่ยวข้อง:
เป็นไปได้ใช้อักขระพิเศษในชื่อฟังก์ชันเปลือก?
ฉันไม่สนใจที่จะใช้เมตาอักขระ (>) ในชื่อฟังก์ชัน

ชื่อฟังก์ชันพุ่งพรวดและทุบตีที่มี“ -”
ฉันไม่เชื่อว่าตัวดำเนินการ (การลบ "-") ควรเป็นส่วนหนึ่งของชื่อ


คุณอาจพบว่าaliasสุภาพกว่านี้ และเพื่อให้คุณสามารถเขียนฟังก์ชั่นด้วยชื่อที่เหมาะสมและมีปุ่มติดตั้งจากนั้นก็กำหนดชื่อนามแฝงที่มีสไตล์มากขึ้นเพื่อเรียกใช้ฟังก์ชัน ในdashนอกจากนี้ยังมีบางสิ่งที่คุณสามารถทำได้ด้วยและ$PATH %func
mikeserv

คำตอบ:


16

เนื่องจากเอกสารประกอบ POSIX อนุญาตให้เป็นส่วนเสริมจึงไม่มีสิ่งใดป้องกันการใช้งานจากพฤติกรรมดังกล่าว

เช็คง่าย (วิ่งเข้าzsh):

$ for shell in /bin/*sh 'busybox sh'; do
    printf '[%s]\n' $shell
    $=shell -c 'á() { :; }'
  done
[/bin/ash]
/bin/ash: 1: Syntax error: Bad function name
[/bin/bash]
[/bin/dash]
/bin/dash: 1: Syntax error: Bad function name
[/bin/ksh]
[/bin/lksh]
[/bin/mksh]
[/bin/pdksh]
[/bin/posh]
/bin/posh: á: invalid function name
[/bin/yash]
[/bin/zsh]
[busybox sh]
sh: syntax error: bad function name

แสดงให้เห็นว่าbash, zsh, yash, ksh93(ซึ่งkshเชื่อมโยงกับระบบของฉัน) pdkshและแหล่งที่มาของมันช่วยให้หลายไบต์ตัวละครเป็นชื่อฟังก์ชั่น

yash ถูกออกแบบมาเพื่อรองรับอักขระหลายไบต์ตั้งแต่เริ่มต้นดังนั้นจึงไม่แปลกใจที่มันจะทำงาน

เอกสารอื่น ๆ ที่คุณสามารถอ้างถึงคือksh93:

ช่องว่างคือแท็บหรือช่องว่าง ตัวระบุคือลำดับของตัวอักษรตัวเลขหรือขีดล่างที่ขึ้นต้นด้วยตัวอักษรหรือขีดล่าง ตัวระบุถูกใช้เป็นส่วนประกอบของชื่อตัวแปร vname คือลำดับของตัวระบุอย่างน้อยหนึ่งตัวคั่นด้วย a และนำหน้าทางเลือกโดย .. Vnames จะใช้เป็นชื่อฟังก์ชั่นและตัวแปร คำคือลำดับของอักขระจากชุดอักขระที่กำหนดโดยโลแคลปัจจุบันไม่รวมอักขระเมตาที่ไม่ยกมา

ดังนั้นการตั้งค่าCสถานที่:

$ export LC_ALL=C
$ á() { echo 1; }
ksh: á: invalid function name

ทำให้มันล้มเหลว


poshไม่คุ้มที่จะอยู่ในรายการดังกล่าว มันขึ้นอยู่กับบั๊กเฉพาะของ Linux libcและจะไม่ทำงานบนแพลตฟอร์มอื่น
schily

ฉันไม่สามารถอ้างสิทธิ์ซ้ำของคุณเกี่ยวกับการksh93ใช้ ksh93 ที่คอมไพล์ด้วยตนเองจากแหล่งดั้งเดิม ในขณะที่ksh88ดูเหมือนว่าจะยอมรับตัวอักษรที่ไม่ใช่ 7-Bit-ASCII สำหรับชื่อฟังก์ชั่นเฉพาะksh93ไบนารีจาก Ubuntu ดูเหมือนว่าจะยอมรับพวกเขา
schily

@schily KSH ผมใช้ในการทดสอบนี้เป็นไบนารีใน Debian (เพื่อมันอาจจะเหมือนกันกับหนึ่งบน Ubuntu)
cuonglm

9

โปรดทราบว่าฟังก์ชั่นแชร์เนมสเปซเดียวกันกับคำสั่งอื่น ๆ รวมถึงคำสั่งในระบบไฟล์ซึ่งในระบบส่วนใหญ่ไม่มีข้อ จำกัด เกี่ยวกับตัวอักขระหรือแม้กระทั่งไบต์ที่อาจมีอยู่ในพา ธ

ดังนั้นในขณะที่กระสุนส่วนใหญ่ จำกัด ตัวละครของฟังก์ชั่นของพวกเขาไม่มีเหตุผลที่ดีว่าทำไมพวกเขาถึงทำอย่างนั้น นั่นหมายความว่าในเชลล์เหล่านั้นมีคำสั่งที่คุณไม่สามารถแทนที่ด้วยฟังก์ชันได้

zshและrcอนุญาตอะไรก็ได้สำหรับชื่อฟังก์ชั่นรวมถึงบางอย่างด้วย/และสตริงว่าง zshแม้อนุญาตให้ NUL ไบต์

$ zsh
$ $'\0'() echo nul
$ ^@
nul
$ ""() uname
$ ''
Linux
$ /bin/ls() echo test
$ /bin/ls
test

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

ที่นี่ไม่มีปัญหาด้านความปลอดภัยเนื่องจากฟังก์ชั่นที่คุณ (ผู้เขียนสคริปต์) กำหนดนั้นเป็นสิ่งที่คุณเรียกใช้

ในกรณีที่อาจมีปัญหาด้านความปลอดภัยคือเมื่อการวิเคราะห์คำได้รับผลกระทบจากสภาพแวดล้อมเช่นกับเชลล์ที่ชื่อที่ถูกต้องสำหรับฟังก์ชั่นได้รับผลกระทบจากสถานที่เกิดเหตุ


หนึ่งอาจจะเล่นเกมในทุบตีเกินไปที่เริ่มต้นด้วยfunction /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }และอาจสิ่งที่มีประโยชน์เกินไปกับฟังก์ชั่นการตั้งชื่อ--, //, @หรือ%อื่น ๆ
mr.spuratic

แต่อย่าเชลล์มีแนวโน้มที่จะข้ามการค้นหาตารางแฮชเมื่อ/พบในชื่อ? และฟังก์ชั่นไม่ได้เป็นเพียงชื่อที่ปฏิบัติการได้ - โค้ดของมัน ฉันคิดว่าการใช้งานที่ง่ายอาจประสบปัญหาการแยกวิเคราะห์ได้มากมายหากชื่อฟังก์ชันที่เก็บไว้รวมถึงตัวอักษร
mikeserv

ใช่ฉันรู้ว่าไม่สามารถทุบตีเพื่อให้มีค่าโมฆะใน vars ซึ่งสามารถขยายไปยังชื่อฟังก์ชันได้อย่างสมเหตุสมผล ฉันไม่ได้มีตัวอย่างที่เฉพาะเจาะจง แต่ฉันรู้สึกว่าเกมที่ให้ชื่อเกือบทุกอย่างนี้มีความเสี่ยงต่อการละเมิดความปลอดภัยมากกว่า "วิธีง่าย ๆ ในการทำงาน" ฉันหวังว่าฉันผิด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.