【Shell】シェル ~ 基本編・条件分岐 if / case ~

■ はじめに

シェルの条件式をメモ。

目次

【1】if文
 1)構文
  a) if - else
  b) if - elif - else
 2)条件式
  a) 数値の比較
  b) 文字列の比較
  c) ファイルの比較
 3)その他事項
  a) AND
  b) OR
  c) NOT
 4)サンプル
  例1:数値の比較
  例2:引数チェック - Hello world
【2】case文
 1)構文
 2)応用編:部分一致(前方一致・後方一致)
 3)サンプル
  例1:環境によって変数値を変える
  例2:引数で処理を変える
 4)応用:テンプレート

 【1】 if文

* 結構覚えづらいので、メモ。

1)構文

 a) if - else

if [ 【条件式】 ]; then
    # 【条件式】が真
else
    # 【条件式】が偽
fi # 閉じるのは if の逆

 b) if - elif - else

if [ 条件1 ]
then
  処理1
elif [ 条件2 ]
then
  処理2
else
  処理3
fi # 閉じるのは if の逆

2)条件式

a) 数値の比較

条件式 説明 サンプル
値1 -eq 値2 == (EQuals) if ${value} -eq 5; then
値1 -ge 値2 <= (Greater than or Equal to) if ${value} -ge 5; then
値1 -gt 値2 < (Greater Than) if ${value} -gt 5; then
値1 -le 値2 >= (Less than or Equal to) if ${value} -le 5; then
値1 -lt 値2 <= (Less Than) if ${value} -lt 5; then
値1 -ne 値2 <= (Not Equal) if ${value} -ne 5; then

b) 文字列の比較

条件式 説明 サンプル
値1 = 値2 値1と値2が等しい場合に真 if [ ${val} = "-" ]; then
値1 != 値2 値1と値2が等しくない場合に真 if [ ${val} != "-" ]; then
-z 値1 NULL/空文字だったら真 if [ -z "$result" ]; then
-n 値1 NULL/空文字じゃなかったら真 if [ -n "$result" ]; then

https://qiita.com/egawa_kun/items/196cd354c0d8e4e0fefc
https://hacknote.jp/archives/32292/

c) ファイルの比較

条件式 説明 サンプル
-s ファイル1 空じゃなかったら真 if [ -s ${error_log} ]; then
! -s ファイル1 空だったら真 if [ ! -s ${error_log} ]; then

https://ex1.m-yabe.com/archives/3623

#!/bin/bash

input_file="hello_world.txt"
cat /dev/null > ${input_file}

if [ ! -s ${input_file} ]; then
  echo "${input_file} is empty"
else
  ls -l ${input_file}
fi

3)その他事項

* 以下を見ればOK

https://linux.just4fun.biz/?%E9%80%86%E5%BC%95%E3%81%8D%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88/if%E6%96%87%E3%81%AE%E6%9D%A1%E4%BB%B6%E5%BC%8F%E3%81%A7and%2C+or%2C+not%E3%82%92%E4%BD%BF%E3%81%86%E6%96%B9%E6%B3%95
a) AND

[ 条件式1 -a 条件式2 ]

b) OR

[ 条件式1 -o 条件式2 ]

# 以下「例2:引数チェック - Hello world」を参照

c) NOT

[ ! 条件式 ]

4)サンプル

例1:数値の比較

#!/bin/bash

TARGET_VALUE=${1}

if [ ${TARGET_VALUE} -eq 5 ]; then
  echo "Go go ${TARGET_VALUE}!"
elif [ ${TARGET_VALUE} -gt 5 ]; then
  echo "${TARGET_VALUE} is Greater than 5!!"
else
  echo "Other... ${TARGET_VALUE}"
fi

# [出力例]
# $ ./sample.sh 3
# Other... 3
#
# $ ./sample.sh 5
# Go go 5!
#
# $ ./sample.sh 6
# 6 is Greater than 5!!

例2:引数チェック - Hello world

#!/bin/bash

INPUT_VALUE="${1}"

if [ "${INPUT_VALUE}" = "hello" -o "${INPUT_VALUE}" = "world" ]; then
  echo "This is Hello world!!"
else
  echo "This is NOT hello world..."
fi

出力結果例

