Sự khác biệt giữa việc chạy một tệp thực thi chỉ bằng tên và bằng cách thêm dấu chấm / dấu gạch chéo trước nó là gì?


13

Đây là đầu ra từ ls -alllệnh:

-rwxr----- 1 subhrcho dba  3600 Nov 13 17:26 jdev
-rw-r----- 1 subhrcho dba  1566 Nov 13 17:26 jdev-Darwin.conf
-rw-r----- 1 subhrcho dba   347 Mar  6  2009 jdev-debug.boot
-rw-r----- 1 subhrcho dba   821 Nov 13 17:26 jdev-logging-debug.conf
-rw-r----- 1 subhrcho dba   584 Nov 13 17:26 jdev-logging.conf
-rw-r----- 1 subhrcho dba  4717 Jul 31 16:09 jdev.boot
-rw-r----- 1 subhrcho dba 12877 Nov 13 17:26 jdev.common
-rw-r----- 1 subhrcho dba  5047 Dec  6 01:43 jdev.conf
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdev.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64W.exe
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdevW.exe

Bây giờ khi tôi chạy, jdevnó chạy một phiên bản khác của Oracle JDveloper so với khi tôi chạy nó ./jdev.. Tại sao nó lại như vậy?

Câu trả lời:


20

Khi bạn chạy một tệp thực thi (hay đúng hơn là trong thế giới unix / linux - một tệp có quyền / cờ thực thi) như vậy:

$ ./jdev

sau đó bạn đánh dấu .rằng bạn muốn chạy một tệp trong thư mục làm việc của bạn (thư mục mà bạn hiện đang ở) có tên jdevvà có quyền thực thi đối với người dùng đang khởi chạy nó (bạn phải lưu ý rằng nó vẫn có thể là một liên kết đến tập tin khác, bạn có thể kiểm tra bằng cách gõ ls -l jdevvào terminal)

(xem quyền truy cập tệp trong linux / unix )

Khi bạn chạy nó như

$ jdev

sau đó rất có thể đã được jdevcài đặt ở đâu đó trên hệ thống và bạn có nó trong $PATH(ví dụ /usr/bin/hoặc /bin/hoặc /usr/local/bin/)

Như peterph đã nêu: bạn có thể sử dụng whichđể chỉ ra tệp thực thi đang được khởi chạy với lệnh cụ thể, ví dụ:

$ which find
/usr/bin/find

1
Cũng không phải là whichtiện ích có thể cho bạn biết những gì thực thi sẽ được sử dụng nếu không có đường dẫn nào được đưa ra.
peterph

@peterph Chỉnh sửa câu trả lời của tôi.
Patryk

7
Sẽ tốt hơn nhiều khi sử dụng typeđể kiểm tra những gì được khởi chạy bằng lệnh cụ thể. Nguyên nhân whichsẽ chỉ cho bạn thấy một nhị phân ở đâu đó trong $ PATH, tuy nhiên nó có thể được đặt bí danh cho một nhị phân hoàn toàn khác.
vội vàng

@rush Tôi vừa thử nó và nó sẽ không hoạt động như bạn nói : [~] $which zsoelim /usr/bin/zsoelim [~] $ type zsoelim zsoelim is /usr/bin/zsoelim. Trong khizsoelim -> soelim
Patryk

2
@Patryk Tôi nghĩ rằng rush có nghĩa là các bí danh / hàm shell, whichkhông có cơ hội tìm thấy, vì nó là một nhị phân độc lập không có quyền truy cập vào môi trường shell đang chạy (theo ý tôi là bí danh và hàm, không chỉ các biến môi trường , một số trong đó được kế thừa).
peterph

8

Nếu bạn gọi một lệnh không có dấu gạch chéo trong tên của nó trong shell thì nó sẽ tìm trong các bí danh, hàm và trong danh sách các đường dẫn được cung cấp trong $PATHbiến môi trường. (lưu ý rằng bạn có thể có thư mục làm việc hiện tại (được chỉ định là .hoặc chuỗi trống) hoặc bất kỳ thư mục tương đối nào $PATH, nhưng điều đó không được khuyến nghị vì lý do bảo mật).

Nếu có một dấu gạch chéo trong tên, thì điều đó không xảy ra, tên đó được lấy làm đường dẫn để thực thi lệnh từ đó (mặc dù một số shell như zshcho phép bí danh hoặc hàm có dấu gạch chéo trong tên của chúng sẽ được ưu tiên).

Vì vậy, nếu bạn muốn chạy một lệnh được gọi foolà trong thư mục làm việc hiện tại, bạn phải đưa ra một tên có chứa dấu gạch chéo. ./foolà rõ ràng nhất. Bạn cũng có thể sử dụng đường dẫn đầy đủ hoặc ../dir/foo...

