คำสั่งของ executables เริ่มต้นด้วยการทุบตี


14

ถ้าฉันรันtestคำสั่งใน bash testยูทิลิตี้ในตัว (ประเมินนิพจน์แบบมีเงื่อนไข) จะเริ่มขึ้น:

$ type test
test is a shell builtin
$ type -a test
test is a shell builtin
test is /usr/local/bin/test
test is /usr/bin/test
$ 

อย่างไรก็ตามดังที่เห็นในผลลัพธ์ของtype -a testข้างต้นมีอีกหนึ่งtestในไดเรกทอรี / usr / local / bin และอีกหนึ่งในไดเรกทอรี / usr / bin สั่งซื้อไฟล์เอ็กซีคิ้วท์ได้อย่างไรคือคำสั่งในตัวที่ต้องการเสมอแล้วคำสั่งที่เหลือจะขึ้นอยู่กับลำดับของไดเรกทอรีในตัวแปร $ PATH นอกจากนี้เป็นไปได้หรือไม่ที่จะเปลี่ยนลำดับของโปรแกรมเริ่มทำงานเช่นถ้าฉันพิมพ์ระบบtestจะเริ่ม / usr / bin / test แทน bash-builtin testหรือไม่


คุณสามารถระบุเส้นทางแบบเต็มเมื่อเรียกใช้คำสั่งเช่น., /usr/bin/test -f "$file"...
jasonwryan

@ jasonwryan ฉันรู้เรื่องนี้แล้ว แต่ฉันแค่สนใจว่ามีวิธีที่จะเปลี่ยนลำดับของโปรแกรมที่เริ่มทำงานได้หรือไม่
Martin

คำตอบ:


25

ลำดับความสำคัญสูงสุดคือนามแฝงทุบตีแล้ว builtins พิเศษ (เฉพาะในโหมด POSIX) แล้วฟังก์ชั่นแล้ว builtins $PATHแล้วค้นหาใน

builtin testในการดำเนินการในตัวใช้ เพื่อรันโปรแกรมภายนอกใช้เส้นทางที่ชัดเจน:
ที่จะไม่สนใจฟังก์ชั่นและชื่อแทนการใช้ หากต้องการข้ามเพียงนามแฝงให้ใช้หรือขยายอื่น ๆ/bin/test
command test
\test

มันเป็นไปได้ที่จะเปิด / enable testปิดในตัวด้วย

(อัปเดตตามความคิดเห็นด้านล่าง)
(แก้ไขผู้ดูแลระบบที่ไม่ถูกต้องแก้ไขว่าทุบตีมีdisableอยู่แล้วในความเป็นจริงมีเพียงenable)


1
@ 1_CR gena2x ถูกต้อง คำตอบของฉันไม่ได้สร้าง builtins พิเศษซึ่งมีความสำคัญเหนือกว่าฟังก์ชั่นตาม POSIX (แม้ว่าบางเชลล์ไม่เข้ากันได้; bash เป็นไปตามโหมด POSIX เท่านั้น)
Gilles 'หยุดชั่วร้าย'

1
แนะนำแก้ไข: นามแฝงจะถูกปิดการใช้งานเมื่อคุณพูดคำสั่ง (หรือส่วนหนึ่งส่วนใด) ในขณะที่\testหรือหรือ'test' tes't'
John Kugelman

2
นั่นไม่ใช่ภาพเต็ม ดูเหมือนว่าการขยายตัวใด ๆ (ในคู่มือทุบตีการทดแทนทั้งหมดการขยายตัวหนอนและอื่น ๆ ที่เรียกว่าการขยายตัว ) ปิดการใช้งานนามแฝง ฉันเหนื่อย.
gena2x

1
อ้างจากหน้าคนทุบตี.:. "คำแรกของคำสั่งง่ายๆแต่ละถ้า unquoted, มีการตรวจสอบเพื่อดูว่ามันมีนามแฝงถ้าเป็นเช่นนั้นคำว่าจะถูกแทนที่ด้วยข้อความของนามแฝงตัวละคร/, $, backtick และ=และอักขระเมตาอักขระหรือข้อความที่อ้างถึงในรายการด้านบนอาจไม่ปรากฏในชื่อนามแฝง "
John Kugelman