$ ./sample.sh hello
This is Hello world!!

$ ./sample.sh world
This is Hello world!!

$ ./sample.sh hi
This is NOT hello world...

 【2】case文

1)構文

case 変数 in
   パターン1)
         処理1
         ;;
   パターン2)
         処理2
         ;;
   パターン3 | パターン4)
         処理3
         ;;
   *)
         処理X
         ;;
esac # 閉じるのは case の逆

2)応用編:部分一致(前方一致・後方一致)

* 以下の関連記事を参照のこと

シェルで部分一致(前方一致・後方一致)
https://dk521123.hatenablog.com/entry/2020/09/01/000000

3)サンプル

例1:拡張子を判断

#!/bin/bash

TARGET=${1}

value="cus"
case ${TARGET} in
  *.csv | *.tsv)
    echo "CSV or TSV : ${TARGET}"
    ;;
  *.txt)
    echo "TEXT : ${TARGET}"
    ;;
  *.${value})
    echo "Custom file : ${TARGET}"
    ;;
  *)
    echo "Other : ${TARGET}"
esac

echo "Done"

出力結果

$ ./sample.sh hello.txt
TEXT : hello.txt
Done

$ ./sample.sh hello.cus
Custom file : hello.cus
Done

$ ./sample.sh hello.tsv
CSV or TSV : hello.tsv
Done

$ ./sample.sh hello.csv
CSV or TSV : hello.csv
Done

$ ./sample.sh hello.xxx
Other : hello.xxx
Done

$ ./sample.sh csv.xxx
Other : csv.xxx
Done

例2:環境によって変数値を変える
https://dk521123.hatenablog.com/entry/2020/04/16/113816

#!/bin/bash

case "$1" in
  prod)
    S3_BUKET_NAME="s3-buket-pd001"
    ;;
  stage)
    S3_BUKET_NAME="s3-buket-sg001"
    ;;
  dev)
    S3_BUKET_NAME="s3-buket-dv001"
    ;;
  *)
    S3_BUKET_NAME="s3-buket-xx001"
    ;;
esac

echo "Result = ${S3_BUKET_NAME}"

出力結果

# [Case1]
#$ ./sample.sh dev
#Result = s3-buket-dv001

# [Case2]
#$ ./sample.sh prod
#Result = s3-buket-pd001

# [Case3]
#$ ./sample.sh dev
#Result = s3-buket-dv001

# [Case4]
#$ ./sample.sh
#Result = s3-buket-xx001

例3:引数で処理を変える

#!/bin/bash

startSomething() {
   # 処理
}

stopSomething() {
   # 処理
}

case "$1" in
  start | s | S)
    startSomething
    ;;
  stop)
    stopSomething
    ;;
  restart | r | R)
    stopSomething
    startSomething
    ;;
  *)
    echo "start/stop/restart"
    exit 1
    ;;
esac

exit 0

4)応用:テンプレート

#! /bin/sh
 
#
# 何らかの処理
#

command1() {
  # 何らかの処理
  return 0
}
  
command2() {
  # 何らかの処理
  return 0
}
  
case "$1" in
 command1)
        command1
        ;;
 command2)
        command2
        ;;
 *)
        echo "Usage: $0 {command1|command2}"
        exit 1
        ;;
esac
exit 0

 参考文献

https://eng-entrance.com/linux-shellscript-operator
http://d.hatena.ne.jp/zenpou/20080621/1214068526
http://www.k4.dion.ne.jp/~mms/unix/shellscript/shell_cont.html
ディレクトリのファイルの有無をしらべる
http://kuchitama.hateblo.jp/entry/20111226/p1

関連記事

シェル について ~入門編~
https://dk521123.hatenablog.com/entry/2014/10/23/005406
シェル について ~基本構文編~
https://dk521123.hatenablog.com/entry/2015/02/20/001600
関数
https://dk521123.hatenablog.com/entry/2015/03/17/233124
シェルスクリプトあれこれ
https://dk521123.hatenablog.com/entry/2018/03/03/210642
シェルで部分一致(前方一致・後方一致)
https://dk521123.hatenablog.com/entry/2020/09/01/000000
ファイルに関する処理あれこれ
https://dk521123.hatenablog.com/entry/2020/09/28/000000