Neden yolsuz çoban köpekleri kullanmıyorsun?


Yanıtlar:


20

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 :

  • Arayanın yürütecek bir programın bir kabuk betiği mi yoksa yerel bir ikili mi olduğu konusunda endişelenmesi gerekmez.
  • Betiğin kendisi arayan yerine hangi tercümanın kullanılacağını belirler.
  • Çekirdek günlüklerde komut dosyası adını kullanır.

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.


2
Hayır, çekirdek execve, shebang'da mutlak bir yol gerektirmez , ancak bir shebang'da bağıl bir yola sahip olmak çok az mantıklıdır.
Stéphane Chazelas

3
“Shebang'ın yürütme çağrısını dahili olarak nasıl yeniden yönlendireceğini” merak eden herkes için: Bu aslında tercümanları ihtiyaç duyan çalıştırıcılarda çalıştırmak için kullanılan genel bir mekanizmanın bir parçası. Dinamik olarak bağlı ELF çalıştırılabilirleri tarafından "yorumlanı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.
Peter Cordes

#! / usr / bin / env -S [shebang], yolunu bilmeden düğümü çalıştırmam için gerekliydi (nvm kullanarak - ki onu beklediğimden farklı bir yere yerleştirir).
TamusJRoyce

-S sadece 8.30'dan beri coreutils ile kullanılabilir. Bkz gitlab.com/gnuwget/wget/commit/... .
Tim Ruehsen rockdaboot

19

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.


4
$ 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.


1
Tam yöne dönüşüm kabuk tarafından yapılır Teşekkürler, yine de ... bunu açıklamak için örnek gerekiyor mu? Gördüğüm gibi, kabuk sadece 2 argümanla (bir noktada stracedönüştürülmüş /usr/bin/strace) çalışıyor.
Alois Mahdal
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.