./ vs. untuk menjalankan program di bawah terminal

13

Saya perlu klarifikasi mengenai cara kita menjalankan executable di bawah terminal. Ini mungkin pertanyaan yang lemah, tetapi apa perbedaan antara menjalankan executable dengan ./an_executabledan . an_executable(misalkan kita berada di dir di mana an_executable berada)

Saya sudah tahu bahwa yang pertama membuat shell mencari an_executable di direktori saat ini ( .), tetapi mengapa tidak /diperlukan setelah .saat menggunakan versi yang terakhir?

Terima kasih sebelumnya.

zipzap
sumber

Jawaban:

22

The . executablesintaks tidak bekerja dengan sembarang executable (atau bukan?). Alih-alih, ini adalah alias untuk bash bawaan source. Jadi perbedaannya sebagian besar relevan dengan skrip bash, dan kebenarannya adalah semuanya benar-benar berbeda :)

./executablememinta untuk menjalankan executable "normal". ./adalah referensi relatif ke jalur saat ini. Ini menghindari memiliki shell (bash) mencoba untuk menemukan executable di direktori di $PATH(yang akan dilakukan jika Anda tidak menentukan path sama sekali dengan perintah). Alasan mengapa Anda tidak bisa begitu saja melakukannya executableadalah karena alasan keamanan; bayangkan Anda membuka kompres arsip yang Anda unduh dan berisi versi jahat ls. Jika dijalankan langsung dari direktori Anda saat ini, Anda akan menjalankan versi itu tanpa disadari.

Di sisi lain, . executablemengatakan "sumber file bernama executable". Karena Anda secara langsung memberi nama file dan itu benar-benar tidak harus dapat dieksekusi, pembatasan keamanan untuk $ PATH tidak berlaku. Sumber hanya akan "menjalankan" (atau tampaknya menjalankan) skrip shell. Apa yang dilakukannya adalah:

   source filename [arguments]
          Read and execute commands from filename  in  the  current  shell
          environment  and return the exit status of the last command exe‐
          cuted from filename.

Jadi ... Apa sebenarnya perbedaan antara mengeksekusi dan sumber? Dengan asumsi skrip shell yang sama, mengeksekusinya ( ./script) akan menelurkan shell baru, menjalankan skrip di dalam shell itu, dan ketika skrip keluar, tutup shell itu dan kembali ke shell induk. Akibatnya, ini akan memulai bashproses baru untuk menjalankan skrip).

( . script) akan menyebabkan shell saat ini membaca perintah dari file seolah-olah sedang diketik di baris perintah. Tidak ada shell baru yang muncul.

Cara yang sangat mudah untuk melihat bagaimana ini berperilaku adalah dengan menulis skrip yang hanya berisi exit. Jika ./scriptya, sepertinya tidak akan terjadi apa-apa, ini karena proses shell baru dimulai, exitperintah keluar dari shell baru dan shell Anda saat ini tidak terpengaruh.

Jika Anda . script, terminal Anda saat ini akan ditutup, karena exitperintah berjalan di shell saat ini. Jadi itu sama dengan mengetik exitpada command prompt.

roadmr
sumber
Memang, saya berurusan dengan skrip shell ketika saya memperhatikan perilaku ini. Terima kasih banyak, itulah jawaban yang saya butuhkan. :)
zipzap
pertanyaan lain muncul (jika Anda tidak keberatan): jika skrip saya berisi hanya beberapa pesan sederhana dengan gema, dan saya menjalankannya dengan ./script, lalu mengapa saya dapat melihat pesan di shell induk jika subkulit ditutup segera setelah eksekusi berakhir?
zipzap
2
Karena sementara subkulit adalah proses terpisah , ia menggunakan terminal yang sama dengan shell yang memohon. Ini mirip dengan bagaimana Anda masih dapat melihat lsoutput: Anda mengetik perintah, itu berjalan, menunjukkan output dan kemudian berakhir, tetapi output tetap di terminal.
roadmr
2
Jangan bingung shell dengan terminal; mereka hal yang berbeda. Buka terminal, dan prompt perintah diberikan oleh abash shell yang berjalan di dalamnya. Jika Anda mengetik bash, Anda akan menjalankan shell lain ; ke shell pertama, itu hanya sebuah program yang akan dijalankan. Jika Anda mengetik exit, Anda akan menutup shell terakhir yang Anda mulai tetapi masih di shell pertama (yang dari saat Anda memulai terminal). Sekali lagi, ini semua terjadi dalam terminal yang sama.
roadmr
1
@ DavidZ saya memang menyebutkannya :) "Sumber hanya akan" menjalankan "(atau tampaknya menjalankan) skrip shell."
roadmr