Çalıştırmadan Önce Bir Linux Bash Komut Dosyasının Sözdizimini Doğrulama

Yayınlanan: 2022-06-16
Kırmızı bir zemin üzerinde dizüstü bilgisayar ekranında bir Linux terminali.
fatmawati achmad zaenuri/Shutterstock

Linux Bash komut dosyalarındaki hatalar ve yazım hataları, komut dosyası çalıştırıldığında korkunç şeyler yapabilir. Komut dosyalarınızı çalıştırmadan önce sözdizimini kontrol etmenin bazı yolları.

Bu Sinir bozucu Böcekler

Kod yazmak zordur. Veya daha doğrusu, hatasız, önemsiz olmayan kod yazmak zordur. Ve bir programda veya komut dosyasında ne kadar çok kod satırı varsa, içinde hata olma olasılığı o kadar artar.

Programladığınız dilin bunda doğrudan bir etkisi vardır. Montajda programlama, C'de programlamadan çok daha zordur ve C'de programlama, Python'da programlamadan daha zordur. Programladığınız dil ne kadar düşük seviyedeyse, kendiniz için o kadar çok iş yapmanız gerekir. Python, yerleşik çöp toplama rutinlerinden hoşlanabilir, ancak C ve derleme kesinlikle yapmaz.

"Bilgisayar Hatası" Nedir ve Terim Nereden Gelmiştir?
İLGİLİ "Bilgisayar Hatası" Nedir ve Terim Nereden Gelmiştir?

Linux kabuk komut dosyaları yazmak, kendi zorluklarını ortaya çıkarır. C gibi derlenmiş bir dilde, derleyici adı verilen bir program, kaynak kodunuzu (bir metin dosyasına yazdığınız insan tarafından okunabilen yönergeleri) okur ve onu bir ikili yürütülebilir dosyaya dönüştürür. İkili dosya, bilgisayarın anlayabileceği ve buna göre hareket edebileceği makine kodu talimatlarını içerir.

Derleyici, yalnızca okuduğu ve ayrıştırdığı kaynak kod sözdizimine ve dilin diğer kurallarına uyuyorsa bir ikili dosya oluşturur. Dilin komut sözcüklerinden biri olan ayrılmış bir sözcüğü veya bir değişken adını yanlış yazarsanız, derleyici hata verir.

Bash'de Değişkenlerle Nasıl Çalışılır
İLGİLİ Bash'de Değişkenlerle Nasıl Çalışılır

Örneğin, bazı diller, kullanmadan önce bir değişken tanımlamanız konusunda ısrar ederken, diğerleri o kadar telaşlı değildir. Çalıştığınız dil değişkenleri bildirmenizi gerektiriyorsa ancak bunu yapmayı unutursanız, derleyici farklı bir hata mesajı verecektir. Bu derleme zamanı hataları ne kadar can sıkıcı olsa da, birçok sorunu yakalar ve sizi bunları çözmeye zorlar. Ancak, sözdizimsel hataları olmayan bir programınız olsa bile, bu, içinde hiç hata olmadığı anlamına gelmez. Ne münasebet.

Reklamcılık

Mantıksal kusurlardan kaynaklanan hataları tespit etmek genellikle çok daha zordur. Programınıza iki ve üç toplamasını söylerseniz, ancak gerçekten iki ile ikiyi toplamasını istiyorsanız, beklediğiniz cevabı alamazsınız. Ama program ne yazdıysa onu yapıyor. Programın oluşumunda veya sözdiziminde yanlış bir şey yok. Sorun sensin. İstediğinizi yapmayan iyi biçimlendirilmiş bir program yazdınız.

Test Zordur

Basit bir program bile olsa bir programı baştan sona test etmek zaman alıcıdır. Birkaç kez çalıştırmak yeterli değildir; kodun tüm bölümlerinin doğrulanması için kodunuzdaki tüm yürütme yollarını gerçekten test etmeniz gerekir. Program girdi isterse, kabul edilemez girdiler de dahil olmak üzere tüm koşulları test etmek için yeterli bir dizi girdi değeri sağlamanız gerekir.

