[自分用]シェルスクリプト勉強まとめ


シェルスクリプト入門

はじめに

これは自分用に書いたまとめです。
誰かの勉強する際の役に立ったり、間違いなどフィードバックいただければ嬉しいなと思い投稿しました。

初歩

シェバン or シバンっていうらしい


#! /bin/bash

ディレクトリがコマンドの実行パスに含まれていないためシェルスクリプトを実行するには以下のようにする


./hello

一行に複数の命令を描きたい場合はセミコロンで区切る


echo 'hoge'; echo 'fuga'

コメントアウトは#を使う


# hoge

変数

変数を宣言
=イコールの前後に空白がないようにする


name="hoge"

$変数名、${変数}とすることで変数を使える


echo 'hello  $name’
echo 'hello  ${name}

内容を書き換えて欲しくない変数を作る場合はreadonlyというキーワードをつける


readonly name = ‘hoge’

‘ ’シングルクオーテーションを使うと変数の中身が展開されない


echo 'hello4 ${name}’

特殊変数
実行時に値を渡すことができ、渡された値には$1、$2のようにアクセスすることができる


echo "hello $1"

実行時
./hello hoge
値を渡す

\$0 スクリプトの名前
\$# 引数の数
\$@ or $* すべての引数

実行時にユーザーから入力を受け付ける


read name

入力前にテキストを表示したい場合は-p(プロンプトオプション)を使ってあげる


read -p “Name: “ name

複数の値を一気に複数の変数に割り当てる


read -p "Pick 3 colors: " c1 c2 c3
echo $c1
echo $c2
echo $c3

四つ入れると余った分は最後に全部入れられるから最後に二つ入る

配列

colors=(red blue pink)
echo ${colors[0]}
echo ${colors[1]}
echo ${colors[2]}
すべての要素を表示する
echo ${colors[@]}
要素の個数を表示する
echo ${#colors[@]}

値を変更する


colors[1]=silver

要素を追加する


colors+=(green orange)

数値計算をする

数値の計算には``を使う


echo `expr 5 + 2`

↑の場合、一部の文字をエスケープしたりしないといけないらしい

↓のような書き方もできる


echo $((5 + 2))

(( ))の中で変数を使う場合は、$がいらない
n=10
echo $((n=n+5))

bashでは基本的に整数の演算子かできない


echo $((10 / 3))

if文を使った条件分岐


read -p "Name? " name
if test "name" = "taguchi"
then
  echo "welcome"
fi

testじゃなくて[ ]を使って書くこともできる


read -p "Name? " name
if  [ "$name" = "taguchi" ]
then
  echo "welcome"
fi

elifも使える


read -p "Name? " name
if  [ "$name" = "taguchi" ]
then
  echo "welcome"
elif [ "$name" = "tanaka" ]
then
  echo "welcom tanaka"
else
  echo "you are not taguchi"
fi

thenを一行に書くこともできる

read -p "Name? " name
if  [ "$name" = "taguchi" ]; then
  echo "welcome"
elif [ "$name" = "tanaka" ]; then
  echo "welcom tanaka"
else
  echo "you are not taguchi"
fi

文字列や数値の比較には(())か[[]]を使う
この場合は、変数に""をつけなくていい

-z 文字列の長さが0かどうか
=~ 正規表現


read -p "Name? " name
if [[ -z $name ]]; then
  echo 'empty'
fi

read -p "Name? " name
if [[ $name =~ ^t ]]; then
  echo 'starts with t'
fi

種類を問わず存在しているか -e
ファイルが問わず存在しているか -f
ディレクトリが存在しているか -d


if [[ -f $0 ]]; then
  echo 'file exits...'
fi

if [[ -d $0 ]]; then
  echo 'dir exits...'
fi

read -p "Number? " n
if (( $n > 10 )); then
  echo 'bigger than 10'
fi

ループ処理


forでループ処理
for i in 1 2 3 4 5
do
  echo $i
done

ブレース展開できる


for i in {1..5}; do
  echo $i
done

for ((i=1; i<=5; i++)); do
  echo $i
done

colors=(red blue pink)
for color in ${colors[@]}; do
  echo $color
done

dateコマンドを実行すると日付が返ってくる。
この実行結果を受け取ってシェルスクリプトを実行する。


for item in $(date); do
  echo $item
done

whileループについて


while ((i < 10)); do
  ((i++))
  echo $i
done

ルートをスキップするcontinue、抜けるためのbreak


while (( i < 10 )); do
  ((i++))
  if (( $i == 2 )); then
    continue
  fi
  if (( $i == 8 )); then
    break
  fi
  echo $i
done

while :

nullコマンド、いつでも条件が成立する
while true みたいなイメージ


while :
do
  read -p "Command? " cmd
  if [[ $cmd == 'quit' ]]; then
    break
  else
    echo "$cmd"
  fi
done

ファイルの内容を処理する


i=1
while read line; do
  echo $i "$line"
  ((i++))
done

パイプを使ってファイルの内容を渡す方法もある


cat ファイル | スクリプトを実行

case文


read -p "Signal color? " color
case "$color" in
  red)
    echo "stop"
    ;;
  blue|green)
    echo "go"
    ;;
  yellow)
    echo "caution"
    ;;
  *)
    echo "wrong signal"
esac

ユーザーに値を選んでもらえる select

selectの中はループ処理になるため、breakで抜ける必要がある


select color in red blue yellow green; do
  case "$color" in
    red)
      echo "stop"
      ;;
    blue|green)
      echo "go"
      ;;
    yellow)
      echo "caution"
      ;;
    *)
      echo "wrong signal"
      break
  esac
done

関数を使ってみる


function hello() {
  echo "hello..."
}

functionは省略できる


function hello() {
  echo "hello..."
}

# 関数名を書けば実行される
hello
hello

関数には引数を渡すことができる


# 引数から受け取った値を使うには$
function hello() {
  echo "hello... $1"
}

# 関数名を書けば実行される
hello tanaka
hello yamamoto

returnを使って関数が正常終了したかどうかの終了ステータスを返すことができる

UNIXの世界では0だと正常終了、それ以外の場合は以上終了を意味する


hello(){
  if [[ $1 == 'tanaka' ]]; then
    return 1
  else
    return 0
  fi
}

# 直前の関数の少量ステータスは$?で調べることができる
hello tanaka; echo $?
hello hoge; echo $?

終わり

基礎的なことしかやってないから時間がある時にもっと色々してみようと思います。
自分はシェルスクリプト書いてこんなことしてますとかコメントで教えていただけると嬉しいです。