Help us understand the problem. What is going on with this article?

シェルスクリプトBash入門

More than 1 year has passed since last update.

気分転換にシェルスクリプトを書いてみる。
今回使うシェルは

$ echo $SHELL
/bin/bash

1.定番の"Hello world!"

まずは作業フォルダーに移動します。
そのあとVimを使ってスクリプトファイルを作ります。

hello.sh
#!/bin/bash

echo "Hello World!"
exit 0

実行しようと「./hello.sh」とコマンド打つと
-bash: ./hello.sh: Permission denied
とパーミッションつまり権限がないと言われる。
ls -la hello.shでみてみると
-rw-r--r-- 1 ebisennet staff 30 12 4 21:32 hello.sh
まあ実行権限はないですね。
chmod u+x hello.sh
で実行権限を与えます。確認すると
-rwxr--r-- 1 ebisennet staff 30 12 4 21:32 hello.sh
実行できますね。

$ ./hello.sh
Hello World!

できましたね。

ちなみにexit 0正常終了の意味
コメントは行頭#でその行はコメントできる
セミコロンを使うことで1行にまとめることができる。

hello.sh
#!/bin/bash

# コメント
echo "hello world!";exit 0

2.変数

hello.sh
#!/bin/bash↲
↲
# 変数 =の両端にスペースを入れない↲
↲
# 文字列↲
# 'は変数展開されないことに注意↲
s="Hello"↲
↲
echo $s↲
echo "$s"↲
echo "${s}" #こちらを使った方が他の環境でも実行されやすい↲
echo $s$s↲
echo "$s $s"↲
echo "${s} ${s}"↲
echo '$s'

結果

vim.bash
$ ./hello.sh
Hello
Hello
Hello
HelloHello
Hello Hello
Hello Hello
$s

数値

hello.sh
#!/bin/bash↲
↲
# 変数 =の両端にスペースを入れない↲
↲
# 数値↲
↲
x=10↲
echo $x↲
echo $x+2

結果

$ ./hello.sh
10
10+2

計算されていないことに注意してください
計算するには

echo `expr $x + 2`

としなければならない。スペースを一つ一つ空けなければならない。

$ ./hello.sh
10
10+2
12

四則演算、優先計算、readonly

#!/bin/bash↲
↲
# 変数 =の両端にスペースを入れない↲
# 値を変更させないようにするには readonly 変数名=値↲
# 数値↲
↲
x=10↲
echo `expr $x + 2`↲
echo `expr $x - 2`↲
echo `expr $x \* 2`↲
echo `expr $x / 2`↲
↲
↲
echo `expr \( $x + 5 \) \* 2`↲
echo `expr $x / 2`↲
↲
readonly y=10↲
y=20↲

実行結果

$ ./hello.sh
12
8
20
5
30
5
./hello.sh: line 18: y: readonly variable

配列

#!/bin/bash↲
↲
# 配列↲
↲
a=(2 4 6)↲
↲
echo $a↲
echo "---------------"↲
echo ${a[0]}↲
echo ${a[1]}↲
echo ${a[2]}↲
echo "---------------"↲
# @は全ての要素 #は要素数↲
echo ${a[@]}↲
echo ${#a[@]}↲

実行結果

$ ./hello.sh
2
---------------
2
4
6
---------------
2 4 6
3

注意 $a[1]は2[1]と表示される

配列の要素変更

#!/bin/bash↲
↲
# 配列↲
↲
a=(2 4 6)↲
↲
# 要素の変更↲
a[2]=10↲
echo ${a[@]}↲
echo "---------------"↲
# 要素の追加↲
a+=(20 30)↲
echo ${a[@]}↲
echo "---------------"↲
# 応用 `でくくったところは実行結果を返すもの↲
d=(`date`)↲
echo ${d[3]}

実行結果

$ ./hello.sh
2 4 10
---------------
2 4 10 20 30
---------------
14時50分44秒
$ date
2016年 3月15日 火曜日 14時50分50秒 JST

条件分岐

#!/bin/bash↲
↲
# 条件式↲
# 正常終了(0)↲
↲
# 数値の評価↲
↲
# 1=2ではないので1が出力される。$?は正常終了かそれ以外かがわかる。↲
test 1 -eq 2; echo $?↲
test 1 -eq 1; echo $?↲
echo "----------------"↲
# -ne <> or !=↲
test 1 -ne 2; echo $?↲
# >↲
test 1 -gt 2; echo $?↲
# >=↲
test 1 -ge 2; echo $?↲
# <↲
test 1 -lt 2; echo $?↲
# <=↲
test 1 -le 2; echo $?↲

実行結果

$ ./hello.sh
1
0
----------------
0
1
1
0
0

文字列、ファイルに対しての条件式

#!/bin/bash↲
↲
# 条件式↲
# 正常終了(0)↲
↲
#文字列の評価↲
↲
# =↲
# !=↲
↲
# ファイル↲
# -nt (newer than)↲
# -ot (older than)↲
# -e↲
# -d↲
test -e hello.sh; echo $?↲
↲
# 論理演算子↲
# -a (and)↲
# -o (or)↲
# ! (否定)↲
test 1 -eq 1 -a 2 -eq 2; echo $?↲

実行結果

$ ./hello.sh
0
0

IF文

#!/bin/bash

# if文

x=70
if test $x -gt 60
then
  echo "ok!"
fi
# 上と同じ処理[]はテストの命令となっているためスペースが必要
if [ $x -gt 60 ]; then
  echo "ok!"
fi
# 複数条件
echo "-----------------"
y=40
if [ $y -gt 60 ]; then
  echo "ok!"
else
  echo "soso..."
fi

if [ $y -gt 60 ]; then
  echo "ok!"
elif [ $y -gt 40 ]; then
  echo "soso..."
else
  echo "ng..."
fi

実行結果

$ ./hello.sh
ok!
ok!
-----------------
soso...
ng...

case文

#!/bin/bash↲
↲
# case文↲
↲
signal="red"↲
case $signal in↲
  "red")↲
    echo "stop!"↲
    ;;↲
  "yellow")↲
    echo "caution!"↲
    ;;↲
  "green")↲
    echo "go!"↲
    ;;↲
  *)↲
    echo "..."↲
    ;;↲