Daha yüksek seviyeli diller için birim testleri ve otomatik testler, kapsamlı testlerin yönetilebilir bir alıştırma olmasına yardımcı olur. Soru şu ki, hatasız Bash kabuk komut dosyaları yazmamıza yardımcı olacak herhangi bir araç var mı?

Cevap, Bash kabuğunun kendisi de dahil olmak üzere evet.

Komut Dosyası Sözdizimini Kontrol Etmek İçin Bash Kullanma

Bash -n (noexec) seçeneği, Bash'e komut dosyasını çalıştırmadan bir komut dosyasını okumasını ve sözdizimsel hataları kontrol etmesini söyler. Komut dosyanızın ne amaçladığına bağlı olarak, bu, onu çalıştırmaktan ve sorun aramaktan çok daha güvenli olabilir.

İşte kontrol edeceğimiz senaryo. Karmaşık değildir, esas olarak bir if ifadeleri kümesidir. Bir ayı temsil eden bir sayı ister ve kabul eder. Senaryo, ayın hangi mevsime ait olduğuna karar verir. Açıkçası, kullanıcı hiç girdi sağlamazsa veya rakam yerine harf gibi geçersiz girdi sağlarsa bu işe yaramaz.

 #! /bin/bash

read -p "Bir ay girin (1 ila 12): " ay

# bir şey girdiler mi?
eğer [ -z "$ay" ]
sonra
  echo "Bir ayı temsil eden bir sayı girmelisiniz."
  çıkış 1
fi

