Làm thế nào để sử dụng `which` trên một lệnh bí danh?


76

Giống như hầu hết người dùng, tôi có một loạt các bí danh được thiết lập để đưa ra một bộ cờ mặc định cho các chương trình được sử dụng thường xuyên. Ví dụ,

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

Vấn đề là nếu tôi muốn sử dụng whichđể xem vim/ grep/ ls/ etc của tôi đến từ đâu, bí danh sẽ cản trở:

$ which vim
vim: aliased to vim -X

Đây là đầu ra hữu ích, nhưng không phải là những gì tôi đang tìm kiếm trong trường hợp này; Tôi biết vimlà bí danh vim -Xnhưng tôi muốn biết vim đến từ đâu.

Nói ngắn gọn về việc không xác định bí danh chỉ để tôi có thể sử dụng whichnó, có cách nào dễ dàng để which'tháo gỡ ' bí danh và tự chạy trên đó không?

Chỉnh sửa: Có vẻ như whichlà một shell-dựng với các hành vi khác nhau trên các shell khác nhau. Trong Bash, đề nghị của SiegeX về --skip-aliascờ hoạt động; tuy nhiên, tôi đang ở trên Zsh. Có một cái gì đó tương tự tồn tại ở đó?


trong zsh, nếu bạn muốn biết nơi đó vimđến từ đâu , bạn sẽ sử dụngwhere vim
Matija Nalis

Câu trả lời:


105

whichthực sự là một cách tồi để làm những việc như thế này, vì nó đoán được môi trường của bạn dựa trên $SHELLvà các tệp khởi động (nó nghĩ) mà shell sử dụng; đôi khi nó không chỉ đoán sai, mà bạn thường không thể bảo nó cư xử khác đi. ( whichtrên Ubuntu 10.10 của tôi không hiểu --skip-aliasnhư được đề cập bởi @SiegeX chẳng hạn.) typesử dụng môi trường shell hiện tại thay vì chọc vào các tệp cấu hình của bạn và có thể được yêu cầu bỏ qua các phần của môi trường đó, vì vậy nó sẽ cho bạn thấy những gì thực sự sẽ xảy ra thay vì những gì sẽ xảy ra trong một bản dựng lại shell mặc định của bạn.

Trong trường hợp này, type -Psẽ bỏ qua mọi bí danh hoặc hàm:

$ type -P vim
/usr/bin/vim

Bạn cũng có thể yêu cầu nó bóc tất cả các lớp, từng lớp một và cho bạn thấy những gì nó sẽ tìm thấy:

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

(Mở rộng về điều này từ các ý kiến ​​:)

Vấn đề whichlà nó thường là một chương trình bên ngoài thay vì được tích hợp sẵn, điều đó có nghĩa là nó không thể nhìn thấy bí danh hoặc chức năng của bạn và phải cố gắng xây dựng lại chúng từ các tệp khởi động / cấu hình của shell. (Nếu đó là một vỏ được tích hợp sẵn, như trong zshnhưng rõ ràng là không bash, nhiều khả năng sử dụng môi trường của vỏ và làm điều đúng đắn.)

typelà một lệnh tuân thủ POSIX được yêu cầu để hành xử như thể nó là một lệnh tích hợp (nghĩa là nó phải sử dụng môi trường của lớp vỏ được gọi từ bao gồm các bí danh và hàm cục bộ), vì vậy nó thường một hàm tích hợp.

Nó thường không được tìm thấy trong csh/ tcsh, mặc dù trong hầu hết các phiên bản hiện đại của những phiên bản whichnày là vỏ được tích hợp sẵn và thực hiện đúng; đôi khi, tích hợp whatthay vào đó, và đôi khi không có cách nào tốt để xem môi trường của shell hiện tại từ csh/ tcshtất cả.


6
Cảm ơn! Đây là một cái gì đó rất hữu ích để thêm vào túi thủ thuật của tôi. Tôi đặc biệt thích điều đó type -adường như trả lại tất cả các trường hợp trên của bạn $PATH, không chỉ là trường hợp đầu tiên. Tôi nghĩ rằng tôi sẽ bí danh whichđể type:)
Adrian Petrescu

2
@ geekizard: Cảm ơn. Nếu typelà một phần của tiêu chuẩn POSIX thì đó là cách để đi. Để trả lời câu hỏi của tôi, hãy gõ hoạt động trên zsh (trên Debian). Tại sao các bản phân phối không được loại bỏ whatwhichnếu chúng không được chuẩn hóa và không có chức năng bổ sung?
Faheem Mitha

1
Không, thậm chí không từ xa.
geekizard

1
@Faheem: tài liệu lại, tôi sẽ bắt đầu với info bash 'Bash builtins'Linux, mặc dù bạn cũng có thể lấy nó dưới dạng zshtài liệu tham khảo. Chính thức hơn, pubs.opengroup.org/onlinepub/009695399/utilities/type.html (mà tôi lưu ý không thực sự cụ thể -Phoặc -a, hoặc thậm chí -plà hình thức ban đầu của -P, nhưng yêu cầu nó sử dụng môi trường shell hiện tại).
geekizard

