Bagaimana cara Unix mencari file yang dapat dieksekusi?

47

Ketika sebuah file dieksekusi, bagaimana cara Unix mencarinya? Jika ada beberapa file yang dapat dieksekusi di PATH dengan nama yang sama, mana yang lebih disukai? Apakah direktori saat ini termasuk dalam pencarian ketika file dieksekusi?

Misalkan ada file dengan nama executable.shdi direktori saat ini. Apakah itu akan berhasil jika dijalankan $ executeddan .bukan bagian dari PATH?

Leonid
sumber
menyebutkan which <executable>perintah akan bermanfaat di utas ini.
Akuntan

Jawaban:

45

$ PATH dicari dari awal hingga akhir, dengan eksekusi yang cocok pertama dijalankan. Jadi direktori pada awal $ PATH diutamakan daripada yang datang kemudian. File executable di direktori saat ini (.) Hanya dieksekusi jika. ada dalam $ PATH (yang biasanya tidak ). Tidak ada penyertaan implisit dari direktori saat ini di jalur pencarian.

pemain coneslayer
sumber
Sungguh aneh bahwa, $ PATH saya tidak mengandung ., tetapi tampaknya akan mencari dari direktori saat ini terlebih dahulu, sebelum memeriksa direktori yang ditetapkan dalam $ PATH itu sendiri.
Eric Wang
19

Untuk file dalam direktori saat ini, Anda harus mendahului mereka ./, sehingga perintahnya menjadi ./executable.sh. Anda tidak boleh memiliki .di PATH Anda karena menimbulkan risiko keamanan, di antara masalah lainnya.

Direktori yang lebih dulu ada di PATH dan dicari terlebih dahulu.

Urutan keseluruhan untuk pencarian adalah seperti ini jika saya ingat dengan benar:

  • alias

  • fungsi yang diekspor

  • perintah shell bawaan

  • skrip dan binari di PATH Anda

John T
sumber
7
Saya akan menambahkan hash - ingat bash (dan mungkin shell lainnya) menyimpan hash dari perintah yang baru digunakan untuk membuat menemukan mereka lebih mudah. Terkadang Anda harus membersihkan cache (menggunakan hash -r) jika Anda mengubah PATH atau lokasi program Anda.
Rich Homolka
3
+1 untuk urutan pencarian. Akan lebih baik jika Anda dapat mengingat sumber informasi :)
twan163
8

Meskipun ini telah dijawab dengan baik oleh beberapa orang lain, saya ingin menambahkan beberapa pemikiran:

1) PATH hanya dikonsultasikan jika executable yang dipanggil tidak memiliki elemen path di dalamnya. somecommand akan dicari dalam $ PATH, ./somecommandatau /usr/bin/somecommand, atau ../../bin/somecommandhanya menggunakan aturan direktori, bukan PATH

Jika ada beberapa file yang dapat dieksekusi di PATH dengan nama yang sama mana yang lebih disukai?

Itu berhenti pada yang pertama ia temukan, membaca $ PATH kiri ke kanan.

Apakah direktori saat ini termasuk dalam pencarian ketika file dieksekusi?

Jika direktori saat ini di PATH maka itu dicari. Ingatlah bahwa direktori kosong di PATH termasuk direktori saat ini. mis. PATH =: / usr / bin (terkemuka kosong) PATH = / usr / bin: (trailing empty) dan PATH = / usr / bin :: / bin (kosong tengah) semuanya akan secara efektif menyertakan direktori kerja saat ini.

Misalkan ada file dengan nama executable.sh di direktori saat ini. Apakah itu berhasil jika dijalankan $ dieksekusi dan. bukan bagian dari PATH?

Itu tidak akan pernah menemukannya dengan mencari PATH. Jika dir saat ini tidak ada dalam PATH, itu tidak akan menemukannya dengan pencarian PATH.

Yang mengatakan (dan maaf menambah kebingungan) jika ada alias atau fungsi yang menjalankan perintah, itu akan dijalankan. Atau jika shell Anda memiliki cache lokasi, dan file yang dapat dieksekusi ada di dalam cache, ia mungkin menemukannya. Jadi, ia tidak akan pernah menemukannya di PATH, tetapi dapat dijalankan dengan cara lain.

Homolka yang kaya
sumber
Terima kasih atas cachecatatannya, hampir membuat saya gila bahwa executable lama /usr/bin/masih belum digunakan /usr/local/bin, tetapi ada di sebelah kiri $PATHsampai saya log out, dan login lagi.
Akuntan
1
@Akun dalam bash Anda dapat melakukan 'hash -r' untuk menghapus cache shell
Rich Homolka
4

Untuk melihat apa jalur Anda saat ini cukup ketik echo $PATH, atau printenv PATH.

Maka Anda akan tahu urutan pencarian. Jika Anda memiliki banyak file dengan nama yang sama, jalankan ____ mana yang akan dilihat.

Ex.

sistem #> yang grep

/ usr / bin / grep

cara keren untuk menemukan file yang berfungsi seperti target Anda adalah menggunakan apropos:

apropos grep

bzgrep (1) - mencari kemungkinan file terkompresi bzip2 untuk ekspresi reguler

egrep (1) - garis cetak yang cocok dengan suatu pola

fgrep (1) - garis cetak yang cocok dengan suatu pola

grep (1) - garis cetak yang cocok dengan suatu pola

dan seterusnya...

mbb
sumber
2
Oh yeah - Saya lupa fungsi whereis untuk menemukan SEMUA contoh file:> whereis grep
mbb
grep: / bin / grep / usr / bin / grep /usr/share/man/man1/grep.1.gz
mbb
whereismenggunakan daftar lokasi hardcoded, bukan $PATH.
grawity
@grawity Bisakah Anda mengembangkannya?
WinEunuuchs2Unix
-2

@ coneslayer- Urutan default untuk menemukan executable adalah path saat ini, perintah bawaan dan kemudian $ PATH. Jadi jika sebuah fungsi bernama executable sudah ada di pwd, maka itu dieksekusi.

proc
sumber
Jika Anda berbicara tentang cangkang Thompson, cangkang Mashey, atau peninggalan fosil lainnya dari 40 tahun yang lalu, Anda mungkin benar. Tapi tidak ada arus, shell Unix utama mencari direktori saat ini secara otomatis.
Scott
@Scott Jadi jalur pencarian default untuk sebuah perintah pertama kali dibangun dan kemudian $ PATH dan mencari CWD hanya jika saya berikan ./? Apakah saya benar?
proc
Nah, alias, fungsi, dan bawaan. Kemudian, jika Anda menentukan jalur dengan perintah (termasuk ./), itu mencari direktori itu saja; jika tidak, ia mencari $PATH.
Scott