# geçerli bir ay mı?
if (( "$ay" < 1 || "$ay" > 12); sonra
  echo "Ay 1 ile 12 arasında bir sayı olmalıdır."
  0 çıkışı
fi

#bahar ayı mı?
if (( "$ay" >= 3 && "$ay" < 6); sonra
  echo "Bu bir Bahar ayı."
  0 çıkışı
fi

# Yaz ayı mı?
if (( "$ay" >= 6 && "$ay" < 9); sonra
  echo "Bu bir Yaz ayı."
  0 çıkışı
fi

# Sonbahar ayı mı?
if (( "$ay" >= 9 && "$ay" < 12); sonra
  echo "Bu bir Sonbahar ayı."
  0 çıkışı
fi

# kış ayı olmalı
echo "Bu bir Kış ayı."
0 çıkışı
Reklamcılık

Bu bölüm, kullanıcının herhangi bir şey girip girmediğini kontrol eder. $month değişkeninin ayarlanmamış olup olmadığını test eder.

 eğer [ -z "$ay" ]
sonra
  echo "Bir ayı temsil eden bir sayı girmelisiniz."
  çıkış 1
fi

Bu bölüm, 1 ile 12 arasında bir sayı girip girmediklerini kontrol eder. Harfler ve noktalama işaretleri sayısal değerlere dönüşmediğinden, rakam olmayan geçersiz girişi de yakalar.

 # geçerli bir ay mı?
if (( "$ay" < 1 || "$ay" > 12); sonra
  echo "Ay 1 ile 12 arasında bir sayı olmalıdır."
  0 çıkışı
fi

Diğer tüm If yan tümceleri, $month değişkenindeki değerin iki değer arasında olup olmadığını kontrol eder. Eğer öyleyse, ay o mevsime aittir. Örneğin, kullanıcı tarafından girilen ay 6, 7 veya 8 ise Yaz ayıdır.

 # Yaz ayı mı?
if (( "$ay" >= 6 && "$ay" < 9); sonra
  echo "Bu bir Yaz ayı."
  0 çıkışı
fi

Örneklerimiz üzerinde çalışmak istiyorsanız, komut dosyasının metnini kopyalayıp bir düzenleyiciye yapıştırın ve "seasons.sh" olarak kaydedin. Ardından, chmod komutunu kullanarak komut dosyasını yürütülebilir hale getirin:

 chmod +x mevsimler.sh 
Bir komut dosyasında yürütülebilir izni ayarlama

Senaryoyu şu şekilde test edebiliriz:

  • Hiçbir girdi sağlama.
  • Sayısal olmayan bir giriş sağlama.
  • 1 ila 12 aralığının dışında bir sayısal değer sağlama.
  • 1 ila 12 aralığında sayısal değerler sağlamak.

Her durumda, betiği aynı komutla başlatırız. Tek fark, kullanıcının komut dosyası tarafından tanıtıldığında sağladığı girdidir.

 ./sezonlar.sh 

Bir komut dosyasını çeşitli geçerli ve geçersiz girdilerle test etme

Bu beklendiği gibi çalışıyor gibi görünüyor. Bash'e betiğimizin sözdizimini kontrol ettirelim. Bunu -n (noexec) seçeneğini çağırarak ve betiğimizin adını ileterek yaparız.

 bash -n ./sezonlar.sh 

Bir betiğin sözdizimini test etmek için Bash kullanma

Reklamcılık

Bu, “hiç haber iyi haber değildir” olgusudur. Bizi sessizce komut istemine döndürmek, Bash'in her şeyin yolunda olduğunu söyleme şeklidir. Senaryomuzu sabote edelim ve bir hata sunalım.

İlk if tümcesinden then zaman öğesini kaldıracağız.

 # geçerli bir ay mı?
if (( "$ay" < 1 || "$ay" > 12); # "sonra" kaldırıldı
  echo "Ay 1 ile 12 arasında bir sayı olmalıdır."
  0 çıkışı
fi

Şimdi betiği önce kullanıcı girdisi olmadan sonra da kullanıcı girdisi ile çalıştıralım.

 ./sezonlar.sh 

Geçersiz ve geçerli girdilerle bir komut dosyasını test etme

Komut dosyası ilk çalıştırıldığında kullanıcı bir değer girmez ve bu nedenle komut dosyası sonlandırılır. Sabote ettiğimiz bölüme bir türlü ulaşılamıyor. Betik, Bash'den bir hata mesajı olmadan sona erer.

Komut dosyası ikinci kez çalıştırıldığında, kullanıcı bir girdi değeri sağlar ve ilk if cümlesi, kullanıcının girdisini akıl sağlığı açısından kontrol etmek için yürütülür. Bu, Bash'ten gelen hata mesajını tetikler.

Bash'in bu yan tümcenin sözdizimini - ve diğer tüm kod satırlarını - kontrol ettiğini unutmayın, çünkü komut dosyasının mantığını umursamaz. Bash komut dosyasını kontrol ettiğinde komut dosyası çalışmadığından kullanıcıdan bir sayı girmesi istenmez.

Komut dosyasının farklı olası yürütme yolları, Bash'in sözdizimini nasıl kontrol ettiğini etkilemez. Bash, her satırın sözdizimini kontrol ederek, komut dosyasının tepesinden altına kadar basit ve metodik bir şekilde çalışır.

ShellCheck Yardımcı Programı

Unix'in en parlak döneminden bir C kaynak kodu kontrol aracı olarak adlandırılan bir linter, programlama hatalarını, biçimsel hataları ve dilin şüpheli veya şüpheli kullanımını tespit etmek için kullanılan bir kod analiz aracıdır. Linterler birçok programlama dili için mevcuttur ve bilgiçlikleriyle tanınırlar. Bir linter'in bulduğu her şey başlı başına bir hata değildir, ancak dikkatinizi çekecek her şey muhtemelen dikkati hak eder.

Reklamcılık

ShellCheck, kabuk komut dosyaları için bir kod analiz aracıdır. Bash için bir linter gibi davranır.

Eksik ve then ayrılmış kelimemizi komut dosyamıza geri koyalım ve başka bir şey deneyelim. İlk if cümlesinden “[” açılış parantezini kaldıracağız.

 # bir şey girdiler mi?
if -z "$ay" ] # açılış parantez "[" kaldırıldı
sonra
  echo "Bir ayı temsil eden bir sayı girmelisiniz."
  çıkış 1
fi

betiği kontrol etmek için Bash kullanırsak bir sorun bulmaz.

 bash -n mevsimler.sh
 ./sezonlar.sh 

Herhangi bir sorun tespit edilmeden sözdizimi denetimini geçen bir komut dosyasından gelen bir hata mesajı

Ancak betiği çalıştırmayı denediğimizde bir hata mesajı görüyoruz. Ve hata mesajına rağmen komut dosyası çalışmaya devam ediyor. Bu yüzden bazı böcekler çok tehlikelidir. Komut dosyasında daha sonra gerçekleştirilen eylemler, kullanıcıdan gelen geçerli girdilere dayanıyorsa, komut dosyasının davranışı tahmin edilemez olacaktır. Verileri potansiyel olarak riske atabilir.

Bash -n (noexec) seçeneğinin komut dosyasındaki hatayı bulamamasının nedeni, “[” açılış parantezinin [ adlı harici bir program olmasıdır. Bash'in bir parçası değil. test komutunu kullanmanın kısa bir yoludur.

Reklamcılık

Bash, bir betiği doğrularken harici programların kullanımını kontrol etmez.

ShellCheck'i Yükleme

ShellCheck kurulum gerektirir. Ubuntu'ya yüklemek için şunu yazın:

 sudo apt shellcheck'i kurun 

Ubuntu'da shellcheck kurulumu

ShellCheck'i Fedora'ya kurmak için bu komutu kullanın. Paket adının karışık durumda olduğunu unutmayın, ancak komutu terminal penceresinde verdiğinizde tümü küçük harflidir.

 sudo dnf ShellCheck'i kurun 

Fedora'ya shellcheck yükleme

Manjaro ve benzeri Arch tabanlı dağıtımlarda pacman kullanıyoruz:

 sudo pacman -S kabuk denetimi 

Manjaro'ya shellcheck yükleme

ShellCheck'i kullanma

Komut dosyamızda ShellCheck'i çalıştırmayı deneyelim.

 shellcheck mevsimler.sh 

ShellCheck ile bir komut dosyasını kontrol etme

ShellCheck sorunu bulur ve bize bildirir ve daha fazla bilgi için bir dizi bağlantı sağlar. Bir bağlantıya sağ tıklayıp açılan içerik menüsünden "Bağlantıyı Aç"ı seçerseniz bağlantı tarayıcınızda açılır.

ShellCheck raporlama hataları ve uyarıları

ShellCheck ayrıca, o kadar ciddi olmayan başka bir sorun bulur. Yeşil metinle bildirilir. Bu, bunun bir uyarı olduğunu, bir hata olmadığını gösterir.

Hatamızı düzeltelim ve eksik olan “[”yi değiştirelim. Bir hata düzeltme stratejisi, önce en yüksek öncelikli sorunları düzeltmek ve daha sonra uyarılar gibi daha düşük öncelikli sorunlara kadar çalışmaktır.

Eksik “[”yi değiştirdik ve ShellCheck'i bir kez daha çalıştırdık.

 shellcheck mevsimler.sh 

ShellCheck ile bir komut dosyasını ikinci kez kontrol etme

Reklamcılık

ShellCheck'in tek çıktısı önceki uyarımıza atıfta bulunuyor, yani bu iyi. Düzeltilmesi gereken yüksek öncelikli sorunlarımız yok.

Uyarı bize -r (olduğu gibi oku) seçeneği olmadan read komutunun kullanılmasının girişteki ters eğik çizgilerin kaçış karakterleri olarak değerlendirilmesine neden olacağını söyler. Bu, bir linter'in üretebileceği bilgiçlik çıktısının türüne iyi bir örnektir. Bizim durumumuzda, kullanıcı yine de ters eğik çizgi girmemelidir - bir sayı girmeleri gerekir.

Bunun gibi uyarılar, programcının bir karar vermesini gerektirir. Düzeltmek için çaba sarf etmek mi yoksa olduğu gibi bırakmak mı? İki saniyelik basit bir düzeltme. Ve ShellCheck'in çıktısını karıştıran uyarıyı durduracak, bu yüzden tavsiyesini alsak iyi olur. read komutundaki bayrakları seçmek için bir “r” ekleyeceğiz ve betiği kaydedeceğiz.

 read -pr "Bir ay girin (1 ila 12): " ay

ShellCheck'i bir kez daha çalıştırmak bize temiz bir sağlık raporu verir.

ShellCheck tarafından bildirilen hata veya uyarı yok

ShellCheck Arkadaşınızdır

ShellCheck, bir dizi sorunu tespit edebilir, raporlayabilir ve tavsiyelerde bulunabilir. Kaç tür sorunu algılayabileceğini gösteren hatalı kod galerisine göz atın.

Ücretsizdir, hızlıdır ve kabuk komut dosyaları yazmaktan çok fazla acı çeker. Sevilmeyecek ne var?