2
type -phành xử khác nhau giữa zsh và bash. type -Phoàn toàn không tồn tại trong zsh.
kojiro

15

Trong bash:

type -P vim

Trong zsh:

type -p vim

Ở cả hai:

/usr/bin/which vim

Hoặc là:

( unalias vim; type vim )

2
Cuối cùng là mát mẻ. Chúng ta có thể có một bí danh để làm điều này. :)
balki

Trong bash on redhat tôi phải sử dụng loại -P, và không phải cái nào, nếu tôi muốn câu trả lời đúng. Không có bí danh hoặc chức năng được quan tâm.

Tiến sĩ Eval, "cái nào"? Mũ đỏ nào?
Mikel

@Mikel RH7.4. GNU mà v2.20.

4

Trong zsh whichlà một nội dung như lệnh này báo cáo:

$ whence -w which
which: builtin

Để thực thi lệnh bên ngoài (trong bất kỳ shell nào) which, hãy sử dụng Đường dẫn đầy đủ :

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

do đó, lệnh lsđã được tìm thấy (giá trị thoát là 0) và được đặt tại /bin/ls.

Bên trong zsh; một cách (bên cạnh cách trên) để tìm kiếm các lệnh bên ngoài là:

$ whence -p ls
/bin/ls

Tuy nhiên, điều đó sẽ không giải quyết các bí danh lồng nhau như:

$ alias dire='ls -l'

Lệnh sẽ báo cáo rằng không có direlệnh nào được tìm thấy.

$ whence -p dire; echo $?
1

Để giải quyết các bí danh lồng nhau (thủ công) xem Resolve nested aliases to their source commands


2

Của tôi được định nghĩa như vậy

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

1

Hãy thử như sau:

which --skip-alias vim

1
Hấp dẫn! Điều này hoạt động trên Bash, nhưng không phải trên Zsh (Tôi thực sự không nghĩ rằng điều này sẽ phụ thuộc vào vỏ). Điều này khiến tôi nhận ra rằng đó whichthực sự là một trình bao dựng sẵn và không phải là tiện ích Unix thông thường như tôi đã giả định. Vì vậy, tôi nên chỉnh sửa câu hỏi của mình và chỉ định Zsh. Cảm ơn đã chỉ ra điều này cho tôi!
Adrian Petrescu

whichkhông phải là nội dung, ít nhất là không có trên Debian. Nó là một kịch bản shell và là một phần của debianutils, vì vậy hoạt động trên zsh. Tuy nhiên, --skip-aliaskhông phải là một tùy chọn whichtrên Debian. Có nhiều loại khác nhau whichnổi xung quanh? Đây không phải là một lệnh được tiêu chuẩn hóa.
Faheem Mitha

@Faheem Mitha: Nó là một nội dung zsh. Xem man zshbuiltins. mà [-wpams] đặt tên ... Tương đương với từ -c.
Mikel

Vâng trên Xubfox bash, nó không phải là một tính năng tích hợp và không có --skip-aliastùy chọn.
polym

Trên CentOS (và RHEL?) 6, đây là một tệp thực thi /usr/bin/whichcộng với một bí danh /etc/profile.dcho phép nó xử lý các bí danh nhưng --skip-aliashoạt động. Kết quả là which whichhiển thị bí danh, nhưng command which whichhiển thị thực thi!
dave_thndry_085

0

Một cách khác là command which vim, hoạt động theo cùng một cách trong cả hai zshbash

Ví dụ: trên mac của tôi:

LOLcalhost :: ~ % command which grep
/usr/local/bin/grep

Ah đủ công bằng.
Zee Alexander

0

Cả hai typewhichhành xử khác nhau theo loại vỏ của bạn.

Trong bash, whichlà một lệnh tồn tại trong PATH. Nó tìm kiếm lệnh bạn cung cấp PATH. Bash buildin type -P(P for PATH) hành xử chính xác như thế nào which.

Trong ZSH, cả hai whichtypeđều là nội hàm và một phần chức năng của nội dung whence. which -plà những gì bạn muốn. Nó buộc một tìm kiếm đường dẫn. ( -Ptùy chọn không có sẵn cho typeZSH.)

từ [-vcwfpamsS] [-x num] tên ...

-p

Thực hiện tìm kiếm đường dẫn cho tên ngay cả khi đó là bí danh, từ dành riêng, hàm shell hoặc hàm dựng sẵn.

Thêm từ hướng dẫn ZSH.

mà [-wpamsS] [-x num] tên ...

Tương đương với từ -c.

Để bỏ qua builtin whichvà buộc sử dụng lệnh whichtừ PATHtrong ZSH:

alias which="command which"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.