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 foundPATHの設定は以下コマンドで確認できます。
$ echo $PATHPATHの追加は、下記のように行います。
$ export PATH=$PATH:追加したいパス実際に確認します。
$ ls
hello
$
$ pwd
/tmp
$
$ export PATH=$PATH:/tmp
$
$ hello
Hello Worldbashコマンドで実行
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 
BBBcase文
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 
BBBfor文
for  変数名  in  変数に代入する値のリスト
do
     実行文
done$ cat for 
#!/bin/bash
for  i  in  `seq  10  15`
do
     echo  $i
done
$ 
$ ./for 
10
11
12
13
14
15while文
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!"
COMMENTCOMMENT の箇所は任意の文字列でかまいません。
キーボード入力受け付け
標準入力からの入力を受け付けるには、readコマンド を利用します。
下記例では、キーボードから入力した文字列を、変数usernameに格納しています。
read  username
echo  "Hello, $username!"内部コマンドの確認
test や read は内部コマンドです。
内部コマンドの一覧を表示するには、helpコマンドを利用します。
内部コマンドの説明を確認するには下記のようにします。
help  内部コマンド名 
			 
			 
			 
			 
			 
			 
			