Tipik zorunlu programlamada , talimat dizileri yazarsınız ve bunlar açık kontrol akışı ile birbiri ardına yürütülür. Örneğin:
if [ -f file1 ]; then # If file1 exists ...
cp file1 file2 # ... create file2 as a copy of a file1
fi
vb.
Örnekte görülebileceği gibi, zorunlu programlamada yürütme akışını kolayca takip edersiniz, verdiğiniz herhangi bir komutun bir sonucu olarak yürütüleceğini bilerek, yürütme bağlamını belirlemek için her zaman herhangi bir kod satırından yukarı doğru ilerlersiniz. akıştaki konum (veya işlevleri yazıyorsanız arama sitelerinin konumlarını).
Geri aramalar akışı nasıl değiştirir?
Geri aramalar kullandığınızda, bir dizi talimatı "coğrafi olarak" kullanmak yerine, ne zaman çağrılacağını açıklarsınız. Diğer programlama ortamlarındaki tipik örnekler, “bu kaynağı indir ve indirme tamamlandığında bu geri aramayı çağırın” gibi durumlardır. Bash'in bu türden genel bir geri arama yapısı yoktur, ancak hata yönetimi ve diğer bazı durumlar için geri çağrıları vardır ; örneğin (bu örneği anlamak için önce komut değiştirme ve Bash çıkış modlarını anlamak gerekir):
#!/bin/bash
scripttmp=$(mktemp -d) # Create a temporary directory (these will usually be created under /tmp or /var/tmp/)
cleanup() { # Declare a cleanup function
rm -rf "${scripttmp}" # ... which deletes the temporary directory we just created
}
trap cleanup EXIT # Ask Bash to call cleanup on exit
Bunu kendiniz denemek istiyorsanız, yukarıdakileri bir dosyaya kaydedin, diyelim ki cleanUpOnExit.sh
çalıştırılabilir yapın ve çalıştırın:
chmod 755 cleanUpOnExit.sh
./cleanUpOnExit.sh
Buradaki kodum asla açıkça cleanup
işlevi çağırmaz; Bash'e ne zaman çağrılacağını söyler trap cleanup EXIT
, yani “sevgili Bash, lütfen cleanup
çıktığınızda komutu çalıştırın ” (ve cleanup
daha önce tanımladığım bir işlev olur, ancak Bash'in anladığı her şey olabilir). Bash bunu tüm ölümcül olmayan sinyaller, çıkışlar, komut hataları ve genel hata ayıklama için destekler (her komuttan önce çalıştırılacak bir geri arama belirleyebilirsiniz). Buradaki geri arama cleanup
, Bash tarafından kabuk çıkmadan hemen önce "geri çağrılan" işlevdir.
Bash'in kabuk parametrelerini komut olarak değerlendirme yeteneğini, geri arama odaklı bir çerçeve oluşturmak için kullanabilirsiniz; bu, bu cevabın kapsamının biraz ötesindedir ve etrafta dolaşmanın her zaman geri aramalar içerdiğini düşündürerek belki de daha fazla karışıklığa neden olur. Temel işleve bazı örnekler için bkz. Bash: bir işlevi parametre olarak iletme. Buradaki fikir, olay işleme geri çağrılarında olduğu gibi, işlevlerin verileri parametre olarak alabileceği gibi, diğer işlevler de - bu, arayanların verilerin yanı sıra davranış sağlamasına da izin verir. Bu yaklaşımın basit bir örneği,
#!/bin/bash
doonall() {
command="$1"
shift
for arg; do
"${command}" "${arg}"
done
}
backup() {
mkdir -p ~/backup
cp "$1" ~/backup
}
doonall backup "$@"
( cp
Birden fazla dosyayla başa çıkabildiğinden, bunun biraz işe yaramaz olduğunu biliyorum , sadece örnekleme amaçlıdır.)
Burada doonall
parametre olarak verilen başka bir komutu alan ve parametrelerinin geri kalanına uygulayan bir fonksiyon yaratıyoruz ; backup
bunu, betiğe verilen tüm parametrelerde işlevi çağırmak için kullanırız . Sonuç, tüm bağımsız değişkenlerini birer birer yedek dizine kopyalayan bir komut dosyasıdır.
Bu tür bir yaklaşım, işlevlerin tek sorumluluklarla yazılmasına izin verir: doonall
'nin sorumluluğu, tüm argümanlarında birer birer birer şey yürütmektir; backup
'nin sorumluluğu, (bağımsız) argümanının bir kopyasını bir yedekleme dizininde oluşturmaktır. Her ikisi de doonall
ve backup
daha fazla kod yeniden kullanımı, daha iyi testler vb. Sağlayan diğer bağlamlarda kullanılabilir.
Bu durumda geri arama, diğer bağımsız değişkenlerinin her birinde “geri çağırmayı” backup
söylediğimiz işlevdir doonall
- doonall
davranışla (ilk argümanını) ve verileri (kalan argümanları) sunarız.
(İkinci örnekte gösterilen türden bir kullanım örneğinde, “geri arama” terimini kendim kullanmayacağımı, ancak belki de kullandığım dillerden kaynaklanan bir alışkanlık olduğunu düşünüyorum. geri aramaları olay odaklı bir sisteme kaydetmek yerine)