Ubuntu-OSX uyumluluğu ve kullanım kolaylığı için #! / Bin / sh veya #! / Bin / bash kullanın & POSIX


18

İstediğim kabuğu çağırmak için komut dosyalarının ilk satırı olarak kullanabileceğimi biliyorum.

Misiniz #!/bin/shtüm Unix sistemleri ile uyumluluk mutlak gereklilik ise tavsiye edilebilir?

Benim durumumda önemsediğim tek işletim sistemi Ubuntu (Debian) ve OSX. Bu göz önüne alındığında #!/bin/bash, her iki sistemde de işe yarayacağından emin olabilir miyim ?
Bu aynı zamanda komutlar için daha modern ve daha açık sözdizimine sahip komut dosyalarını kullanmayı kolaylaştırır mı? #!/bin/shKullanmak POSIX kullanmakla da ilgili mi?


1
Muhtemelen birçok dağıtımın birleşmeye başladığını /binve /usr/bin. Sonuç olarak, #!/usr/bin/env <shname>bu günlerde taşınabilirlik için kullanmak muhtemelen daha iyidir .
HalosGhost

Yanıtlar:


15

Yeni başlayanlar için, Bash'in önceden kurulu olduğu varsayımını yapabiliyorsanız (ki bence listelediğiniz tüm sistemlerde böyledir), uyumlu olmak için aşağıdaki hashbang'ı kullanın:

#!/usr/bin/env bash

bu bash, içinde /binveya dışında olsun, yapılandırılacak her şeyi başlatır /usr/local/bin.

Geniş bir aralıktaki çoğu sistemde (AIX, Solaris, çeşitli BSD lezzetleri dahil), bashfarklı yerlerde envsona erdi , her zaman sonuçlandı /usr/bin/env. Ancak hile benim değil Bash Yemek Kitabı'nın yazarı.

Her neyse, evet Bash hayatınızı kolaylaştıran bazı "modern" özellikleri kullanmanızı sağlar.

Örneğin çift parantez:

[[ -f "/etc/debian_version" ]] && echo "This is a Debian flavor"

oysa geleneksel kabuk ağızlarında:

test -f "/etc/debian_version" && echo "This is a Debian flavor"

ancak çift parantez ile ilgili en iyi şey, eşleşme için düzenli ifadelere izin vermesidir. Bash Hackerlar Wiki o yönde size birçok hileler verecektir.

Ayrıca $((2**10)), $((expression))sözdizimi ile aynı olan oldukça uygun ifadeleri veya diğer aritmetik ifadeleri kullanabilirsiniz .

Subshells için backticks kullanmak biraz modası geçmiş olsa da iyidir. Ancak, $(command ...)farklı alt kabuk seviyelerinde birçok şeyden kaçmak zorunda kalmayacağınız için , invokasyonların yuvalama özellikleri çok daha uygundur.

Bunlar, Bash'in geleneksel ortak POSIX shsözdizimi üzerinde verdiği birkaç şeydir .

Ancak kabukta daha fazla güç istiyorsanız (sadece komut dosyalarında değil), ayrıca bir göz atın zsh.


Bash çok kullanışlı bir araçtır, ancak Bash komut dosyası hatalarına karşı savunmasız olabilecek hizmetleri başlatmak için kullanmamaya dikkat edin, örneğin access.redhat.com/security/cve/CVE-2014-6271 . Bu shtür görevler için sadık kalın.
Rick-777

1
Rick-777, güvenlik açığının büyük ölçüde abartılı olduğunu ve benim görüşüme göre FUD olduğunu düşünüyorum. Bir sistem hizmeti bash altında çalışırsa hiçbir şekilde bu hataya karşı savunmasız değildir. Bu hataya, uzak kullanıcıların FastCGI gibi bir veya daha fazla ortam değişkenine doğrudan erişmesine izin verirken ve hatta yalnızca bash'ın eklenmemiş sürümlerinde doğrudan erişmesine izin verirse, bu hataya karşı savunmasızdır. shBağlantılı sistemlerde bash, güvenlik açığı kullanılarak azaltılmaz sh.
Score_Under

11

Debian ve Ubuntu olarak, /bin/sholan dashbir POSIX uyumlu kabuk olan. Belirtirseniz #!/bin/sh, kendinizi kodunuzdaki POSIX ifadeleriyle sınırlamanız gerekir. (Avantajı dashdaha hızlı başlar bash, böylece betiğiniz işini daha kısa sürede yapabilir.)

Birçok (en?) Diğer Linux sistemlerinde, /bin/sholduğu bashbirçok komut ile yazılır neden olan #!/bin/shkullandıkları halde onların shebang çizgi olarak bashuzantıları.

