Bir tercümana bir yol belirtmek yerine, tercümanın adını taşıyan ve kabuğun $ PATH üzerinden bulmasını sağlayan bir Shebang olması mümkün mü?
Değilse, bunun bir nedeni var mı?
Bir tercümana bir yol belirtmek yerine, tercümanın adını taşıyan ve kabuğun $ PATH üzerinden bulmasını sağlayan bir Shebang olması mümkün mü?
Değilse, bunun bir nedeni var mı?
Yanıtlar:
PATH araması, genel olarak ortam değişkenleri gibi, kullanıcı alanındaki standart C kütüphanesinin bir özelliğidir. Çekirdek, arayandan execveyeni sürece geçiş yaptığı bir ortam dışında ortam değişkenlerini görmez .
Çekirdek, yolda execve( execvpPATH araması yapmak gibi sarıcı işlevlere bağlıdır ) veya bir shebang'da ( execveçağrıyı içten aşağı yukarı yönlendiren) herhangi bir yorum yapmaz . Bu yüzden mutlak yolu shebang put'a koymanız gerekiyor. Orijinal shebang uygulaması sadece birkaç kod satırları oldu ve önemli ölçüde beri genişletildi edilmemiştir.
Unix'in ilk sürümlerinde, kabuk, bir komut dosyasını çağırdığınızı fark ettiğinde kendisini başlatma işini yaptı. Shebang, birkaç nedenden dolayı çekirdeğe eklendi ( Dennis Ritchie'nin gerekçesini özetleyerek :
Yolsuz shebang'lar, çekirdeğin ortam değişkenlerine ve işlemine erişmesi için artırılmasını PATHveya çekirdeğin PATH aramasını yapan bir kullanıcı alanı programını yürütmesini gerektirir. İlk yöntem, çekirdeğe orantısız miktarda karmaşıklık eklenmesini gerektirir. İkinci yöntem bir #!/usr/bin/envshebang ile zaten mümkün .
Relative Göreceli bir yol koyarsanız, göreceli olarak işlemin geçerli dizinine (betiği içeren dizin değil) yorumlanır.
execve, shebang'da mutlak bir yol gerektirmez , ancak bir shebang'da bağıl bir yola sahip olmak çok az mantıklıdır.
/lib64/ld-linux-x86-64.so.2( lddçıktıya bakınız ). Linux bunu tamamen genel yapar: binfmtdestek (2.1.43'ten beri) tercüman yolu / büyü numarası veya dosya uzantısı çiftlerini kaydetmenizi sağlar. Bunları çalıştırdığınızda PE32 .exelerin çağrılmasını wine, Java sınıfının ve jar dosyalarını çağırmanın java, vb. Vb.
Göze göründüğünden daha fazlası var. #!çizgiler Unix veya Linux çekirdeği tarafından yorumlanır #!, kabukları bir yönü değildir. Bu PATH, çekirdeğin neyi yürüteceğine karar verdiği sırada gerçekten bulunmadığı anlamına gelir .
Hangi çalıştırılabilir dosyayı çalıştıracağınızı veya perltaşınabilir şekilde veya benzer şekilde çağrı yapmayı bilmemekle uğraşmanın en yaygın yolu kullanmaktır #!/usr/bin/env perl. /usr/bin/envBir PATHortam değişkenini miras alan çekirdek çalıştırır . env(bu örnekte) buluntular perlolarak PATHkullanır ve execve(2)sistem çağrıyı çalıştırmak için çekirdek almak için perlçalıştırılabilir.
$ strace sleep 1
execve("/usr/bin/sleep", ["sleep", "1"], [/* 99 vars */]) = 0
Tam yola dönüşüm kabuk tarafından yapılır (daha genel: Kullanıcı alanında). Çekirdek, doğrudan erişebileceği bir dosya adı / yolu bekler.
Sistemin PATH değişkenine bakarak yürütülebilir dosyasını bulmasını istiyorsanız, shebang'ınızı olarak yeniden yazabilirsiniz #!/usr/bin/env EXEC.
Ancak bu durumda da aramayı yapan çekirdek değil.
stracedönüştürülmüş /usr/bin/strace) çalışıyor.