28 Eylül 2021 Salı

bash kodlama $? gömülü değişkeni - Return Value

Giriş
Son çalıştırılan komutun exit status değerini verir.

Bu değişkeni Kullanmamak
Açıklaması şöyle
SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
Bir uygulamayı çalıştırıp döndürdüğü sonucu almak için şu yol izlenebilir
utility

# shellcheck disable=SC2181
if [ "$?" -eq 0 ]; then
    echo ok
else
    echo fail
fi
Ancak şöyle yapmak daha kolay
if utility; then
    echo ok
else
    echo fail
fi
Kullanma Örnekleri
Örnek
Şöyle yaparız.
another_script.sh
exit_code=$?
Örnek
Şöyle yaparız.
grep -q '/example.com' /opt/nfs || grep -Rq '/example.com' /data
if [ $? -eq 0 ]; then   # check exit status
  echo "Passed"
else 
  echo "Failed"
fi
Örnek
set -e ile ilk hata da bash'in devam etmemesi sağlanır. Ancak bazı komutların 0'dan farklı bir şey dönmesi durumunda şöyle yaparız. Böylece set -e dikkate alınmaz.
#!/usr/bin/env bash
set -e
! docker stop foo
! docker rm -f foo
# ... other stuff

bash kodlama - file test

Giriş
file test operators bir nesnenin var olduğunu kontrol etmek için vardır. Tüm seçenekler burada

-a seçeneği - File Exist
-e ile aynı ancak bu seçenek artık deprecated

-b seçeneği - File Is Block Device
Örnek ver

-c seçeneği - File Is Character Device
Örnek ver

-e seçeneği - Dosya/Dizin varlığı kontrolü - File Exists
Örnek
Şöyle yaparız.
set *
if [ -e "$1" ]
then
  echo 'not empty'
else
  echo 'empty'
fi
Örnek
Scriptimiz bir tane dosya oluştursun. Eğer ikinci çalışmada 24 saat geçmemişse çalışmasın istyorsak şöyle yaparız
#!/bin/bash
flag="/var/tmp/$(basename -- $0).flag"
min_age=$(( 60 * 60 * 24 )) # 24 hours

if [ -e "$flag" ] ;then
  (( $(date +%s) - $(date +%s -r "$flag") > min_age )) || exit 1
fi
touch "$flag"

# Proceed with your script
# ...
-f seçeneği - Dosya kontrolü - File Is a Regular File Not Directory
Örnek
Şöyle yaparız.
if [ -f file1 ]; then   # If file1 exists ...
  cp file1 file2      # ... create file2 as a copy of a file1
fi
Örnek
Şöyle yaparız.
for name in ./*; do
  if [ -f "$name" ]; then
    # this is a regular file (or a symlink to one), create directory
    mkdir "$name.d"
  fi
done

-d seçeneği - Dizin kontrolü - File Is Directory
Örnek  - Çift Tırnak İçinde Olmayan Değişken
Eğer değişken boş ise yanlış çalışabilir. Şu kod hatalı.
dirname=

if [ -d $dirname ];
 then
 cd $dirname && rm *
fi
Açıklaması şöyle.
...when you pass nothing to the -d operator of the bash test or [ built-in, bash appears to exit with 0 (in my opinion, this is unexpected).
Düzeltmek için şöyle yaparız. Değişken boş olsa bile doğru çalışır.
if [ -d "$dirname" ]; then
    cd "$dirname" && rm *
fi
Açıklaması şöyle
In this case, if $dirname is empty, you'll be passing "" to the -d operator which correctly evaluates a non-zero exit code so the code inside the block is not executed.
Örnek - Çift Tırnak İçinde Değişken
Şöyle yaparız. İsmi "636.empty" gibi olan yani sayı ile başlayıp ".empty" şeklinde biten dizinleri siler.
for d in *.empty; do
    [ -d "$d" ] && [ -d "${d%.empty}" ] && rmdir "$d"
done
Örnek - Çift Tırnak İçinde Değişken
Dizin yoksa yaratmak için şöyle yaparız.
array1=(
/apache
/apache/bin
/apache/conf
/apache/lib
/www
/www/html
/www/cgi-bin
/www/ftp
)
for dir in "${array1[@]}"; do
  [[ ! -d "$dir" ]] && mkdir "$dir"
done

-h seçeneği - File Is A Symbolic Link
Örnek ver

-p seçeneği - File Is A Pipe
Açıklaması şöyle
True if file exists and is a named pipe (FIFO).
Örnek
Şöyle yaparız
if [ -p "$pipe" ]

-r seçeneği - File Has Read Permission For The User Running The Test
Örnek ver

-s seçeneği - Boş Olmayan Dosya kontrolü - File Not Zero Size
Şöyle yaparız.
if [ ! -s "$filename" ]; then
  echo "$filename is empty"
elif [ -z "$(tail -c 1 <"$filename")" ]; then
  echo "$filename ends with a newline or with a null byte"
else
  echo "$filename does not end with a newline nor with a null byte"
fi