Jawaban:
Mungkin untuk menjaga agar kernel lebih sederhana. Saya tidak berpikir kernel pernah mencari jalan Anda untuk menemukan executable. Itu ditangani oleh perpustakaan C. #!
pemrosesan dilakukan di kernel, yang tidak menggunakan pustaka C standar.
Juga, saya tidak berpikir kernel memiliki gagasan tentang apa path Anda. $PATH
adalah variabel lingkungan, dan hanya proses yang memiliki lingkungan. Kernel tidak. Saya kira itu bisa mengakses lingkungan proses yang melakukan exec, tapi saya tidak berpikir apa pun saat ini di kernel pernah mengakses variabel lingkungan seperti itu.
Anda bisa mendapatkan PATH
-menggunakan semantik menggunakan env
, jadi:
#!/usr/bin/env ruby
memiliki semantik yang Anda inginkan
#!ruby
Alasan yang bergantung pada PATH
tidak dianggap praktik yang baik adalah bahwa skrip tidak dapat membuat asumsi tentang konten variabel lingkungan PATH, melanggar "model ketergantungan berurutan" dari biner di mana
/bin
berisi file executable yang dibutuhkan saat boot;/usr/bin
berisi file executable lain yang digunakan oleh instalasi OS;/usr/local/bin
berisi executable yang diinstal oleh administrator sistem yang bukan bagian dari OS dasar.~/bin
berisi file executable milik pengguna.Setiap level tidak boleh mengasumsikan keberadaan binari kemudian dalam urutan, yang lebih "aplikasi" tetapi mungkin bergantung pada binari sebelumnya, yang lebih "mendasar". Dan variabel PATH cenderung berjalan dari aplikasi ke fundamental, yang merupakan arah yang berlawanan dengan ketergantungan alami di atas.
Untuk mengilustrasikan masalah, tanyakan pada diri sendiri apa yang terjadi jika sebuah skrip ~/bin
memanggil skrip /usr/local/bin
yang memanggil Ruby? Haruskah skrip itu bergantung pada versi yang diinstal OS pada /usr/bin/ruby
, atau pada salinan pribadi yang kebetulan dimiliki oleh pengguna ~/bin/ruby
? PATH
pencarian memberikan semantik tak terduga yang terkait dengan yang terakhir (mungkin ~/bin/ruby
merupakan tautan simbolis yang rusak), sambil memanggang di jalur untuk #!
memberikan yang pertama.
Sebenarnya tidak ada "sistem operasi ... platform-independen informasi tentang jalur untuk perintah terdaftar", jadi hal yang paling sederhana adalah bersikeras jalur yang disediakan di #!
.
Saya percaya itu sehingga Anda dapat menentukan penerjemah alternatif jika Anda butuh atau mau. Sebagai contoh:
#!/home/user/myrubyinterpreter
Lebih sering terlihat dengan skrip shell:
#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
Dari buku Classic Shell Scripting :
Skrip shell biasanya dimulai dengan
#! /bin/sh
. Gunakan path ke shell yang sesuai dengan POSIX jika Anda/bin/sh
tidak mematuhi POSIX. Ada juga beberapa "gotcha" tingkat rendah yang harus diperhatikan:
- Anda harus mengetahui pathname lengkap untuk penerjemah yang akan dijalankan. Ini dapat mencegah portabilitas cross-vendor, karena vendor yang berbeda meletakkan barang-barang di tempat yang berbeda (misalnya,
/bin/awk
versus/usr/bin/awk
).
Ada alasan lain, tetapi dari sudut pandang keamanan saya tidak akan pernah ingin skrip membuat asumsi tentang jalur yang benar. Bagaimana jika itu salah dan menjalankan shell atau penerjemah yang salah? Salah satu yang telah dimasukkan oleh pengguna jahat? Atau bagaimana jika itu bergantung pada shell tertentu dan akan crash jika shell yang salah digunakan?
Pengguna mungkin dipusingkan dengan jalur mereka dan memecahkan barang - jangan percayai pengguna :-) Saya telah melakukan banyak serangan yang bergantung pada pengguna melakukan hal yang salah dengan jalur mereka - biasanya mendapatkan sesuatu dalam urutan yang salah - sehingga saya dapat menumbangkan panggilan skrip normal.
Ya, saya tahu jika Anda sendiri yang menulis skrip, Anda dapat mengklaim bahwa Anda telah menyortir jalan Anda sendiri, tetapi seorang penerjemah tidak dapat membuat keputusan itu.
$PATH
. . Tanpa hak yang lebih tinggi, bagaimana jika LD_PRELOAD
digunakan? PS Downvoted karena memberikan peringatan palsu tentang keamanan merugikan keamanan.
PATH
vektor serangan, dan tidak ada banyak vektor serangan lain sehingga seluruh pendekatan harus dipikirkan kembali?
ruby
, tetapi itu tidak menghentikan Anda untuk menentukan/home/user/myrubyinterpreter
jika Anda mau