はじめに
とある作業をcronに設定して自動化したかったので、その時勉強したシェルスクリプトについてのまとめです。今どきはPythonでコマンド実行できてしまいますが、シェルスクリプトならLinux環境さえあればどこでも実行できるので、こちらを選択しました。
慣れるまで少しだけ時間がかかりましたが、やってること自体は単純なのでコツさえつかめば誰でも書けるようになると思います。
そもそもシェルスクリプトとは?
POSIXおよびIEEE Std 1003.1-2008で定義されたシェルコマンド言語を用いるスクリプトである。通常、オペレーティングシステムのシェルまたはコマンドラインインタプリタ向けに書かれる。狭義では、Unixシェルで用いられるスクリプト言語を指す。
wikipedia 引用
簡単に言うと、複数のコマンドを書き留めておいて、それらを上から実行してくれるファイルのこと。書き留めたコマンドをまとめて実行できるようになるので、cronなど定期的に実行するときに便利。拡張子は.sh。
開発環境
コーディングするうえで、環境はとっても大事
エディタ
Visual Studio Code
拡張機能(意外と大切)
ShellCheck
文法ミスやタイポを指摘してくれる
場合によっては1クリックで修正できるので便利
Error Lends
波線の中身をソースコードの右側に表示してくれる
わざわざマウスカーソルを合わせなくていいので便利
shell-format
保存したとき、スクリプトのフォーマットを整えてくれる
人によっては好き嫌い分かれるかも?
書き方
シバン
シバン(shebang)はインタプリタを指定するために書きく。「シェバン」とか「シェバング」なんて呼ばれることもあり、これを指定しないとインタプリタが指定されないため、動作が不安定になってしまう(かもしれない)。シェルスクリプトでは1行目に以下のように書く。
#! /bin/bash
コメント
シェルスクリプトのコメントアウトは「#」で行います。
#! /bin/bash
# これはコメントです
# 実行されないので処理内容などを書き込みましょう
また、「"<< 任意文字列" コード "任意文字列"」で複数行コメントアウトすることもできる。
#! /bin/bash
<< COMENTOUT
ここもコメントなので実行されません
スクリプトの仕様をトップに書いておく時などに便利です
COMENTOUT
シバンは「#!」で指定するのに、コメントも「#」とは意地悪ですね
実行順番
基本的に上から順に実行される。
#! /bin/bash
ls -la # bashのコマンドは基本なんでも使える
cd /var/www/html/ # パスを指定するタイプのものは絶対パスで指定しましょう
echo 'これが最後に実行されます'
exit 0 # C言語いうところのreturn システム変数'$?'に0を渡します
コマンドは基本的になんでも使えます。特にechoと>>はよく使う。
変数
変数はアルファベットと数字の組み合わせで宣言できます。代入するときは名前だけでよいが、使うときは$を付けて呼び出す。
再書き込みをされたくない場合はreadonlyとすることで再書き込みを防止できる。
#! /bin/bash
str='変数' # `=`の前後にスペースを入れてはいけません
readonly NUM=100 # 再代入をしたくない場合はこちら。定数になるので、大文字で宣言すると良いかも
today=`date` # 出力結果を変数に入れることもできます
echo $str # 呼び出すときは'$'を付けます
echo $(ls -la) # 実行結果を呼び出すときは'$(コマンド)'とします
特殊変数
もちろん、システムで予約された変数が存在する。
変数
$#
コマンドライン引数の数
\$1 ~ \$9
コマンドライン引数
\$0
実行したコマンド
\$?
最後に実行したコマンドの終了状態。成功時は0、失敗時はそれ以外の値が入っていることが多い
\$$
現在のシェルのプロセス番号
よく使うのはこのあたり
if文
シェルスクリプトでもif文で条件分岐することができる。
if [ 条件文 ] then <コマンド> elif [ 条件文 ] then <コマンド> else fiと書く。
#! /bin/bash
var='Hello'
if [ $var = 'Hello' ]; # 大括弧の内側の端には必ず空白を入れること
then
echo 'Hello'
fi
if [ ! $var = 'こんにちは']; # 全体を否定するときは左端に'!'を書く
then
echo 'こんにちは'
else; # elseには'then'が不要
echo 'さただばー'
fi
比較演算子
シェルスクリプトは数値比較の演算子が少し特殊
演算子
意味
A = B
左右の文字列が一致したときに真
A != B
左右の文字列が不一致のときに真
A -eq B
数値が一致すれば真
A -ne B
数値が不一致ならば真
A -ge B
AがB以上なら真
A -gt B
AがBより大きれけれ真
A -le B
AがB以下なら真
A -lt B
AがBより小さければ真
ファイルの存在チェック
ファイルが存在するかどうかもif文で行うことができる。
サンプルでは相対パスで指定しているが、絶対パスで指定した方が絶対良い
#! /bin/bash
# 指定された名前のファイルorディレクトリが存在する場合
# if [ -e 'sample' ];
# 指定された名前のディレクトリが存在する場合
# if [ -d 'sample' ];
# 指定された名前のファイルが存在する場合
if [ -f 'sample' ];
then
echo 'sampleが存在します'
rm sample
fi
関数
シェルスクリプトでは関数も宣言できる。
function <任意の関数名>(){ 任意の処理 }
シェルの変数は基本グローバルであるため、関数内のみで使用したい場合はlocalを付けること
#! /bin/bash
# 実は意味のない関数
function set_name() {
local name=$1 # name変数のスコープはset_nameの中だけになる
}
set_name 'Tanaka' # 呼び出すときは()は不要
標準入力
ここまできたら標準入力で変数に値を入れたいこともあるだろう。そんな時はreadコマンドを使う。
#! /bin/bash
ls -la
read -p 'どのファイルを削除しますか?: ' filename # 変数'filename'に標準入力から値を入れる
if [ -f $filename ]; # ファイルが存在する場合
then
rm $filename
echo '${filename}を削除しました'
exit 0
else;
echo 'そのような名前のファイルは存在しません'
exit 1
fi
そのほか
シェルスクリプトにはそのほかにもいろいろな機能がある。詳しくはここで書かないので、気になる方は自分で調べてみてください。決して書くのが力尽きたわけではない。
for文,while文
いわずと知れたループコンビ
配列
↑のループとうまく組み合わせると便利
case文
場合分けに便利
エラーコードを捌いて記録するときによく使う
trap
終了したときやCtrl + zで停止させたときなどの処理を書ける
エラー処理で非常に重要
select
準備した選択しの中から選べるようにできる
おわりに
初めての投稿だけあって、かなり気合の入った記事になってしまった(あまりの文量に、最後のほうは力尽きてしまったが…)。サーバーレスが流行っているこのご時世でも、シェルスクリプトが役に立つ場面はとても多いと感じた。ルーティンワークはすべてコンピュータに投げてしまって、自分たちはじっくりと別なことをしていきたいですね。
参考記事
https://qiita.com/kaw/items/ffdaf5d23627c0bd7e87
https://wa3.i-3-i.info/word14689.html
https://qiita.com/a_yasui/items/ec4f75b300410af8958d
https://eng-entrance.com/linux-shellscript-operator
↧