Bash kabuğunda betik yazmanın incelikleri — 2

Gökhan Şengün
3 min readJul 23, 2018

--

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.

--

--

Gökhan Şengün

Full stack dad of two and just curious about things. Stories are from my twitter floods @gokhansengun. Main blog is www.gokhansengun.com