本文へスキップ
BecomeCoder
ブログ一覧Wikiコース一覧

シェルスクリプト入門|.shの書き方から実行・cron定期実行まで

#シェルスクリプト#bash#自動化#cron#初心者

結論:シェルスクリプトは「毎回手で打っているコマンドを、上から順にファイルへ書き写す」だけで始められます。 必要なのは、1行目のシバン(#!/bin/bash)、実行権限、そして変数・if・for・関数の4つの型だけ。ここまで書ければ、あとは cron に登録して「自分が寝ている間に動く仕組み」に変えられます。

「手で打つ」と「スクリプトにする」の決定的な違い

たとえば毎朝、こんな作業をしているとします。

  1. ログのディレクトリへ移動する
  2. 昨日のログからエラー行を数える
  3. 結果をファイルに書き出す

3行のコマンドです。手で打っても1分かかりません。それでもスクリプトにする価値があるのは、次の3つが手に入るからです。

つまりシェルスクリプトは「作業の高速化」というより、作業を仕組みに変える道具です。この考え方は 「シェルスクリプトとは ― 手作業を仕組みに変える」 で、実際に短いスクリプトを動かしながら確認できます。

Become-Coderのシェルスクリプトコースは全43レッスンで、エディタと端末が並んだ2画面の構成になっています。左でスクリプトを書き、右の端末で実行結果を見る、という現場と同じ流れを、ブラウザの中だけで再現できます。Linuxマシンも仮想環境も要りません。無料・登録不要です。

まず動かす:シバンと実行権限

スクリプトの1行目に書く #!/bin/bash をシバン(shebang)と呼びます。「このファイルは /bin/bash に読ませて動かしてください」というOSへの指示です。# で始まるのでコメントに見えますが、1行目に限り特別扱いされます。

#!/bin/bash

echo "おはようございます"
echo "今日の日付: $(date +%Y-%m-%d)"

これを script.sh として保存したら、実行方法は2通りあります。

現場で使われるのは後者ですが、作ったばかりのファイルには実行権限がありません。だから ./script.sh といきなり打つと「許可がありません」と怒られます。ここで登場するのが chmod です。

chmod +x script.sh
./script.sh

この「エラーを出す → chmod +x → 動く」という3ステップは、「シバンと実行権限 ― ./script.sh で動かす」 で実際に体験できます。権限の数字(755や644)の意味まで踏み込みたい人は chmod 755の意味とパーミッションの読み方 を参照してください。

覚えるのは4つの型だけ

型1:変数 ― 直書きをやめる

保存先のパスを10か所に直書きしたスクリプトは、引っ越しのとき10か所直すことになります。1か所でも漏れれば壊れます。変数は、この直し漏れを構造的に防ぐ道具です。

BACKUP_DIR=/home/user/backup
echo "保存先: $BACKUP_DIR"

代入するときは = の前後にスペースを入れない、使うときは $ を付ける。この2点だけ守れば動きます。設定を先頭にまとめておくと、3か月後の自分が助かります。「変数 ― 値に名前をつけて使い回す」 で、値を差し替えながら試せます。

コマンドの実行結果をそのまま値にする $( ) も同時に覚えると強力です。TODAY=$(date +%Y%m%d) のように書けば、日付つきのファイル名が作れます(「コマンド置換 ― 実行結果を値として取り込む」)。

型2:if ― 条件で分ける

シェルの if は、他の言語を知っている人ほど戸惑います。if の後ろに書くのは「条件式」ではなくコマンドだからです。

if [ -f logs/app.log ]; then
  echo "ログファイルがあります"
else
  echo "ログファイルがありません"
fi

[ は実はコマンドの名前で、だから [ の後ろと ] の前にはスペースが要ります。この前提さえ分かれば、あとは形を覚えるだけです。詳しくは 「if ― 条件で処理を分ける」 と 「ファイル判定 ― あるか・ディレクトリか・書けるか」 を参照してください。

型3:for ― まとめて処理する

シェルの for は、カウンタを回すというよりリストをなめるものです。実務で圧倒的に多いのは「ファイルを1つずつ処理する」形です。

for file in files/*.txt; do
  echo "処理中: $file"
done

ファイルの中身を1行ずつ処理したいなら while read の型を使います。ログ集計やCSV処理の定番なので、「1行ずつ処理する ― while read の型」 まで進んでおくと応用範囲が一気に広がります。基本形は 「for ― 並べた値を1つずつ処理する」 で扱っています。

型4:関数 ― 名前をつけてまとめる

同じ3行をスクリプトの中で4回書いているなら、関数の出番です。

log() {
  echo "[$(date +%H:%M:%S)] $1"
}

log "処理を開始します"

呼び出しが1行になるだけでなく、直すときも1か所で済みます。「関数 ― 処理に名前をつける」 で、引数の受け取り方まで含めて練習できます。

事故りやすいところ(先に知っておくと丸一日を溶かさずに済む)

シェルスクリプトの不具合は、文法エラーよりも「静かに間違って動く」形で現れます。代表的な3つを先に潰しておきましょう。

1. 失敗しても次の行に進んでしまう

シェルの既定の動きは「1行失敗しても、次の行を実行する」です。バックアップに失敗したのに、その次の「古いファイルを削除」だけが成功する——考えるだけで恐ろしい挙動です。対策は先頭に1行足すだけです。

#!/bin/bash
set -e
set -u

set -e は失敗したらそこで止める、set -u は未定義の変数を使ったらエラーにする指定です。詳しくは 「set -e / set -u ― 失敗したら止める」 を参照してください。

2. クォートを忘れてスペース入りのファイル名で壊れる

my report.txt のようなファイル名は、Windowsから持ち込まれたファイルでは珍しくありません。cat $file と書くと2つの引数として扱われて失敗しますが、cat "$file" なら正しく1つとして渡ります。変数を使うときは基本的に " で囲む、と体に入れてしまうのが安全です。" と ' の違いも含めて 「クォート ― ” と ’ の違いで結果が変わる」 と 「クォートの罠 ― スペース入りのファイル名」 で扱っています。

3. 引数を渡し忘れたときに壊滅的に動く

${1:-logs} のように既定値を書いておく、必須の引数が無ければ使い方を表示して exit 1 で止める。この2つを最初に決めておけば、事故の大半は防げます(「既定値と必須チェック ― 引数がなくても壊れない」)。動かないときの調べ方は 「デバッグ ― 動かないときの調べ方」 にまとめています。

cron で定期実行する

スクリプトが安定して動くようになったら、最後の一歩が定期実行です。Linuxには時刻になったらコマンドを実行してくれる仕組みが最初から入っていて、それが cron です。

予定は5つのフィールドで書きます。

0 3 * * *      毎日 3時0分
*/15 * * * *   15分おき
30 9 * * 1-5   平日の 9時30分

左から「分・時・日・月・曜日」で、* は「毎回」。暗記ではなく構造を理解すれば読めるようになります。仕組みは 「cron とは ― 時間で動く仕組み」、読み方は 「時刻の書き方 ― 5つのフィールドを読む」、登録は 「予定を登録する ― crontab の編集」 で、それぞれブラウザ内で実際に crontab を触りながら確認できます。

そして必ず読んでほしいのが 「cron の落とし穴 ― 手元で動くのに cron で動かない」 です。cronの相談の大半はこれで、原因はほぼ決まっています。

「動いたかどうかを後から確認できて、はじめて運用できる状態」という視点は 「ログと多重起動 ― 運用に耐えるバッチにする」 で扱っています。サーバー運用の文脈でのcronは、サーバーコースの 「定期実行と監視 ― cronで自動化し、ログとリソースで見張る」 でも登場します。

始める前の前提と、Windowsの人へ

シェルスクリプトは「コマンドを並べたもの」なので、ls cd cat grep を知っていることが前提になります。ここが怪しい人は、先にLinuxコースの 「pwd と ls ― 今どこ?何がある?」 から数レッスン触っておくと、スクリプトの中身がそのまま読めます。特に 「パイプ(|)― 出力を次のコマンドへ渡す」 は、1行1行を組み立てる土台です。

業務PCがWindowsで、Linux環境を用意しづらい場合は、Windows標準のバッチファイル(.bat)という選択肢もあります。バッチファイルのリファレンスはコード例中心の読み物として用意しています(ブラウザ実行には対応していません)。Excelの定型作業そのものを自動化したい場合は、シェルスクリプトより先に 事務職の業務効率化はプログラミングで何から? を読むほうが近道です。

次に読む

← ブログ一覧に戻る