esac↲

実行結果

$ ./hello.sh
stop!

while文

#!/bin/bash

# while

i=0
while [ $i -lt 10 ]
do
  i=`expr $i + 1 `
  echo ${i}
done

echo "------------"

# 無限ループ :は正常終了コマンドで常にtureになるのでループする。
j=0
while :
do
  j=`expr $j + 1 `

  if [ $j -eq 3 ]; then
# $i=3の時処理を飛ばす
    continue
  fi 

  if [ $j -gt 10 ]; then
# $i>10の時はループを抜け出し終了
    break
  fi

  echo ${j}
done

実行結果

$ ./hello.sh
1
2
3
4
5
6
7
8
9
10
------------
1
2
4
5
6
7
8
9
10

for文

#!/bin/bash↲
↲
# for文↲
↲
for i in 1 2 3 4 5↲
do↲
  echo ${i}↲
done↲
↲
echo "-------------"↲
↲
# 配列バージョン $iは上でも使われているので注意(普通は区別します。)↲
↲
a=(1 2 3 4 5)↲
↲
for i in ${a[@]}↲
do↲
  echo ${i}↲
done↲

# 省略型↲
↲
for i in `seq 1 5`↲
do↲
  echo ${i}↲
done↲

実行結果

$ ./hello.sh
1
2
3
4
5
-------------
1
2
3
4
5
-------------
1
2
3
4
5

ちなみに、continue,breakも使用可能

コマンドに引数を渡す

#!/bin/bash↲
↲
echo $0 #自分自身参照↲
echo $1 #第一引数↲
echo $2 #第二引数↲
# echo ${10} #第10引数(10以降はカッコをつける)↲
↲
echo $@ #引数全て↲
echo $# #引数の個数↲

実行結果

$ ./hello.sh a b
./hello.sh
a
b
a b
2

ユーザーからの入力の受付

#!/bin/bash↲
↲
# read↲
↲
while :↲
do↲
  # 入力を受け取る↲
  read key↲
  echo "you pressed ${key}"↲
  if [ ${key} = "end" ]; then↲
    break↲
  fi↲
done↲
↲
# 選択肢から選ばせる↲
select option in CODE DIE↲
do↲
  echo "you pressed ${option}"↲
  break↲
done↲

実行結果

$ ./hello.sh
ok
you pressed ok
end
you pressed end
1) CODE
2) DIE
#? 2
you pressed DIE

ファイルから入力

データを作成する

data.txt
hello↲
hoge↲
nyoro
hello.sh
#!/bin/bash↲
↲
i=1while read line #受け取ったデータを1行ずつ処理↲
do↲
  echo "${i}: ${line} "i=`expr $i + 1`↲
done <$1 #第一引数の指定↲

実行結果

$ ./hello.sh date.txt
1: hello
2: hoge
3: nyoro

関数

#!/bin/bash↲
↲
# 関数↲
function hello() {↲
  echo "hello"↲
}↲
hello↲
#functionは省略可能である。 hello() {}↲
ok() {↲
  echo "ok"-↲
}↲
ok↲
#引数を使う↲
hello2() {↲
  echo "hello2 $1 and $2"↲
}↲
hello2 Mike Tom↲

実行結果

$ ./hello.sh
hello
ok
hello2 Mike and Tom

#!/bin/bash↲
↲
# 関数 ローカル変数、グローバル変数↲
function hello() {↲
  echo "hello"↲
  i=5↲
  echo ${i}↲
}↲
↲
hello↲
echo "-------------"↲
echo ${i}↲

実行結果

$ ./hello.sh
hello
5
-------------
5

#!/bin/bash↲
↲
# 関数 ローカル変数、グローバル変数↲
function hello() {↲
  echo "hello"↲
  i=5↲
  local j=10↲
  echo "${i} ${j}"↲
}↲
↲
hello↲
echo "-------------"↲
echo ${i}↲
echo ${j}↲

実行結果

$ ./hello.sh
hello
5 10
-------------
5

local変数を参照した場合空行になっています。

ebisennet
フリーのエンジニアをしてます。 主にIBM cloudとWatsonを使った学習、分析、アプリ開発を、しています。 自分も何かしら情報を発信できたらと思っていますが、今は勉強中!
http://ebisennet.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away