2017-01-25 62 views
5

Eski meslektaşım tarafından bash'da yazılmış bir proje üzerinde çalışırken, tüm .sh dosyalarının hiçbir şey içermediğini fark ettim ama fonksiyon tanımları #!/bin/false ile başlıyor, yani anladığım kadarıyla, yalnızca dahil dosyaların yürütülmesini önleyen bir güvenlik mekanizması.Başhekimliğinde #!/Bin/false 'in amacı

Örnek:

#!/bin/false 
function foo(){ 
    echo foontastic 
} 

my_script.sh

#!/bin/bash 

./my_foo.sh # does nothing 
foo # error, no command named "foo" 

. ./my_foo.sh 
foo # prints "foontastic" 

Ancak #!/bin/false kullanmadığınızda

my_foo.sh, hem doğru ve yanlış kullanımının etkileri tam olarak aynı:

Örnek:

my_bar.sh

function bar(){ 
    echo barvelous 
} 

my_script.sh

#!/bin/bash 

./my_bar.sh # spawn a subshell, defines bar and exit, effectively doing nothing 
bar # error, no command named "bar" 

. ./my_bar.sh 
bar # prints "barvelous" 

yana düzgün beklenen işleri olarak her iki durumda da source onlara ekleyerek bu komut dosyalarını kullanarak ve bunları yürütme Her iki durumda da bir ebeveyn kabuğunun perspektifinden hiçbir şey yapmaz ve geçersiz kullanımla ilgili bir hata mesajı üretmez, tam olarak bu betikteki #!/bash/false'un amacı nedir? üst kabuğun açısından #!/bin/false veya kullanarak

+2

geçerli: 'FALSE shebang ile, içerik yürütülmez. Yanlış bağlamda kullanıldığında ya da ağır kaynaklandığında betiğin hataya açık olması güvenliktir. Muhtemelen, meslektaşınızın yakaladığı, çoğu durumda kod üzerinde hiçbir etkisi olmayan, ancak daha karmaşık durumlarda yararlı olabilecek bir alışkanlıktır. – Aserre

+0

Aynı zamanda, kabuk yorumlayıcısını doğrudan 'bash my_script.sh' olarak çağırdığınızda, "#!/Bin/true" veya "#!/Bin/false" gibi kuyruk satırlarının betik üzerinde hiçbir etkisi olmadığı dikkate alınmalıdır. ', bu sözdizimi 'bash' ile ne olursa olsun betiği çalıştırır ve 'foontastic' foontastic ' – Inian

+2

'/my_bar.sh' bir yankı ortaya çıkarmaz: yepyeni bir kabuk oluşturur. Bu sadece bir teknik değildir: alt kabuklar ana kabuktaki tüm değişkenlerin (dışa aktarma için işaretlenmemiş olanlar dahil) bir kopyasını alırken, ayrı bir kabuk yalnızca dışa aktarılan değişkenleri alır. Alt kümeler, örneğin, parantezler '()' ibaresiyle, '|', process/command substitution '$()' '<()' '>()' komutunu ekleyerek diğer şekillerde başlatılır. – Fred

cevap

4

, bu

onunla üç farklı şeyler yapabilirsiniz içinde en bash koduyla bir dosya testcode düşünelim:

$ ./testcode 
You are executing ./testcode 

Bu deneme kodunda doğru izinlere ve varsa çalışır sağ shebang. #!/bin/false bir shebang ile, bu hiçbir şey verir ve 1 (yanlış) bir kod döndürür.

$ bash ./testcode 
You are executing ./testcode 

Bu tamamen (hatta eksik olabilir) shebang göz ardı ve sadece okunur izni, değil çalıştırılabilir izin gerektirir. Windows'da bir CMD komut satırından bash komut dosyalarının (yolunuzda bash.exe varsa ...) basma yolu budur, çünkü şaşkınlık machanizmi çalışmaz.

$ . ./testcode 
You are sourcing ./testcode 

Bu da tamamen yukarıdaki gibi shebang göz ardı eder, ama bir komut dosyası yürütme ise , geçerli kabuk o yürütmek zorunda anlamına gelir, bir komut dosyası kaynak çünkü, tam bir farklı bir konudur başvurmalarını demektir Bunu yürütmek için yeni bir kabuk. Örneğin, bir kaynak kodda bir exit komutunu koyarsanız, geçerli kabuktan çıkacaksınız, bu da nadiren istediğiniz gibi. Bu nedenle, kaynak kullanımı genellikle, diğer programlama dillerinin import ifadesine benzeyen bir şekilde, işlev tanımlarını veya sabitleri yüklemek için kullanılır ve çeşitli programcılar, çalıştırılmak istenen komut dosyaları arasında ayrım yapmak için farklı alışkanlıklar geliştirir ve , kaynaklanacak dosyalarını içerir. Genellikle eski için herhangi bir uzantı kullanmıyorum (diğerleri .sh kullanıyor), ancak ikincisi için .shinc uzantısını kullanıyorum. Eski meslektaşınız, #!/bin/false no'lu bir shebang kullandı ve bunlardan sadece bunu neden başka bir zillion seçeneğine tercih ettiklerini sorabilirsiniz. Aklıma gelen bir nedeni ayrı bu dosyaları anlatmak için file kullanabilirsiniz olmasıdır: Elbette

$ file testcode testcode2 
testcode: Bourne-Again shell script, ASCII text executable 
testcode2: a /bin/false script, ASCII text executable 

, bu dosyalar tek fonksiyon tanımlarını içerir eklerseniz, bunları çalıştırmak için zararsızdır, böylece sanmıyorum İş arkadaşınız yürütmeyi engelledi.

Python dünyada esinlenerek benim başka alışkanlık, (gelişmekte en az iken) return yana

... function definitions here ... 

[ "$0" != "${BASH_SOURCE[0]}" ] && return 

... regression tests here ... 

infaz komut bir hata üretir benim .shinc dosyaların sonunda bazı regresyon testleri yerleştirmektir ama kaynaklı komut Tamam, aynı sonucu elde etmek için daha şifreli yolu Sen kendin söyledin

... function definitions here ... 

return 2>/dev/null || : 

... regression tests here ... 
1

fark dönüş kodu bulunmaktadır.

/bin/false

hep (benim durumumda 1'de, ancak standart olup olmadığından emin değil) başarısız kodu döndürmez. #!/bin/false komut yürütülecek tasarlanmamıştır olduğunu belgelemektedir sadece kullanarak Yani

./my_foo.sh //does nothing 
echo $? // shows "1", a.k.a failing 

./my_bar.sh //does nothing 
echo $? // shows "0", a.k.a. everything went right 

ama bunu yaparken de bir hata dönüş kodu üretir:

olduğunu deneyin. Genelde

+0

Eğer my_bar.sh "exit 1" içeriyorsa, ikinci örneğiniz doğru değil. Ayrıca yürütme yerine bu dosyaları dahil ederken (". ./my_foo", ". ./my_bar") dönüş değeri aslında son çalıştırılan komutun bir dönüş değeridir, bu yüzden geri dönüş değerlerini koruma olarak kullanmak için hepsini bitirmem gerekir "true" ile sadece komut dosyalarını içerir. –

+0

OP tarafından sağlanan "my_bar.sh" betiği bir "exit" komutu içermiyor. Ayrıca, dönüş kodu sadece komut dosyasının dönüş kodudur. '#!/Bin/false' kullanıldığında hatalı bir dönüş kodu oluşacaktır. –

+0

Kılavuza göre: 'false - hiçbir şey yap, başarısız' – ash