bashUzantıları kullanmak istiyorsanız , tüm sistemlerde en güvenli yaklaşım belirtmektir #!/bin/bash; bu şekilde bağımlılığınızı açıkça belirtirsiniz bash. Bunu Debian ve Ubuntu'da yapmanız gerekiyor . Ek bir avantaj olarak, /bin/sh bashbazı uzantıları devre dışı bıraktığında ( ayrıntılar için POSIX modunun açıklamasınabash bakın); #!/bin/bashtam olarak yararlanmak için belirtmek gerekir bash.

OS X'te /bin/bashde mevcuttur ve /bin/shkullanılabilir bash. Belirleme #!/bin/bashorada da iyi çalışacaktır.


5

Evet, hem OSX hem de Linux gelecek /bin/bash. Çok güvenli olmalısın. Ancak, bu POSIX değildir . POSIX kabuğu /bin/shçoğu (tümü?) Sistemlerde bulunur ve bu en taşınabilir yaklaşımdır ve POSIX uyumlu olmanın tek yoludur.

Birçok sistemde /bin/shişaret ederken bash, diğerlerinde farklı kabukları gösterebileceğini unutmayın. dashÖrneğin Debian ve Ubuntu için bir sembolik bağlantı . Ayrıca, /bin/shbir bağlantı olsa bile bash, kabuğun davranışı, sh( man bashbenimki vurgudan) olarak adlandırıldığında değişir :

Bash sh adıyla çağrılırsa, POSIX standardına da uyurken, sh'in eski sürümlerinin başlatma davranışını mümkün olduğunca yakından taklit etmeye çalışır. Etkileşimli bir giriş kabuğu veya --login seçeneğiyle etkileşimli olmayan bir kabuk olarak çağrıldığında, önce / etc / profile ve ~ / .profile komutlarını bu sırayla okumaya ve yürütmeye çalışır. --Noprofile seçeneği bu davranışı engellemek için kullanılabilir. Sh adıyla etkileşimli bir kabuk olarak çağrıldığında, bash ENV değişkenini arar, varsa değerini genişletir
genişletilmiş değeri okumak ve yürütmek için bir dosyanın adı olarak kullanır. Sh olarak çağrılan bir kabuk başka herhangi bir başlangıç ​​dosyasındaki komutları okumaya ve yürütmeye çalışmadığından, --rcfile seçeneğinin bir etkisi yoktur. Sh adıyla çağrılan etkileşimli olmayan bir kabuk, başka herhangi bir başlangıç ​​dosyasını okumaya çalışmaz. Sh olarak çağrıldığında, başlangıç ​​dosyaları okunduktan sonra bash posix moduna girer.


2

"Tüm Unix sistemleri" ile uyumluluk mutlak bir gereklilikse - ve değilse, neden bir kabuk betiği yazıyorsunuz? - o zaman evet, kullandığınız olmalıdır #! /bin/shBash yüklü olması garanti edilmez, çünkü her yerde dursun içinde, /bin.

Aslında bundan çok, çok daha kötü. 1995'te kabuk ortamlarını donduran Solaris ve AIX gibi şeyleri içeren tüm Unix sistemleriyle uyumluluğa ihtiyacınız varsa . Bu, eski moda sözdizimi gibi şeyleri kullanmanız gerektiği anlamına gelir - yeni sistemler düştü! Ve ayrıca kabuk işlevleri, diziler yok , hayır , hayır , aritmetik için hayır , muhtemelen stil olmayan komut ikamesi, büyük girdinin nasıl elde edilebileceğine dair küçük ve belgesiz üst sınırlar, ...sort +N[[ ... ]]${foo#glob}$(( ... ))$( ... )

Muhtemelen bu kadar uyumluluktan rahatsız olmamaktan kurtulabilirsiniz , ancak ilk etapta bir sorun olsa bile, kabuğundan daha az korkunç bir dili düşünmenizi şiddetle tavsiye ederim. Temel Perl yorumlayıcısının Bash'ten elde edilebilir olması daha olasıdır.


Teşekkürler. Başlangıçta belirtildiği gibi "Benim durumumda önemsediğim tek işletim sistemi Ubuntu (Debian) ve OSX." Bunlar son 5 yıl içinde kullandığım (ve onları çok kullanıyorum) tek 2 sistem, bu yüzden 'neden' sadece üzerinde çalışacak bir kabuk komut dosyası yazıyorum. Evrensel bir senaryoya ve sunacağı kısıtlamalara hiç ihtiyacım yok.
Michael Durrant

@MichaelDurrant Bu durumda, bir kabuk komut dosyası yazmanıza gerek yoktur ve olmamalıdır. Bunun yerine, toplam taşınabilirliğe ihtiyacınız olmadığında bir seçenek olan çok sayıda daha iyi komut dosyası dilinden birini kullanmalısınız .
zwol
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.