วิธีการใช้ `ซึ่ง` กับคำสั่ง aliased?


76

เช่นเดียวกับผู้ใช้ส่วนใหญ่ฉันมีการตั้งค่านามแฝงมากมายเพื่อให้ชุดธงเริ่มต้นสำหรับโปรแกรมที่ใช้บ่อย ตัวอย่างเช่น

alias vim='vim -X'
alias grep='grep -E'
alias ls='ls -G'

ปัญหาคือถ้าฉันต้องการใช้whichเพื่อดูว่าvim/ grep/ ls/ / etc ของฉันมาจากไหนนามแฝงที่ได้รับในทาง:

$ which vim
vim: aliased to vim -X

นี่เป็นผลลัพธ์ที่มีประโยชน์ แต่ไม่ใช่สิ่งที่ฉันกำลังมองหาในกรณีนี้ ฉันรู้ว่าvimเป็นนามแฝงvim -Xแต่ฉันต้องการที่จะรู้ว่า vimมาจากไหน

ขาดการกำหนดนามแฝงชั่วคราวเพียงเพื่อให้ฉันสามารถใช้whichกับมันได้หรือไม่มีวิธีง่าย ๆ ที่จะwhich'แกะ' นามแฝงและเรียกใช้ตัวมันเองหรือไม่?

แก้ไข:ดูเหมือนว่าwhichเป็นตัวเชลล์ที่มีพฤติกรรมที่แตกต่างกันในแต่ละเชลล์ ใน Bash คำแนะนำของ SiegeX เกี่ยวกับการ--skip-aliasทำงานของธง; อย่างไรก็ตามฉันอยู่ใน Zsh มีสิ่งที่คล้ายกันอยู่ที่นั่นไหม?


ใน zsh หากคุณต้องการทราบว่าvimมาจากไหนคุณต้องใช้where vim
Matija Nalis

คำตอบ:


105

whichจริงๆแล้วมันเป็นวิธีที่ไม่ดีในการทำสิ่งต่าง ๆ เช่นนี้เพราะมันทำให้เดาได้ว่าสภาพแวดล้อมของคุณเป็นอย่างไร$SHELLและไฟล์เริ่มต้น (มันคิดว่า) เชลล์ใช้ ไม่เพียง แต่บางครั้งก็เดาผิด แต่โดยทั่วไปคุณไม่สามารถบอกให้มันทำงานผิดไปได้ ( whichบน Ubuntu 10.10 ของฉันไม่เข้าใจ--skip-aliasตามที่กล่าวไว้โดย @SiegeX) typeใช้สภาพแวดล้อมเชลล์ปัจจุบันแทนที่จะใช้ poking ในไฟล์ปรับแต่งของคุณและสามารถบอกให้ละเว้นบางส่วนของสภาพแวดล้อมนั้นได้ เกิดขึ้นแทนสิ่งที่จะเกิดขึ้นในการสร้างเชลล์เริ่มต้นขึ้นใหม่

ในกรณีนี้type -Pจะข้ามนามแฝงหรือฟังก์ชั่นใด ๆ :

$ type -P vim
/usr/bin/vim

คุณยังสามารถขอให้ลอกเลเยอร์ทั้งหมดออกทีละชั้นและแสดงให้คุณเห็นสิ่งที่มันจะพบ:

$ type -a vim
vim is aliased to `vim -X'
vim is /usr/bin/vim

(ขยายจากความคิดเห็น :)

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

typeเป็นคำสั่งที่เข้ากันได้กับ POSIX ซึ่งจำเป็นต้องทำตัวเหมือนเป็นแบบบิวด์อิน (นั่นคือมันต้องใช้สภาพแวดล้อมของเชลล์ที่เรียกใช้จากการรวมนามแฝงและฟังก์ชั่นในตัวเครื่อง) ดังนั้นจึงเป็นแบบบิวด์อิน

โดยทั่วไปจะไม่พบในcsh/ tcshถึงแม้ว่าในรุ่นที่ทันสมัยที่สุดของพวกwhichมันคือเชลล์บิวด์อินและทำสิ่งที่ถูกต้อง บางครั้งมีการติดตั้งในตัวwhatและบางครั้งก็ไม่มีวิธีที่ดีในการดูสภาพแวดล้อมของเชลล์ปัจจุบันจากcsh/ tcshเลย


6
ขอบคุณ! นี่เป็นสิ่งที่มีประโยชน์มากในการเพิ่มลูกเล่นลงในกระเป๋าของฉัน ฉันชอบโดยเฉพาะอย่างยิ่งที่type -aดูเหมือนว่าจะส่งคืนอินสแตนซ์ทั้งหมดของคุณ$PATHไม่ใช่เฉพาะตอนแรก ฉันคิดว่าฉันจะนามแฝงwhichเพื่อtype:)
เอเดรีย Petrescu

2
@ geekosaur: ขอบคุณ หากtypeเป็นส่วนหนึ่งของมาตรฐาน POSIX นั่นเป็นวิธีที่จะไป หากต้องการตอบคำถามของฉันให้พิมพ์ผลงานบน zsh ด้วย (บนเดเบียน) ทำไมการกระจายไม่ได้กำจัดwhatและwhichถ้ามันไม่ได้มาตรฐานและไม่มีฟังก์ชั่นพิเศษ?
Faheem Mitha

1
ไม่ไม่ใช่จากระยะไกล
geekosaur

1
@Faheem: เอกสารอีกครั้งฉันจะเริ่มต้นด้วยinfo bash 'Bash builtins'บน Linux แม้ว่าคุณจะได้รับมันจากzshคู่มืออ้างอิง เป็นทางการมากขึ้นpubs.opengroup.org/onlinepubs/009695399/utilities/type.html (ซึ่งฉันทราบว่าไม่ได้ระบุจริง-Pหรือ-aหรือ-pเป็นรูปแบบดั้งเดิม-Pแต่ต้องการให้ใช้สภาพแวดล้อมเชลล์ปัจจุบัน)
geekosaur

2
type -pพฤติกรรมแตกต่างกันระหว่าง zsh และ bash type -Pไม่มีอยู่ใน zsh เลย
kojiro

15

ในbash:

type -P vim

ในzsh:

type -p vim

ในทั้งสอง:

/usr/bin/which vim

หรือ:

( unalias vim; type vim )

2
อันสุดท้ายคือเท่ห์ เราสามารถมีนามแฝงที่จะทำเช่นนี้ :)
balki

ในทุบตีในสิ่งที่ฉันต้องใช้พิมพ์ -P และไม่ซึ่งถ้าฉันต้องการคำตอบที่ถูกต้อง ไม่มีชื่อแทนหรือฟังก์ชั่นที่เกี่ยวข้อง

ดร. อีวาล "ไหน" หมวกสีแดงอันไหน
Mikel

@Mikel RH7.4 GNU ซึ่ง v2.20

4

ใน zsh whichเป็น builtin ตามคำสั่งนี้รายงาน:

$ whence -w which
which: builtin

เพื่อรันคำสั่งภายนอก (ในเชลล์ใด ๆ ) whichให้ใช้พา ธ แบบเต็ม :

$ /bin/which ls; echo $?
/bin/ls
0

ดังนั้นคำสั่งlsถูกพบ (มีค่าออกจาก 0), /bin/lsและตั้งอยู่ที่

ข้างในzsh; วิธี (ด้านข้างข้างบน) เพื่อค้นหาคำสั่งภายนอกคือ:

$ whence -p ls
/bin/ls

อย่างไรก็ตามจะไม่สามารถแก้ไขนามแฝงที่ซ้อนกันได้เช่น:

$ alias dire='ls -l'

คำสั่งจะรายงานว่าไม่direพบคำสั่ง

$ whence -p dire; echo $?
1

สำหรับการแก้ไขนามแฝงที่ซ้อนกัน (ด้วยตนเอง) โปรดดู Resolve nested aliases to their source commands


2

เหมืองที่กำหนดไว้เช่นนี้

alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

1

ลองทำสิ่งต่อไปนี้:

which --skip-alias vim

1
ที่น่าสนใจ! สิ่งนี้ใช้ได้กับ Bash แต่ไม่ใช่ใน Zsh (ฉันไม่คิดว่ามันจะขึ้นกับเชลล์) นี่ทำให้ฉันรู้ว่าwhichจริงๆแล้วมันเป็นเชลล์ในตัวและไม่ใช่ยูทิลิตี้ Unix ปกติอย่างที่ฉันคิดเอาไว้ ดังนั้นฉันควรแก้ไขคำถามของฉันและระบุ Zsh ขอบคุณสำหรับการชี้ให้ฉันเห็น!
Adrian Petrescu

whichไม่ใช่ builtin อย่างน้อยไม่ได้อยู่ใน Debian มันเป็นเชลล์สคริปต์และเป็นส่วนหนึ่งของ debianutils ดังนั้นทำงานบน zsh อย่างไรก็ตาม--skip-aliasไม่ใช่ตัวเลือกwhichใน Debian มีความหลากหลายของการwhichลอยอยู่รอบ ๆ ? สิ่งนี้ไม่ปรากฏว่าเป็นคำสั่งมาตรฐาน
Faheem Mitha

@Faheem Mitha: มันเป็น zsh builtin man zshbuiltinsดู ซึ่งชื่อ [-wpams] ... เทียบเท่ากับที่มาของ -c
มิเคล

ใช่ใน Xubuntu bashมันไม่ใช่แบบในตัวและไม่มี--skip-aliasตัวเลือก
polym

บน CentOS (และ RHEL?) 6 มันเป็นไฟล์ปฏิบัติการ/usr/bin/whichบวกกับชื่อแทนที่/etc/profile.dให้มันจัดการนามแฝง แต่--skip-aliasใช้ได้ เป็นผลwhich whichให้แสดงนามแฝง แต่command which whichแสดงปฏิบัติการ!
dave_thompson_085


0

ทั้งสองtypeและwhichทำงานแตกต่างกันไปตามชนิดของเชลล์

ในทุบตีเป็นคำสั่งที่มีอยู่ในwhich PATHมันค้นหาคำสั่งที่คุณให้PATHมา Bash builtin type -P(P for PATH) ทำตัวเหมือนwhichกัน

ใน ZSH ทั้งสองwhichและtypeมี builtins และฟังก์ชั่นบางส่วนของ whencebuiltin which -pคือสิ่งที่คุณต้องการ มันบังคับให้ค้นหาเส้นทาง ( -Pตัวเลือกไม่พร้อมใช้งานสำหรับtypeZSH)

ดังนั้น [-vcwfpamsS] ชื่อ [-x num]

-p

ค้นหาพา ธ เพื่อค้นหาชื่อแม้ว่าจะเป็นนามแฝงคำที่สงวนไว้ฟังก์ชันเชลล์หรือ builtin

เพิ่มเติมจากคู่มือ ZSH

อันไหน [-wpamsS] ชื่อ [-x num]

เทียบเท่ากับ -c

ในการข้ามbuiltin whichและบังคับใช้คำสั่งwhichจากPATHใน ZSH:

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