`mà`, nhưng tất cả


19

Tôi nghĩ rằng hầu hết đều quen thuộc với whichlệnh và tôi sử dụng nó thường xuyên. Tôi vừa gặp phải một tình huống mà tôi tò mò không chỉ là lệnh nào là đầu tiên trong đường dẫn của tôi, mà là bao nhiêu và tất cả các lệnh trong tất cả các đường dẫn của tôi. Tôi đã thử trang người đàn ông nào (đánh máy man whichlàm tôi cười), nhưng không thấy gì.


1
Trên hệ thống của tôi, đó là điều đầu tiên được liệt kê trên trang man : which --all.
Shawn J. Goff

2
Trên của tôi (linux) nó chỉ which -a.
người dùng không xác định

Câu trả lời:


23

Trên một số hệ thống, which -ahiển thị tất cả các trận đấu. Nếu shell của bạn là bash hoặc zsh¹, bạn có thể sử dụng typethay thế: type foohiển thị trận đấu đầu tiên và type -a foohiển thị tất cả các trận đấu. Ba lệnh type, whichwhencethực hiện hầu hết cùng một điều; chúng khác nhau giữa hệ vỏ và hệ điều hành về tính khả dụng, tùy chọn và chính xác những gì chúng báo cáo. typeluôn có sẵn và hiển thị tất cả các tên giống như lệnh có thể (bí danh, từ khóa, hàm dựng sẵn, hàm và lệnh bên ngoài).

Cách duy nhất hoàn toàn di động để hiển thị tất cả các trận đấu là phân tích $PATHchính mình. Đây là một kịch bản shell thực hiện điều này. Nếu bạn biến nó thành hàm shell, hãy đảm bảo đặt thân hàm trong ngoặc đơn (để thay đổi IFSset -fkhông thoát khỏi hàm) và thay đổi exitthành return.

#!/bin/sh
set -f       # disable globbing
IFS=:        # break words at : only
not_found=1
for d in $PATH; do
  if [ -f "$d/$x" ] && [ -x "$d/$x" ]; then
    printf '%s\n' "$d/$x"
    not_found=0
  fi
done
exit $not_found

¹ Hoặc ksh 93, theo tài liệu, mặc dù ksh 93s + 2008-01-31 chỉ in trận đấu đầu tiên khi tôi thử.


Đó là shmã số không hoạt động đúng nếu có thành phần trống trong $PATH. Cũng lưu ý rằng đó $IFSlà một dấu phân cách trường (ít nhất là trong vỏ POSIX) trong khi in $PATH, dấu hai chấm được sử dụng làm dấu tách trường . Xem whichtập lệnh được tìm thấy trên Debian để biết cách triển khai chính xác.
Stéphane Chazelas

các typeBUILTIN trong ksh93u+ 2012-08-01dường như làm việc đúng cách.
Stéphane Chazelas

5

Cờ --all hoặc -a sẽ hiển thị cho bạn tất cả các trận đấu trong đường dẫn của bạn và bí danh (ít nhất là trên Fedora, Ubuntu và CentOS):

which -a which

Trên AIX và Solaris, điều này sẽ giúp bạn gần gũi:

echo "$PATH" | sed -e 's/:/ /g' | \
while read -r p; do find "$p" -type f -name "which"; done

Bạn cần trích dẫn kép xung quanh các thay thế tham số, nếu không thì tập lệnh sẽ không hoạt động nếu $PATHchứa các ký tự toàn cầu hoặc vỏ. read -rlà cần thiết để đối phó với dấu gạch chéo ngược. Đây không phải là một phương pháp tốt vì findsẽ mất nhiều thời gian và có thể trả về kết quả trùng khớp nếu một thư $PATHmục chứa các thư mục con. May mắn thay, findkhông hữu ích ở đây; xem câu trả lời của tôi
Gilles 'SO- ngừng trở nên xấu xa'

Tôi biết tìm thấy cảm thấy sai vì nó chắc chắn sẽ chậm trong các thư mục lồng nhau. Globbing và không gian trong $ PATH? eww Nhưng bạn đã đúng (mặc dù bạn đủ tốt để không nói nhiều): một bài viết của tôi được viết kém.
Eli Heady

1

Nếu bạn không có whichhỗ trợ -a, hoặc whencecó sẵn, hãy tự cuộn:

#!/bin/sh -f

IFS=":"
for PART in $PATH
do
  if test -x "$PART/$1"
  then
    echo $PART/$1
  fi
done

Bạn đang thiếu set -fđể tắt Globing trên không được bảo vệ $PATH. test -fkhông đủ vì chỉ có các tệp thực thi được muốn ở đây; bạn cần test -x. Hmm, tôi nhận ra tôi đã quên kiểm tra tập tin thường xuyên trong kịch bản của tôi.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles: chỉnh sửa theo lời khuyên của bạn. Tôi là tất cả cho chính xác, nhưng tôi thấy whence README.txtkhông thể như whence "file* wi?h we!rd name". Chỉ cần cố gắng để cho thấy nó dễ dàng để đi qua $PATH.
MattBianco

0

ksh và zsh có "whence" là một vỏ tích hợp. whence -alàm những gì bạn muốn theo zsh:

 7:27AM 7 % whence -a cat
/usr/bin/cat
/bin/cat
/usr/bin/cat
/bin/cat

Tôi phải dọn sạch PATH trong zsh, tôi có rất nhiều bản sao trong đó. whence -ahoạt động khác nhau theo ksh:

$ whence -a cat
cat is a tracked alias for /usr/bin/cat

Tôi phải nói rằng, đó dường như cũng là một hành vi có khả năng hữu ích.

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.