なんだこれは
シェルスクリプト便利ですよね。
でも、いっつも書き方忘れます
もういい加減Google先生にコマンド単位で聞くの怠いので、書き方をまとめておく。
シェル芸ってレベルの記事じゃないですが、まあ、小さなスクリプト書く程度なら有益な記事です。たぶん。
オフビートで雑なエントリだけど気にしないでください。
基礎編
こっからシェルスクリプトの基本的な構文について書いていきます。マジで基本的な構文。
実行権限
意外と忘れがちだが、まず最初に権限を与えとこう。じゃなきゃ実行できねえ。
(*'~') $ touch sample.sh
(*'~') $ chmod +x ./sample.sh
宣言
これはシェルスクリプトだ って宣言を1行目に書くのを忘れるな。
shかbashの違いはそんなないのでbashでいいと思われる。
#!/bin/bash
コメントアウト
コメントアウトは知っておきたいですよね。まあ、先頭に#
つけるだけです。
(*'~') $ cat sample.sh
# !/bin/bash
# echo "not display"
echo "display"
(*'~') $ ./sample.sh
display
引数
引数や変数の書き方についてまとめるよ
引数の取り方
実際に書いて覚えるのが早い。引数の取り方は下記のスクリプトのように取れる。$
で変数だよって意味。
(*'~') $ cat sample.sh
# !/bin/bash
echo $#
echo $@
echo "$@"
echo $*
echo "$*"
echo $0
echo $1
echo $2
echo $9
試しに引数与えるとこんな感じになるよ。
(*'~') $ ./sample.sh hoge 1
2
hoge 1
hoge 1
hoge 1
hoge 1
./sample.sh
hoge
1
(*'~') $
説明
-
$#
: スクリプトに渡された引数の数 -
$@
: スクリプトに渡された全ての引数。 -
$*
: スクリプトに渡された全ての引数。ダブルコーテーションで囲なければ$@
と同じ。 -
$0
: 実行されてるスクリプト名。 -
$n
: スクリプトに渡されたn番目の引数。与えた引数の範囲を越えると空文字を出力。10番目以降の引数は${n}
と記述しないと展開できないよ。
$@
と $*
の違い
ダブルコーテーションで囲なければ$@
と同じであるが、囲むと以下のように、引数毎に出力するか、まとめて一つの引数で出力するかの違いがある。
(*'~') $ cat sample.sh
# !/bin/bash
for arg in "$@"
do
echo $arg
done
for arg in "$*"
do
echo $arg
done
(*'~') $ ./sample.sh hoge foo 1
hoge
foo
1
hoge foo 1
変数
引数で既に書いてるけど、変数を参照するときは$
がつく。定義するときはつけない。
あと、注意点が変数を定義する時に=
の左右に空白は入れない事。繋げて書こう。
(*'~') $ cat ./sample.sh
# !/bin/bash
hoge="This is Hoge"
echo $hoge
(*'~') $ ./sample.sh
This is Hoge
変数展開
文字列の中で変数を展開する。ダブルコーテーションの中で変数書くだけ。
(*'~') $ cat ./sample.sh
# !/bin/bash
hoge="This is Hoge"
echo "What is this? $hoge"
(*'~') $ ./sample.sh
What is this? This is Hoge
コマンドの実行結果
コマンドの実行結果を変数に格納できる。$()
の中で実行したいコマンドを記述。
(*'~') $ cat ./sample.sh
# !/bin/bash
hoge=$(echo "This is Hoge")
echo "What is this? $hoge"
(*'~') $ ./sample.sh
What is this? This is Hoge
条件分岐
先ほどもちょっと書いたけど、if、for、case文の書き方について記述するよ。
if
文
必ず使いますね。ちょっと癖がある。
比較演算子で-n
とか-z
とかあるけど、結構混乱するんで普通に"" = "$hoge"
みたいな比較の方が簡単だと思います。
因みに、変数は必ずダブルコートで囲んで文字列として比較してください
(*'~') $ cat sample.sh
# !/bin/bash
if [ "" = "$1" ]; then
echo "params not given"
fi
if [ "" != "$1" ]; then
echo "params given $1"
fi
(*'~') $ ./sample.sh
params not given
(*'~') $ ./sample.sh hoge
params given hoge
if ~ else
これまたよく使う構文。elif
って毎回忘れる。
(*'~') $ cat sample.sh
# !/bin/bash
if [ "hoge" = "$1" ]; then
echo "params is hoge"
elif [ "foo" = "$1" ]; then
echo "params is foo"
else
echo "params are not hoge or foo"
fi
(*'~') $ ./sample.sh hoge
params is hoge
(*'~') $ ./sample.sh foo
params is foo
(*'~') $ ./sample.sh other
params are not hoge or foo
for
文
さっきちょっとやったね
(*'~') $ cat sample.sh
# !/bin/bash
for arg in "$@"
do
echo $arg
done
(*'~') $ ./sample.sh hoge foo 1
hoge
foo
1
case
文
地味に使うよね
(*'~') $ cat sample.sh
# !/bin/bash
case "$1" in
hoge)
echo "params is hoge"
;;
foo)
echo "params is foo"
;;
*)
echo "params are not hoge or foo"
;;
esac
(*'~') $ ./sample.sh hoge
params is hoge
(*'~') $ ./sample.sh foo
params is foo
(*'~') $ ./sample.sh other
params are not hoge or foo
ヒアドキュメント
地味に便利なヒアドキュメント。シェルでももちろん使えます。
最初のEOS部分をシングルコーテーションで囲むと変数展開はされません。
因みに、EOSは最初と最後の文字を揃えればなんでもいいです。慣習として全て大文字であれば。
(*'~') $ cat sample.sh
# !/bin/bash
cat << EOS
you can discribe multiple lines.
$1
EOS
cat << 'EOS'
$1
EOS
(*'~') $ ./sample.sh hoge
you can discribe multiple lines.
hoge
$1
終了処理
スクリプトを途中で終了するにはexitコマンドに数字を与えます。0
が正常終了で、1
が異常終了です。主に引数が不足してる時に処理を止める時とかに使います。
(*'~') $ cat sample.sh
# !/bin/bash
case "$1" in
0)
echo "success"
exit 0
;;
*)
echo "error"
exit 1
;;
esac
echo "can't reach"
(*'~') $ ./sample.sh 0
success
(*'~') $ ./sample.sh 1
error
まとめ
こんなもんでどうだろう。
体系的に記述してるエントリーが意外となかった(たぶん探し方が悪い)ので、書いてみました。
やっぱり自分で書くとなんかわかった気になりますね。
後日に応用編を追加していきます。