2
+1 สำหรับคำแนะนำในการช่วยฉันค้นหาแหล่งที่มาของข้อมูลนี้: อยู่ในหน้า bash man ภายใต้ส่วนคำสั่งการดำเนินการย่อหน้าที่สองและสาม
twan163

6

คำสั่งในตัวมักใช้กับคำสั่งภายนอกเสมอ เหตุผลคือคำสั่งในตัวเร็วขึ้น (และในบางกรณีเช่นcdหรือเฉพาะคำสั่งในตัวเท่านั้นที่สามารถมีผลที่ต้องการ)test -o BASH_OPTION

บางครั้งคำสั่งภายนอกอาจมีความสามารถที่เชลล์บิวด์อินไม่มี ในกรณีดังกล่าวคุณสามารถเรียกคำสั่งภายนอกโดยกำหนดเส้นทางที่ชัดเจน (เช่นมีเครื่องหมายทับ) (สิ่งนี้จะข้ามข้อกังวลใด ๆ เกี่ยวกับลำดับใน$PATH) หากคุณไม่ต้องการโค้ดฮาร์ดไดรฟ์ภายนอก แต่ต้องการป้องกันการใช้ builtin คุณสามารถใช้"$(type -P test)"(ตัวพิมพ์ใหญ่P) ใน bash, "$(whence -p test)"ksh และ=testzsh อีกวิธีในการบังคับใช้คำสั่งภายนอกคือการใช้commandbuiltin ( command -p test …) หรือเพื่อผ่านenvยูทิลิตี้ ( env test …)

ใน zsh disable testคุณสามารถปิดการใช้งานในตัวด้วย นี่เป็นสิ่งที่ถาวร (สำหรับเชลล์ปัจจุบันหรือ subshell) จนกว่า builtin จะเปิดใช้งานenable testอีกครั้งด้วย ในทุบตีคุณสามารถทำเช่นเดียวกันกับenable -n testการปิดการใช้งานและenable testเพื่อเปิดใช้งานอีกครั้ง

คุณสามารถใช้นามแฝงหรือฟังก์ชั่นที่จะบังคับให้การดำเนินการของคำสั่งที่แตกต่างกันเช่นหรือalias test=/usr/bin/test test () { /usr/bin/test "$@"; }หากคุณมีนามแฝงดังกล่าวคุณสามารถป้องกันการใช้งานโดยอ้างถึงส่วนใด ๆ ของมันเช่น\testจะทำหน้าที่ปกติ / builtin / ค้นหาภายนอก โปรดทราบว่าขึ้นอยู่กับเชลล์และการตั้งค่าคำจำกัดความของนามแฝงในฟังก์ชั่นอาจจะขยายเมื่อฟังก์ชั่นจะอ่านหรือเมื่อมีการดำเนินการ หากคุณได้กำหนดฟังก์ชั่นที่คุณสามารถใช้command testเพื่อป้องกันไม่ให้การค้นหาฟังก์ชั่นเช่นเดียวกับการค้นหานามแฝง (ดังนั้นที่นี่testในตัวจะถูกเรียกเว้นแต่คนพิการ)


เค้าenvมีความเหมาะสมที่นี่มากเกินไป?
Steven Penny

ดังนั้นหากเชลล์รันจาก BusyBox เป็นคำสั่งอื่น ๆ โดยปกติแล้วคำสั่งภายนอกจาก BusyBox เดียวกันจะถือเป็น internals หรือไม่ เช่นฉันเพิ่มเต็มdfไปยัง PATH ในตำแหน่งแรกลบ alias 'df', which dfshows / opt / bin / df, แต่ df ทำงาน / bin / df -> busybox
papo

@papo which dfไม่จำเป็นต้องแสดงให้คุณเห็นสิ่งที่dfทำงาน unix.stackexchange.com/questions/85249/…
Gilles 'SO- หยุดความชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.