Bash kabuğunda betik yazmanın incelikleri — 2
Bu flood’da Linux işletim sisteminde Bash
kabuğunda (shell) çalıştırmak üzere yazılan betiklerden (script) bahsetmeye devam edeceğim.
Önceki flood’da Bash
'te bir değişkenin VAR=VALUE
biçiminde tanımlandığını görmüştük. Başka bir yöntem ise değişkeni export VAR=VALUE
ile tanımlayarak ortam değişkeni (environment variable) haline getirmektir. Bu iki tanımlama arasındaki farklı açıklayarak başlayalım.
export
ile tanımlanan değişkenler hem tanımlandıkları betik içerisinden hem de o betik tarafından çağrılan çocuk betikler (sub-script) tarafından erişilebilirler. VAR=VALUE
ile tanımlanan yerel değişkenler ise sadece ana betik tarafından erişilebilir olurlar.
Bash
kabuğu çalıştırdığı her program için yeni bir proses oluşturur. Bash
yeni prosesi oluştururken kendisinde tanımlı olan ortam değişkenlerini çocuk prosese aktarır, diğer değişkenleri ise aktarmaz. Bu sebeple yerel değişkenler yeni yaratılan proses tarafından görülmez.
Aşağıdaki ekran çıktısında main-script.sh
betiği biri ortam değişkeni olmak üzere iki değişken tanımlamış ve sub-script.sh
betiğini çağırmıştır. Değişkenler her iki betikte de ekrana döktürülerek LANG_SELECTED
değişkeninin sub-process.sh
'te görülmediği gösterilmiştir.
Anlaşılacağı üzere kabuktan (shell) koşturulan bütün betiklerde görülmesi gereken parametreler ortam değişkeni (environment variable) olarak tanımlanır. Argümanı sadece bir alt betiğe vermek için ise aşağıdaki kullanımı tercih etmek gerekir.
Yukarıda ana betikten çocuk betiklere parametre aktarılmasını görmüş olduk. Çocuk betikte hesaplanan bir değerin ana betiğe aktarılması için ise ortam değişkenleri veya stdout
kullanılabilir. Öncelikle ortam değişkeni ile aktarım yöntemini inceleyelim.
Çocuk betiği koşturan proses, ana betiği koşturan proses tarafından oluşturulduğu için normal şartlarda ana proses ancak çocuk prosesin çıkış kodunu alabilir çünkü çocuk proses çıkış yaptıktan sonra bütün ortam değişkenleri vb işletim sistemi tarafından temizlenir.
source
veya .
komutları ile çocuk betiklerin yeni proses yerine ana betiği koşturan proses tarafından koşturulması sağlanabilir. Bu sayede çocuk betik sonlandıktan sonra, çocuk betiğin ana proseste oluşturduğu ortam değişkenlerine ana betik tarafından da erişilebilir.
Aşağıdaki ekran çıktısında ana betik, çocuk betiği source
ile kendi prosesinde koşturduktan sonra onun oluşturduğu ortam değişkenini ekrana bastırmıştır.
Bash
üzerinde bir program çalıştırmak ve programın ekran çıktısını (stdout
) almak için $(...)
veya `...`
sentaksları kullanılır. Aşağıdaki örnekte docker image ls
çıktısı içindeki redis
imajının ID'si süzülüp bir değişkene atılmıştır.
Yukarıdakine benzer şekilde ana betikten çağrılan bir çocuk betik ana betiğe bir veya daha fazla değer döndürebilir. Aşağıdaki örnekte çocuk betiğin ana betiğe birden fazla değer döndürdüğü durum gösterilmiştir.
Böylece çocuk betikten ana betiğe değer döndürmenin ikinci ve kullanımı daha doğru olan yöntemini de görmüş olduk. Bu yöntemin ilk yönteme göre daha doğru olmasının sebebi ana prosesin ortam değişkeni alanını kirletmemesi ve izolasyona olanak tanımasıdır.
Son olarak, bazı durumlarda bir programın ürettiği değişkenleri kabukta veya kabuk tarafından çalıştırılan betikte ortam değişkenleri olarak tanımlamak isteyebiliriz. Aşağıda sub-script.sh
tarafından tanımlanan ortam değişkenleri eval
tarafından çalıştırılmıştır.
Başka bir örnek olarak aşağıdaki ekran çıktısında docker-machine
ile oluşturulan bir sanal makinaya erişmek için kabukta tanımlanması gereken ortam değişkenlerinin yukarıda anlatılan method ile kabuğa eklenebileceği gösterilmektedir.