Linuxでシェルスクリプトを書くために必要な基礎知識をまとめました。「作成方法・実行方法」「変数」「if、forなどの制御構造」「条件文の作り方」など解説します。
シェルスクリプトの作り方・実行方法
スクリプトを作成して直接実行
まずは簡単な例です。「hello」というスクリプトを作成して実行させます。
#!/bin/bash
echo "Hello World"
$ vi hello
$
$ ls -l hello
-rw-r--r-- 1 wakuwaku staff 33 Nov 18 12:12 hello
$
$ chmod u+x hello
$
$ ls -l hello
-rwxr--r-- 1 wakuwaku staff 33 Nov 18 12:12 hello
$
$ ./hello
Hello World
ここで、押さえておきたいポイントは2つです。
- スクリプトの1行目に「bashで実行されます」という宣言を記述。
- ファイルの所有者のパーミッションに実行権を付与。
u(所有者)
g(グループ)
o(その他)
x(実行権)
PATHを通して実行
環境変数PATHに、「hello」が置かれているディレクトリパスを追加すると、ファイル名を指定するだけで実行できます。
PATHが通ってない状態ですと、command not found
となります。
$ hello
bash: hello: command not found
PATHの設定は以下コマンドで確認できます。
$ echo $PATH
PATHの追加は、下記のように行います。
$ export PATH=$PATH:追加したいパス
実際に確認します。
$ ls
hello
$
$ pwd
/tmp
$
$ export PATH=$PATH:/tmp
$
$ hello
Hello World
bashコマンドで実行
bashコマンドから起動することもできます。
「-v」オプションを利用すると全行エコー表示されます。
$ bash -v hello
#!/bin/bash
echo "Hello World"
Hello World
「-x」オプションを利用すると実行文がエコー表示されます。
$ bash -x hello
+ echo 'Hello World'
Hello World
「ファイルを直接実行」「bashコマンドで実行」とした場合、新しくシェルが起動されて実行されます。つまり、現在のシェルに影響を与えません。
sourceコマンド、
ドット(.)コマンドによる実行
sourceコマンド
ドット(.)コマンド
で実行した場合、実行したシェル(カレントシェル)から起動されます。つまり、現在のシェルに影響を与えます。 例えば、スクリプト内でcdを行なっていれば、スクリプト実行後、ディレクトリが移動された状態になります。
変数
シェル変数
ローカル変数のようなもので、子プロセスでは引き継がれません。
全ての変数の設定を表示
set
指定した変数の設定を表示
set | grep 変数名
変数に値を設定
余計なスペースを入れないでください。
変数名=値
変数の定義を削除
unset 変数名
環境変数
グローバル変数のようなもので、子プロセスでも引き継ぎます。
シェル変数を環境変数に変更
export シェル変数名
環境変数の変更
export <オプション> 環境変数名=値
実行するコマンドにのみ環境変数を一時的に設定
env 環境変数名=値 コマンド
変数の出力
#!/bin/bash
string="Hello world"
echo $string
echo '$string'
echo "$string"
echo ${string}
Hello world
$string
Hello world
Hello world
'(シングルクォート)
で囲むと展開されません。
変数を数字として扱う方法
シェル変数は文字です。なので、下記のように文字として表示されます。
$ cat add1
#!/bin/bash
x=3
y=10
z=$x+$y
echo $z
$
$ ./add1
3+10
数字として扱うには、下記のように$(( ))
で囲みます。
$ cat add2
#!/bin/bash
x=3
y=10
z=$((x + y))
echo $z
$
$ ./add2
13
コマンド置換(コマンドの出力結果を文字列として利用する方法)
$()
で囲む、もしくは バッククォート
で囲みます。個人的には、$()
の方が見やすいです。
$ echo "今日は$(date)です"
今日はSun Nov 18 12:51:28 JST 2018です
$
$ echo "今日は`date`です"
今日はSun Nov 18 12:51:47 JST 2018です
引数
特殊変数で引数を取得できます。
特殊変数 | 概要 |
---|---|
$0 | シェルスクリプトのファイル名 |
$1 | 1 番目の引数 |
$2 | 2 番目の引数 |
$# | 引数の数 |
$$ | プロセス番号 |
$* | 全引数リスト(”$1 $2 … $n”) |
$@ | 全引数リスト(”$1″ “$2” … “$n”) |
下記スクリプトで動作確認します。
#!/bin/bash
echo $0
echo $1
echo $2
echo $#
echo $$
echo $*
echo $@
$ ./arg aaa bbb ccc ddd
./arg
aaa
bbb
4
92494
aaa bbb ccc ddd
aaa bbb ccc ddd
制御構造
if文
if 条件式
then
実行文1
else
実行文2
fi
$ cat if
#!/bin/bash
if [ 1 -ge 2 ]
then
echo "AAA"
else
echo "BBB"
fi
$
$ ./if
BBB
case文
case 条件式 in
値1)
実行文1;;
値2)
実行文2;;
:
:
esac
$ cat case
#!/bin/bash
x=BBB
case $x in
AAA)
echo "AAA"
;;
BBB)
echo "BBB"
;;
CCC)
echo "CCC"
;;
*)
;;
esac
$
$ ./case
BBB
for文
for 変数名 in 変数に代入する値のリスト
do
実行文
done
$ cat for
#!/bin/bash
for i in `seq 10 15`
do
echo $i
done
$
$ ./for
10
11
12
13
14
15
while文
while 条件文
do
実行文
done
以下例では、現在の分数が10分以上のときだけ hello
と出力します。
$ cat while
#!/bin/bash
while true
do
MINUTE=`date +"%M"`
if test ${MINUTE} -ge 10
then
echo ${MINUTE}
echo "hello"
sleep 60
else
echo ${MINUTE}
sleep 60
fi
done
$
$ ./while
15
hello
16
hello
条件文の作り方
条件文の書式
testコマンドを利用する方法
if test 1 -ge 2
then
echo "AAA"
else
echo "BBB"
fi
[] で囲む方法
if [ 1 -ge 2 ]
then
echo "AAA"
else
echo "BBB"
fi
条件式と[]の間にスペースが必要なので注意してください。
応用例
以下例では、特定のファイルに特定の文字列が含まれていない場合、echoします。
grep xxx file_path > /dev/null
if test $? -ne 0
then
echo "AAA"
fi
$?
には、最後に実行したコマンドの exit値(終了ステータス)
が入力されています。
一般的に以下の値が入力されます。
- コマンド成功時には
0
- 失敗時には
1
ファイル判定
書式 | 判定内容 |
---|---|
-d ファイル名 | 指定したファイルが ディレクトリ なら真 |
-f ファイル名 | 指定したファイルが 通常ファイル なら真 |
-L ファイル名 | 指定したファイルが シンボリックリンク なら真 |
-r ファイル名 | 指定したファイルが 読み取り可能 なら真 |
-w ファイル名 | 指定したファイルが 書き込み可能 なら真 |
-x ファイル名 | 指定したファイルが 実行可能 なら真 |
-e ファイル名 | 指定したファイルが 存在すれば 真 |
-s ファイル名 | 指定したファイルの ファイルサイズが0より大きければ 真 |
文字列判定
書式 | 判定内容 |
---|---|
-n 文字列 | 文字列の長さが0より大きければ真 |
-z 文字列 | 文字列の長さが0であれば真 |
文字列1 = 文字列2 | 2つの文字列が等しければ真 |
文字列1 != 文字列2 | 2つの文字列が等しくなければ真 |
数値判定
書式 | 判定内容 |
---|---|
数値1 -eq 数値2 | 2つの数値が等しければ真 |
数値1 -ge 数値2 | 数値1が数値2以上であれば真 |
数値1 -gt 数値2 | 数値1が数値2より大きいのであれば真 |
数値1 -le 数値2 | 数値1が数値2以下であれば真 |
数値1 -lt 数値2 | 数値1が数値2未満であれば真 |
数値1 -ne 数値2 | 2つの数値が等しくなければ真 |
論理結合
書式 | 判定内容 |
---|---|
!条件 | 条件が偽であれば真 |
条件1 -a 条件2 | AND条件 |
条件1 -o 条件2 | OR条件 |
その他豆知識
関数
$ cat function
#!/bin/bash
HelloWorld()
{
echo "Hello World"
echo "Hello World"
}
HelloWorld
$
$ ./function
Hello World
Hello World
引数は、通常のシェルスクリプトと同様に $1
$2
などの形でアクセスできます。
※豆知識
unset 関数名
- 関数を削除します。
declare -f
- 定義されている関数のみを表示します。
- setでは変数と関数の両方が表示されます。
コメント
一行コメント
# echo "Hello world!"
複数行コメント
<<COMMENT
echo "Hello world!"
echo "Hello world!"
echo "Hello world!"
COMMENT
COMMENT
の箇所は任意の文字列でかまいません。
キーボード入力受け付け
標準入力からの入力を受け付けるには、readコマンド
を利用します。
下記例では、キーボードから入力した文字列を、変数usernameに格納しています。
read username
echo "Hello, $username!"
内部コマンドの確認
test
や read
は内部コマンドです。
内部コマンドの一覧を表示するには、helpコマンド
を利用します。
内部コマンドの説明を確認するには下記のようにします。
help 内部コマンド名