Thứ tự thực thi bắt đầu trong bash


14

Nếu tôi thực thi testlệnh trong bash, testtiện ích tích hợp (đánh giá biểu thức điều kiện) được khởi động:

$ 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
$ 

Tuy nhiên, như đã thấy ở đầu ra type -a testở trên, có một thư mục khác testtrong / usr / local / bin và một thư mục khác trong thư mục / usr / bin. Các lệnh thực thi được sắp xếp như thế nào, tức là các lệnh dựng sẵn luôn được ưa thích và sau đó các lệnh còn lại phụ thuộc vào thứ tự thư mục trong biến $ PATH? Ngoài ra, có thể thay đổi thứ tự của các tệp thực thi được bắt đầu không, ví dụ: nếu tôi nhập test, thì / usr / bin / test được bắt đầu thay vì bash-dựng sẵn test?


Bạn có thể chỉ định đường dẫn đầy đủ khi gọi lệnh, ví dụ: /usr/bin/test -f "$file"...
jasonwryan

@jasonwryan Tôi biết điều này, nhưng tôi chỉ quan tâm nếu có cách nào để thay đổi thứ tự thực thi bắt đầu.
Martin

Câu trả lời:


25

Ưu tiên cao nhất là bí danh bash, sau đó là nội dung đặc biệt (chỉ trong chế độ POSIX), sau đó là chức năng, sau đó là nội dung, sau đó tìm kiếm $PATH.

Để thực hiện một nội trang, sử dụng builtin test.
Để thực thi một ứng dụng bên ngoài, sử dụng một đường dẫn rõ ràng : /bin/test.
Để bỏ qua các chức năng và bí danh, sử dụng command test.
Để bỏ qua chỉ bí danh, sử dụng \testhoặc bất kỳ loại mở rộng nào khác.

Có thể vô hiệu hóa / kích hoạt tích hợp với enable test.

(Cập nhật theo nhận xét bên dưới)
(Đã sửa lỗi chỉnh sửa quản trị viên không chính xác mà bash đã disabledựng sẵn - thực tế là chỉ có enable)


1
@ 1_CR gena2x là đúng. Câu trả lời của tôi đã bỏ qua các nội dung đặc biệt, được ưu tiên hơn các chức năng theo POSIX (mặc dù một số shell không tuân thủ; bash chỉ tuân thủ trong chế độ POSIX).
Gilles 'SO- ngừng trở nên xấu xa'

1
Đề xuất chỉnh sửa: Bí danh bị vô hiệu hóa khi bạn trích dẫn lệnh (hoặc bất kỳ phần nào của nó), như trong \testhoặc 'test'hoặc tes't'.
John Kugelman

2
Đó không phải là hình ảnh đầy đủ. Có vẻ như bất kỳ loại mở rộng nào (trong hướng dẫn sử dụng bash, tất cả các thay thế, mở rộng dấu ngã và như vậy được gọi là mở rộng ) sẽ vô hiệu hóa các bí danh. Tôi đã thử.
gena2x

1
Trích từ trang bash người đàn ông:.. "Từ đầu tiên của mỗi câu lệnh đơn giản, nếu không thể viện chứng, được kiểm tra để xem nếu nó có một bí danh Nếu vậy, từ đó được thay thế bằng văn bản của alias Các nhân vật /, $, backtick, và =và bất kỳ ký tự đại diện hoặc ký tự trích dẫn nào được liệt kê ở trên có thể không xuất hiện trong tên bí danh. "
John Kugelman

2
+1 cho các gợi ý trong việc giúp tôi tìm nguồn gốc của thông tin này: đó là trong trang bash man, trong phần THỰC HIỆN QUY TẮC, đoạn thứ hai và thứ ba.
twan163

6

Các lệnh tích hợp luôn được ưu tiên hơn các lệnh bên ngoài. Lý do là lệnh tích hợp nhanh hơn (và trong một vài trường hợp, chẳng hạn như cdhoặc , chỉ có lệnh tích hợp mới có thể có hiệu quả mong muốn).test -o BASH_OPTION

Đôi khi lệnh bên ngoài có thể có các khả năng mà shell dựng sẵn không có. Trong trường hợp đó, bạn có thể gọi lệnh bên ngoài bằng cách đưa ra một đường dẫn rõ ràng (nghĩa là chứa dấu gạch chéo) (điều này bỏ qua mọi mối quan tâm về thứ tự trong $PATH). Nếu bạn không muốn mã hóa đường dẫn bên ngoài nhưng bạn muốn ngăn việc sử dụng nội dung, bạn có thể sử dụng "$(type -P test)"(ghi chú vốn P) trong bash, "$(whence -p test)"trong ksh và =testtrong zsh. Một cách khác để buộc sử dụng lệnh bên ngoài là sử dụng hàm commanddựng sẵn ( command -p test …) hoặc đi qua envtiện ích ( env test …).

Trong zsh, bạn có thể vô hiệu hóa nội dung với disable test. Điều này là vĩnh viễn (đối với lớp vỏ hiện tại hoặc lớp vỏ con) cho đến khi phần dựng sẵn được kích hoạt lại enable test. Trong bash, bạn có thể làm tương tự với enable -n testđể vô hiệu hóa và enable testkích hoạt lại.

Bạn có thể sử dụng một bí danh hoặc hàm để buộc thực thi một lệnh khác, ví dụ alias test=/usr/bin/testhoặc test () { /usr/bin/test "$@"; }. Nếu bạn có một bí danh như vậy, bạn có thể ngăn việc sử dụng nó bằng cách trích dẫn bất kỳ phần nào của nó, ví dụ như \testsẽ thực hiện chức năng bình thường / dựng sẵn / tra cứu bên ngoài. Lưu ý rằng tùy thuộc vào trình bao và cài đặt của nó, các định nghĩa bí danh trong một hàm có thể được mở rộng khi một hàm được đọc hoặc khi nó được thực thi. Nếu bạn đã xác định một chức năng, bạn có thể sử dụng command testđể ngăn chặn tra cứu chức năng cũng như tra cứu bí danh (vì vậy ở đây, testnội dung sẽ được gọi trừ khi bị tắt).


wouldnt envđược thích hợp ở đây quá?
Steven Penny

vì vậy, nếu shell chạy từ BusyBox, có phải các lệnh khác, thường là từ bên ngoài cùng BusyBox được coi là nội bộ không? ví dụ như tôi đã thêm đầy đủ dfđể một PATH trên vị trí đầu tiên, loại bỏ bí danh 'df', which dfchương trình / opt / bin / df, nhưng df chạy / bin / df -> busybox
papo

@papo which dfkhông nhất thiết phải cho bạn thấy những gì dfchạy. unix.stackexchange.com/questions/85249/ Ấn
Gilles 'SO- ngừng trở nên xấu xa'
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.