Apa perbedaan antara menjalankan executable hanya dengan nama dan dengan menambahkan dot / slash sebelumnya?

13

Ini adalah output dari ls -allperintah:

-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

Sekarang ketika saya menjalankannya jdevmenjalankan versi yang berbeda dari Oracle JDveloper daripada ketika saya menjalankannya sebagai ... ./jdevMengapa demikian?

Kutu buku
sumber

Jawaban:

20

Ketika Anda menjalankan file yang dapat dieksekusi (atau lebih tepatnya di dunia unix / linux - file dengan hak yang dapat dieksekusi / ditandai) seperti:

$ ./jdev

Anda kemudian menandai dengan .itu Anda ingin menjalankan file di dalam direktori kerja Anda (direktori tempat Anda berada saat ini) yang bernamajdev dan memiliki hak yang dapat dieksekusi untuk pengguna yang meluncurkannya (Anda harus mencatat bahwa itu masih bisa menjadi tautan ke file lain, Anda dapat memeriksa dengan mengetik ls -l jdevdi terminal)

( Lihat izin file di linux / unix )

Ketika Anda menjalankannya sebagai

$ jdev

maka kemungkinan besar ada jdevdiinstal di suatu tempat pada sistem dan Anda memilikinya di $PATH(mis. /usr/bin/atau/bin/ atau /usr/local/bin/)

Seperti yang dikatakan peterph : Anda dapat menggunakan whichuntuk menunjuk executable yang sedang diluncurkan dengan perintah tertentu, misalnya:

$ which find
/usr/bin/find
Patryk
sumber
1
Juga bukan bahwa whichutilitas dapat memberi tahu Anda apa yang dapat dieksekusi akan digunakan jika tidak ada jalur yang diberikan.
peterph
@ Peterf Mengedit jawaban saya.
Patryk
7
Jauh lebih baik digunakan typeuntuk memeriksa apa yang diluncurkan oleh perintah tertentu. Sebab whichakan menunjukkan kepada Anda hanya sebuah biner di suatu tempat di $ PATH, namun itu mungkin sama sekali menjadi biner lain.
buru
@rush Saya baru saja mencoba itu dan itu tidak bekerja akan seperti yang Anda katakan: [~] $which zsoelim /usr/bin/zsoelim [~] $ type zsoelim zsoelim is /usr/bin/zsoelim. Sementarazsoelim -> soelim
Patryk
2
@ Patryk Saya pikir terburu-buru berarti alias shell / fungsi, yang whichtidak memiliki kesempatan untuk menemukan, karena itu adalah biner mandiri yang tidak memiliki akses ke lingkungan shell yang berjalan (yang saya maksudkan alias dan fungsi, bukan hanya variabel lingkungan , beberapa di antaranya adalah warisan).
peterph
8

Jika Anda memanggil perintah tanpa slash dalam namanya di shell, maka dicari di alias shell, fungsi dan dalam daftar jalur yang disediakan dalam $PATHvariabel lingkungan. (perhatikan bahwa Anda dapat memiliki direktori kerja saat ini (ditentukan sebagai .atau string kosong) atau direktori relatif apa pun di $PATH, tetapi itu tidak disarankan untuk alasan keamanan).

Jika ada garis miring pada nama, maka itu tidak terjadi, nama tersebut diambil sebagai jalur untuk menjalankan perintah dari (meskipun beberapa shell seperti zsh memungkinkan alias atau fungsi memiliki garis miring pada namanya yang kemudian akan diutamakan).

Jadi, jika Anda ingin menjalankan perintah bernama fooyang ada di direktori kerja saat ini, Anda harus datang dengan nama yang berisi garis miring. ./fooadalah yang paling jelas. Anda juga bisa menggunakan path lengkap, atau../dir/foo ...

Untuk mengetahui apa yang akan dijalankan shell, gunakan typeperintah. Jangan gunakan whichperintah yang umumnya tidak melakukan apa yang Anda pikirkan dan merupakan warisan cshyang lebih baik dibiarkan begitu saja.

Stéphane Chazelas
sumber
Kenapa tidak "yang" tapi "tipe"?
Geek
@ Geek, Itu FAQ di sini, lihat unix.stackexchange.com/search?q=[which[+type
Stéphane Chazelas
apakah Anda memberikan tautan yang benar?
Geek
Itu adalah hasil pencarian di situs ini untuk membuktikan bahwa itu adalah pertanyaan yang sering diajukan. Banyak jawaban untuk pertanyaan-pertanyaan itu akan memberi tahu Anda mengapa tidak menggunakannya which. Lihat misalnya unix.stackexchange.com/questions/16693/…
Stéphane Chazelas
2

Saya merekomendasikan untuk menggunakan built-in Zsh 'di mana' (lebih baik daripada 'yang') untuk melihat bagaimana dan di mana urutan alias, built-in shell atau apa pun akan ditemukan untuk $ PATH ;-)

Berikut adalah contoh untuk memahami sesuatu dengan lebih baik, bagaimana hal itu dipilih:

[ 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:~ %
Afsin Toparlak
sumber
1

Meskipun ini mungkin tergantung pada shell Anda, aturannya biasanya adalah:

  • Jika Anda memberikan jalur, baik relatif atau absolut, jalur itu digunakan. ./jdevadalah jalur relatif, karena .singkatan dari direktori saat ini (pada kenyataannya, ls -all .akan memberi Anda sama dengan ls -all). Jika ya /usr/bin/tool/, Anda menggunakan jalur absolut. Dalam kasus ini, file yang ditunjuk untuk dieksekusi.

  • Jika Anda tidak memberikan jalur, tetapi hanya nama, direktori di $PATH akan mencari alat yang Anda coba jalankan.

Jika Anda memiliki file di direktori saat ini dengan nama yang sama dengan file di beberapa direktori di $PATH , dan Anda menjalankannya dengan menambahkan ./namanya terlebih dahulu, Anda akan secara efektif menjalankan file yang berbeda.

Mungkin masalah lain adalah bahwa Anda benar-benar mengharapkan jdev untuk menjalankan executable di direktori saat ini. Kecuali Anda berubah$PATH untuk memasukkan ., ini bukan sesuatu yang harus Anda harapkan sama sekali ...

... dan itu masih merupakan ide yang tidak terlalu baik untuk dimasukkan di .sana, jika Anda melakukannya harap paling tidak taruh di bagian akhir, sehingga sisanya $PATHselalu dicari terlebih dahulu - bayangkan Anda berada di direktori jaringan bersama dan seseorang memutuskan untuk meletakkan biner jahat di sana karena ls, jika $PATHdimulai dengan ., sederhana ls -lahakan cukup untuk menyerang sistem Anda.

njsg
sumber
Terminologi Anda membingungkan. jdevsendiri juga merupakan jalur relatif. Aturannya adalah: jika tidak mengandung garis miring, maka itu akan dicari dalam alias, fungsi dan $PATH, jika tidak, akan dicari secara langsung pada sistem file (meskipun beberapa shell memungkinkan alias atau fungsi dengan / dalam nama mereka yang kemudian akan mengambil prioritas).
Stéphane Chazelas