วิธีบังคับให้คำ Bash อ้างอิงนามแฝงฟังก์ชันไฟล์และอื่น ๆ


13

เมื่อพยายามที่จะเพิ่มรายละเอียดให้กับคำถามที่เกี่ยวข้องฉันรู้ว่าฉันไม่ทราบวิธีระบุประเภทคำ Bash ที่มีอยู่เพื่อดำเนินการ ตามที่help typeมีห้าประเภทคำ:

  • นามแฝง
  • คำสำคัญ
  • ฟังก์ชัน
  • builtin
  • ไฟล์

เป็นไปได้สำหรับคำที่มีหลายประเภท ( trueเป็นเพียงตัวอย่าง; คำที่ถูกเขียนทับมากกว่าปกติcd):

$ type -a true
true is a shell builtin
true is /bin/true

คุณจะบังคับให้มีการใช้งานคำพ้องความหมายเฉพาะได้อย่างไร จนถึงตอนนี้ตามลำดับความสำคัญ:

  • นามแฝง: นี่เป็นกรณีพิเศษเนื่องจากมีความสำคัญกว่าคำพ้องอื่น ๆ ทั้งหมด การบังคับใช้สิ่งนี้จะเป็นประโยชน์เมื่อคำสั่งควรล้มเหลวหากไม่ได้กำหนดนามแฝง

    $ 
  • คำสำคัญ:

    $ 
  • ฟังก์ชั่น:

    $ 
  • builtin:

    $ builtin true
  • ไฟล์:

    $ command true
    $ $(which true)
    $ /bin/true

โซลูชันบางส่วน :

  • การอ้างคำไม่รวมชื่อแทนและคำหลัก นั่นคือ,

    $ 'true'

    จะเรียกใช้เฉพาะฟังก์ชัน builtin หรือไฟล์

คำตอบ:


10

สิ่งที่คุณถามไม่สมเหตุสมผลจริงๆ

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

เป็นไปได้ที่จะใช้นามแฝงของคีย์เวิร์ดในเชลล์ส่วนใหญ่ ดังนั้นนามแฝงจึงมีความสำคัญเหนือกว่าคำหลัก (เนื่องจากมีการขยายก่อนและมีโทเค็นมากขึ้นหลังจากที่คุณสามารถมีชื่อแทนคำหลักเพิ่มเติม) ...

นามแฝง (ที่มีข้อยกเว้นของนามแฝง zsh ที่กำหนดด้วยalias -gจะถูกขยายในตำแหน่งคำสั่งเท่านั้น) ดังนั้นโดยทั่วไปจะไม่เข้าbuiltin the-aliasมา

ฟังก์ชั่นมีความสำคัญมากกว่า builtins และ builtins เหนือคำสั่งภายนอก (แล้ว$PATHตัดสินใจว่าจะใช้อันไหน)

คุณสามารถบังคับ builtin ด้วย:

builtin the-cmd and its args

(แม้ว่ามันควรจะสังเกตว่ามันไม่ใช่คำสั่งมาตรฐาน)

คุณสามารถปิดการใช้งานนามแฝงโดยอ้างอิงพวกเขา (แม้ว่ารุ่นที่ยกมาอาจเป็นนามแฝงในบางเชลล์)

ตัวอย่างเช่น (นี่คือไวยากรณ์ zsh) ใน:

'while'() echo function while
alias 'while=echo alias while'

การเขียนwhile trueจะส่งออกจริงalias while trueและจะไม่มีวิธีการใช้whileคำหลักเนื่องจากการอ้างถึงมันจะปิดการใช้งานทั้งชื่อแทนและคำหลัก

คุณจะเรียกใช้whileฟังก์ชันด้วยเช่น:

'whi'le whatever

หากมีwhilebuiltin (แต่แน่นอนว่าพวกเขาจะไม่อยู่ใน shell เหล่านั้นที่มีwhileคีย์เวิร์ด) คุณต้องเขียนมัน:

builtin while whatever

และเพื่อเรียกwhileคำสั่งคุณจะเขียน:

env while whatever

หรือในzsh(เมื่อไม่ได้อยู่ในการshแข่งขัน):

command while whatever 

(ในเชลล์อื่น ๆ , commandป้องกันเฉพาะฟังก์ชั่น, ไม่ใช่บิวอิน)

หรือ

/full/path/to/while whatever

แน่นอนไม่มีอะไรหยุดยั้งไม่ให้คุณทำสิ่งที่ยิ่งใหญ่กว่าเช่น:

alias 'while=while "w"hile; do'
"while"() { while "whi"le; done; }

ซึ่งอย่างน้อยใน zsh ถูกต้อง (แต่โง่)


การออกคำสั่งไม่แสดงชื่อแทนและcommand ระงับการค้นหาฟังก์ชัน แต่ไม่มีการระบุสิ่งใดในคำพ้องความหมายที่เหลืออยู่ที่จะใช้ ฉันกำลังมองหาวิธีที่จะระบุให้ใช้คำพ้องความหมายเฉพาะเท่านั้น
l0b0

@ l0b0 "คำสั่ง" ไม่แสดง alias, keyword และ builtin ทั้งหมด
Stéphane Chazelas

สำหรับการทำความเข้าใจbuiltinจะใช้ในตัวอย่างRVMเพื่อแทนที่cdผลที่ดี
l0b0

คุณถูก; และฉันเพิ่งตรวจสอบว่ามันยังยับยั้งฟังก์ชั่น +1
l0b0

0

สำนวนที่มีประโยชน์มากสำหรับฉันคือ:

FALSE=1; TRUE=0
DEVEL_FLAG=$FALSE
...
in_development() { return $DEVEL_FLAG ; }
cd()
{
 if in_development ; then # -D argument to script toggles development flag
   echo "Would run cd $*"
  else
   builtin cd "$@"
 fi
}

ตอนนี้ถ้าฉันรันสคริปต์ด้วย -D ที่ระบุโหมดการพัฒนาจะถูกเปิดใช้งานและ cd (หรือคำสั่งที่ถูกล้อมอื่น) echoes debug info

สิ่งนี้มีประโยชน์อย่างยิ่งกับสคริปต์ที่รัน ssh แน่นอนว่าฉันสามารถสลับการตั้งค่า -x ได้ แต่สิ่งนี้มีประโยชน์และอ่านง่ายกว่าสำหรับฉัน


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