Để biết shell sẽ chạy cái gì, hãy sử dụng typelệnh. Không sử dụng whichlệnh mà thường không làm những gì bạn nghĩ nó là một di sản cshmà từ đó tốt hơn là để lại một mình.


Tại sao không "mà" mà "loại"?
Geek

@Geek, Đó là một Câu hỏi thường gặp tại đây, xem unix.stackexchange.com/search?q=[which[+type
Stéphane Chazelas

bạn đã cung cấp các liên kết chính xác?
Geek

Đó là kết quả tìm kiếm trên trang web này để chứng minh đó là một câu hỏi thường gặp. Nhiều câu trả lời cho những câu hỏi đó sẽ cho bạn biết tại sao không sử dụng which. Xem ví dụ unix.stackexchange.com/questions/16693/iêu
Stéphane Chazelas

2

Tôi khuyên bạn nên sử dụng 'where' (tốt hơn 'which') của Zsh để xem cách thức và theo thứ tự các bí danh, shell-in hoặc bất cứ thứ gì khác sẽ được tìm thấy để $ PATH ;-)

Dưới đây là một ví dụ để hiểu mọi thứ tốt hơn, cách nó được chọn:

[ 0:04:08 ] afsin@s15426859:~ % pwd
/home/afsin
[ 0:04:30 ] afsin@s15426859:~ % which who
/usr/bin/who
[ 0:04:47 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:27 ] afsin@s15426859:~ % echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/afsin/bin
[ 0:05:31 ] afsin@s15426859:~ % touch who
[ 0:05:40 ] afsin@s15426859:~ % chmod +x who
[ 0:05:47 ] afsin@s15426859:~ % ls -al who
-rwxr-xr-x 1 afsin afsin 0 23. Jan 00:05 who
[ 0:05:50 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:55 ] afsin@s15426859:~ % export PATH=$PATH:.
[ 0:06:09 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:14 ] afsin@s15426859:~ % alias who=who
[ 0:06:19 ] afsin@s15426859:~ % where who
who: aliased to who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:22 ] afsin@s15426859:~ % which who
who: aliased to who
[ 0:06:27 ] afsin@s15426859:~ %

1

Mặc dù điều này có thể phụ thuộc vào vỏ của bạn, nhưng quy tắc thường là:

  • Nếu bạn cung cấp một đường dẫn, tương đối hoặc tuyệt đối, đường dẫn đó được sử dụng. ./jdevlà một đường dẫn tương đối, vì .viết tắt của thư mục hiện tại (trên thực tế, ls -all .sẽ cung cấp cho bạn giống như ls -all). Nếu bạn làm /usr/bin/tool/, bạn đang sử dụng một đường dẫn tuyệt đối. Trong những trường hợp này, tệp được trỏ đến được thực thi.

  • Nếu bạn không cung cấp một đường dẫn, mà chỉ là một tên, các thư mục trong $PATHđược tìm kiếm cho công cụ bạn đang cố gắng chạy.

Nếu bạn có một tệp trong thư mục hiện tại có cùng tên với một tệp trong một số thư mục trong đó $PATHvà bạn chạy nó bằng cách thêm vào ./tên của nó, bạn sẽ chạy một tệp khác một cách hiệu quả.

Có lẽ một vấn đề khác là bạn thực sự mong đợi jdevđể chạy chương trình thực thi trong thư mục hiện tại. Trừ khi bạn thay đổi $PATHđể bao gồm ., đây không phải là điều bạn nên mong đợi ...

... Và vẫn là một ý tưởng không hay lắm để đưa vào .đó, nếu bạn làm như vậy, ít nhất hãy đặt nó ở cuối, để phần còn lại $PATHluôn được tìm kiếm trước - chỉ cần tưởng tượng rằng bạn đang ở trong một thư mục mạng chung và ai đó quyết định đặt một nhị phân xấu xa ở đó ls, nếu $PATHbắt đầu bằng ., một đơn giản ls -lahsẽ đủ để tấn công hệ thống của bạn.


Thuật ngữ của bạn là khó hiểu. jdevmột mình cũng là một con đường tương đối. Quy tắc là: nếu nó không chứa dấu gạch chéo, thì nó sẽ tìm kiếm các bí danh, hàm và $PATHnếu không, nó sẽ tra cứu trực tiếp trên hệ thống tệp (mặc dù một số shell cho phép các bí danh hoặc các hàm có / trong tên của chúng sẽ lấy ưu tiên).
Stéphane Chazelas
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.