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 bash
yerine sh
. Kişisel hashbang üst (satır #!/bin/bash
) belirttiğinden bash
sen ama eğer sadece etkilidir yürütmek gibi senaryoyu heemayl açıkladı . Komut dosyasının adını iletirseniz sh
, sh
otomatik 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 chars
bir 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ı for
dö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ı for
dö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
seq
Komut 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 122
a
z
- Güçlü
printf
komut harfler (örn içine karakter kodlarını açabilirsiniz printf '\141'
baskılar a
bir takip yeni satır ), ancak kodları olmalıdır sekizlik ederken, seq
çıkışlar sadece ondalık . Kullandığım Yani printf
iki kere: iç printf %o $i
çevirir (sağladığı sayıyı ondalık seq
sekizlik biçime), ve ikame dış içine printf
komuta. ( Onaltılık kullanmak da mümkün olsa da , daha basit değildir ve daha az taşınabilir gibi görünmektedir .)
printf
yorumlayan ve \
bu kodu ile karakteri olarak sekizlik bir sayı, ardından ve \n
bir 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 n
kaç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 seq
varsayılan olarak yüklenmez ( jot
bunun yerine çoğu GNU / Linux sistemi tarafından varsayılan olarak yüklenmeyen). expr
Gerekirse, 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 while
kapsama 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 n
ve ilk $n
küçü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 n
birç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 $stop
bir daha yüksek , bu yüzden komutla (küçük veya eşit) -lt
yerine -le
( küçüktür) kullanıyorum [
. (Yapmak stop=$((i + n - 1))
ve kullanmak da işe yarardı [ $i -le $stop ]
).