Betiğiniz, Bash kabuğunun tüm Bourne tarzı kabuklar tarafından sağlanmayan üç özelliğini kullanır. Gibi heemayl diyor , sadece birlikte o senaryoyu çalıştırabilirsiniz bashyerine sh. Kişisel hashbang üst (satır #!/bin/bash) belirttiğinden bashsen ama eğer sadece etkilidir yürütmek gibi senaryoyu heemayl açıkladı . Komut dosyasının adını iletirseniz sh, shotomatik olarak çağrılamaz bash, ancak komut dosyasını çalıştırır. Bunun nedeni , komut dosyanız gerçekten çalıştığında, hashbang satırının bir etkisi olmamasıdır .
Bash özelliklerine bağlı olmayan tamamen taşınabilir komut dosyaları yazmanız gerekiyorsa, diğer alternatifiniz komut dosyasını, onlarsız çalışacak şekilde değiştirmektir. Kullandığınız Bash özellikleri:
- Bir dizi . Bu önce geldi, bu yüzden komut dosyanızı Dash kabuğu ile çalıştırmaya çalıştığınızda hatayı üreten şey buydu .
( {a..z} )Atadığınız parantez içinde ifade charsbir dizi oluşturur ve döngünüzde ${chars[i]}görünen parantez içinde dizine eklenir.
- Brace genişlemesi. Bash'de ve diğer birçok mermide
{a..z}de genişler a b c d e f g h i j k l m n o p q r s t u v w x y z. Ancak, bu Bourne tarzı mermilerin evrensel (veya standartlaştırılmış) bir özelliği değildir ve Dash bunu desteklemez.
- C stili alternatif
for - döngü sözdizimi . Dayalı olsa da aritmetik genişleme olduğunu Bash özgü olmayan kendisi (bazı olsa çok eski olmayan POSIX uyumlu kabukları ya o yok), C tarzı fordöngü olduğunu bir Bash-izm ve yaygın taşınabilir değildir diğer mermiler.
Bash, özellikle Ubuntu gibi GNU / Linux sistemlerinde yaygın olarak bulunur ve (gördüğünüz gibi) macOS ve diğer birçok sistemde de mevcuttur. Bash'e özgü özellikleri ne kadar kullandığınızı göz önünde bulundurarak, bunları kullanmak isteyebilirsiniz ve komut dosyalarını çalıştırırken Bash'i (veya kullandığınız özellikleri destekleyen başka bir kabuğu) kullandığınızdan emin olun.
Ancak, isterseniz bunları taşınabilir yapılarla değiştirebilirsiniz. Dizi ve C tarzı fordöngü kolayca değiştirilebilir; küme ayracı genişletme olmadan (ve bunları kodunuzda sabit kodlamadan) harf aralığını oluşturmak biraz zor olan tek bölümdür.
İlk olarak, tüm küçük Latin harfleri yazdıran bir komut dosyası:
#!/bin/sh
for i in $(seq 97 122); do
printf "\\$(printf %o $i)\n"
done
seqKomut sayısal dizileri oluşturur. Komut yerine$( ) koyma gerçekleştirir , bu nedenle yerine çıktı alır . Bunlar karakter kodları için içinden .$(seq 97 122)seq 97 122az
- Güçlü
printfkomut harfler (örn içine karakter kodlarını açabilirsiniz printf '\141'baskılar abir takip yeni satır ), ancak kodları olmalıdır sekizlik ederken, seqçıkışlar sadece ondalık . Kullandığım Yani printfiki kere: iç printf %o $içevirir (sağladığı sayıyı ondalık seqsekizlik biçime), ve ikame dış içine printfkomuta. ( Onaltılık kullanmak da mümkün olsa da , daha basit değildir ve daha az taşınabilir gibi görünmektedir .)
printfyorumlayan ve \bu kodu ile karakteri olarak sekizlik bir sayı, ardından ve \nbir satır olarak. Ancak kabuk aynı zamanda \bir kaçış karakteri olarak da kullanılır . Bir \önünden $önleyecektir $gelen oluşmaya yayılmasına neden (bu durumda, içinde komut ikamesi ), ama bunu önlemek istemiyorum, ben başka bir ile kaçmış yüzden \; nedeni budur \\. Daha \önce ikincisinin nkaçmasına gerek yoktur, çünkü aksine \$, \nçift tırnaklı bir dizgideki kabuk için özel bir anlamı yoktur.
- Kabuk programlamada çift tırnak ve ters eğik çizginin nasıl kullanıldığı hakkında daha fazla bilgi için , uluslararası standartta alıntı bölümüne bakınız . Ayrıca bakınız 3.1.2 aktaran içinde Bash Referans Kılavuzuna özellikle, 3.1.2.1 Kaçış Karakter ve 3.1.2.3 Çift Alıntılar . (İşte tüm bölüm , bağlamda.) Tek tırnak (
') da kabuk tırnak sözdiziminin önemli bir parçası olduğunu unutmayın, ben sadece bunları bu komut dosyasında kullanmadım.
Bu, Unix benzeri sistemlerin çoğunda taşınabilir ve hangi Bourne tarzı kabuğu kullandığınıza bağlı değildir. Bununla birlikte, birkaç Unix benzeri sistem seqvarsayılan olarak yüklenmez ( jotbunun yerine çoğu GNU / Linux sistemi tarafından varsayılan olarak yüklenmeyen). exprGerekirse, taşınabilirliği daha da artırmak için bir döngü veya aritmetik değiştirme kullanabilirsiniz:
#!/bin/sh
i=97
while [ $i -le 122 ]; do
printf "\\$(printf %o $i)\n"
i=$((i + 1))
done
Bu, yalnızca whilekapsama alanındayken döngüye devam etmek için [komutla birlikte bir -loop kullanır $i.
Komut dosyanızın tamamını yazdırmak yerine, bir değişken tanımlar nve ilk $nküçük harfleri yazdırır . Komut dosyanızın Bash'a özgü hiçbir özelliğe dayanmayan ve Dash üzerinde çalışan, ancak aşağıdakileri gerektiren bir sürümü seq:
#!/bin/sh
n=3 start=97
for i in $(seq $start $((start + n - 1))); do
printf "\\$(printf %o $i)\n"
done
Değerini ayarlama nbirçok mektup senin senaryosunda olduğu gibi yazdırılır şeklindeki değişiklikler.
İşte gerektirmeyen bir sürüm seq:
#!/bin/sh
n=3 i=97 stop=$((i + n))
while [ $i -lt $stop ]; do
printf "\\$(printf %o $i)\n"
i=$((i + 1))
done
Orada, yazdırılması gereken son harfin karakter kodundan $stopbir daha yüksek , bu yüzden komutla (küçük veya eşit) -ltyerine -le( küçüktür) kullanıyorum [. (Yapmak stop=$((i + n - 1))ve kullanmak da işe yarardı [ $i -le $stop ]).