シェルスクリプト(shell script)の作り方・構文をまとめました。
随時追加していきます。
スクリプトの最初の 1 行目の「シバン(shebang)」(#!/bin/bash or #!/bin/sh)
スクリプトの最初の 1 行目です。
#!/bin/bash |
もしくは「sh」の場合もあります。
#!/bin/sh |
「#!/bin/sh」と「#!/bin/bash」の違いはほぼありません。
あるとすれば以下の違いくらいです。
- #!/bin/sh ← POSIX 標準
- #!/bin/bash ← POSIX 標準ではない
「/bin/bash は POSIX 標準ではない」と聞くと機能が少ないのではないかと思うかもしれませんが、逆です。
逆に「/bin/sh」は POSIX 標準から外れないように作られているので若干できることが少なくなります。(準拠しなければいけないのでその分制限されます)
通常は「#!/bin/bash」で全く問題ないはずです。
普段の Linux 上での作業は「/bin/bash」を利用していることがほとんどだからです。
/etc/passwd ファイルを確認するとログインシェルは「/bin/bash」になっていると思います。
(たまにシェルスクリプト好きの人が /bin/csh を使っていることがありますが)
[test@SAKURA_VPS ~]$ cat /etc/passwd
~ 省略 ~
test:x:1004:1004::/home/test:/bin/bash |
ファイルに日付や時刻を入れる
以下のような日付や時刻入りのファイル名を作成したい場合です。
test_20180513-105432 ← 2018年5月13日10時54分32秒に作成したファイルです。 |
以下のコマンドで日付と時刻をファイル名に付けられます。
[root@SAKURA_VPS ~]# touch test_`date “+%Y%m%d-%H%M%S”`
[root@SAKURA_VPS ~]# |
変数に入れる場合
JIKOKU=`date “+%Y%m%d-%H%M%S”` |
if [ “$PS1” ]; then のパターン
シェルの if 文では
if 条件式 ; then
となっています。
if [ “$PS1” ]; then
はどんな条件になるのでしょうか。
[] で test コマンドの代わりになります。
これなら直感的に何を確認しているのかすぐに分かります。
if [ “$TEST01” = “$TEST02” ]; then
つまり「$TEST01」と「$TEST02」の値が同じかどうかを調べています。
しかし、if [ “$PS1” ]; then は、[]の中の値が1つしかありません。
サンプルスクリプト
サンプルスクリプトを作成しました。
[test@cent07 ~]$ vi test.sh #!/bin/sh
# TESTに値をセット
# ただ単に変数だけ入れた状態で実行
# あえて TEST0 に値をセットせずに空にする
# ただ単に変数だけ入れた状態で実行
# 変数TESTの中身を確認 # ただ単に変数だけ入れた状態で実行 |
実行結果
以下、スクリプトの実行結果です。
[test@cent07 ~]$ ./test.sh
偽
偽 |
なるほど。
「偽」が返ってきます。
つまり「 if [ “$PS1” ]; then 」で何をチェックしていたのかというと、変数 $PS1 に値が入っているかチェックをしていたということになります。
私が見逃しただけかもしれませんが、test コマンドでオプションなしで変数が1つだけ入っている場合は、変数が値を持っているかどうかチェックをしていたということです。
if [ ! 式 ]; then の場合
! は「NOT(否定)」です。
- 終了ステータスが「0(正常終了)」の場合 ← 偽(1,false)になる
- 終了ステータスが「0以外(異常終了)」の場合 ← 真(0,true)になる
【例】
まずは NOT を使わない場合の例です。
[root@SAKURA_VPS script]# vi test01.sh |
実行すると以下のようになります。
[root@SAKURA_VPS script]# ./test01.sh |
次に NOT を使ってみます。
■スクリプト例
[root@SAKURA_VPS script]# vi test02.sh |
■スクリプト実行
[root@SAKURA_VPS script]# ./test02.sh 偽 [root@SAKURA_VPS script]# |
以下の構文の場合(NOT がない場合)
VAR_LOG_DIR=/var/log if[ -d $VAR_LOG_DIR -a -w $VAR_LOG_DIR ]; then |
■test コマンドの構文
- -d XXX ← ディレクトリの場合は「真」になります。
- XXX -a XXX ← AND 条件です。両側の式が「真」の場合のみ「真」になります。片方が「偽」の場合は、もう片方が「真」でも「偽」になります。
- -w XXX ← 書き込み権限がある場合「真」になります。
■スクリプト例
[root@SAKURA_VPS script]# vi test03.sh |
■スクリプト実行
[root@SAKURA_VPS script]# ./test03.sh |
NOT で全体を否定する場合はカッコで囲む
NOT で全体を否定したい場合はカッコ(「(」,「)」)で囲みます。
カッコで囲まれた部分は、他よりも優先度が高くなります。
■スクリプト例
[root@SAKURA_VPS script]# vi test04.sh |
■スクリプト実行例
[root@SAKURA_VPS script]# ./test04.sh |
2>&1(リダイレクト)はどういう意味か?
Linux には「ファイルディスクリプタ」と呼ばれる、プログラムがアクセスするファイルや標準入出力などをOSが識別するために用いる識別子
■ファイルディスクリプタ
- 0 ← 標準入力(stdin)
- 1 ← 標準出力(stdout)
- 2 ← 標準エラー出力(stderr)
「&」を付け忘れて「>1」と書くと「1」というファイルにリダイレクトされてしまいます。
「&1」と記述することで、標準出力にリダイレクトされるようになります。
■標準出力に出力される
$ echo “test” |
■標準出力に出力されたメッセージをファイルに書き込む
$ echo “test” > test.txt |
■エラーメッセージが標準エラー出力に出力される
$ echaa “test” |
■エラーメッセージを標準出力にリダイレクトしてファイルに書き込む
$ echaa “test” > test.txt 2>&1 |
まとめ
今後もシェルスクリプトで気が付いた点がありましたらどんどん追加していきます。
コメント