シェルスクリプトとは
シェルスクリプトは、コマンドを連続して実行するプログラムです。手作業で繰り返す操作を自動化できます。
シェルスクリプトのメリット
- ✅ 繰り返し作業の自動化
- ✅ 複雑なコマンドを簡単に実行
- ✅ エラーを減らせる
- ✅ 処理の再現性が高い
- ✅ チームでの共有が容易
基本的なスクリプトの作成
Hello Worldスクリプト
#!/bin/bash
# これはコメントです
echo "Hello, World!"重要な要素:
- #!/bin/bash: シェバン(shebang) - どのシェルで実行するか指定
- echo: 文字列を出力するコマンド
- #: コメント(実行されない)
スクリプトの作成と実行
# スクリプトファイルを作成
nano hello.sh
# 実行権限を付与
chmod +x hello.sh
# 実行
./hello.sh変数の使い方
変数の定義と使用
#!/bin/bash
# 変数の定義(=の前後にスペースを入れない)
name="太郎"
age=25
# 変数の使用($を付ける)
echo "名前: $name"
echo "年齢: $age歳"
# 波括弧で明示的に指定
echo "名前は${name}です"コマンドの結果を変数に格納
#!/bin/bash
# $()でコマンドの結果を変数に代入
current_date=$(date +%Y-%m-%d)
file_count=$(ls -1 | wc -l)
echo "今日は: $current_date"
echo "ファイル数: $file_count個"条件分岐(if文)
基本的なif文
#!/bin/bash
age=20
if [ $age -ge 20 ]; then
echo "成人です"
else
echo "未成年です"
fi比較演算子
- -eq: 等しい(equal)
- -ne: 等しくない(not equal)
- -gt: より大きい(greater than)
- -ge: 以上(greater or equal)
- -lt: より小さい(less than)
- -le: 以下(less or equal)
文字列の比較
#!/bin/bash
str="hello"
if [ "$str" = "hello" ]; then
echo "一致しました"
fi
# 空文字チェック
if [ -z "$str" ]; then
echo "空です"
else
echo "空ではありません"
fiファイルの存在確認
#!/bin/bash
if [ -f "test.txt" ]; then
echo "test.txtは存在します"
else
echo "test.txtは存在しません"
fiファイル・ディレクトリのテスト演算子:
- -f: ファイルが存在する
- -d: ディレクトリが存在する
- -r: 読み取り可能
- -w: 書き込み可能
- -x: 実行可能
ループ処理
forループ
#!/bin/bash
# 連番のループ
for i in 1 2 3 4 5
do
echo "数値: $i"
done
# {開始..終了}の形式
for i in {1..5}
do
echo "番号: $i"
done
# ファイルのループ
for file in *.txt
do
echo "ファイル: $file"
donewhileループ
#!/bin/bash
count=1
while [ $count -le 5 ]
do
echo "カウント: $count"
count=$((count + 1))
done関数の定義
#!/bin/bash
# 関数の定義
greet() {
echo "こんにちは、$1さん!"
}
# 関数の呼び出し
greet "太郎"
greet "花子"
# 戻り値を持つ関数
add() {
result=$(($1 + $2))
echo $result
}
sum=$(add 10 20)
echo "合計: $sum"実用的なスクリプト例
例1: バックアップスクリプト
#!/bin/bash
# バックアップ設定
SOURCE_DIR="/home/user/documents"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="backup_${DATE}.tar.gz"
# バックアップ実行
echo "バックアップを開始します..."
tar -czf "${BACKUP_DIR}/${BACKUP_FILE}" "$SOURCE_DIR"
if [ $? -eq 0 ]; then
echo "バックアップ成功: ${BACKUP_FILE}"
else
echo "バックアップ失敗"
exit 1
fi
# 7日以上前のバックアップを削除
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +7 -delete
echo "古いバックアップを削除しました"例2: ログ監視スクリプト
#!/bin/bash
LOG_FILE="/var/log/app.log"
KEYWORD="ERROR"
# ログファイルの監視
tail -n 0 -f "$LOG_FILE" | while read line
do
if echo "$line" | grep -q "$KEYWORD"; then
echo "[ALERT] エラー検出: $line"
# メール通知やSlack通知などを追加可能
fi
done例3: システム情報レポート
#!/bin/bash
REPORT_FILE="system_report_$(date +%Y%m%d).txt"
echo "=== システムレポート ===" > "$REPORT_FILE"
echo "作成日時: $(date)" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
echo "--- ディスク使用量 ---" >> "$REPORT_FILE"
df -h >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
echo "--- メモリ使用量 ---" >> "$REPORT_FILE"
free -h >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
echo "--- CPU情報 ---" >> "$REPORT_FILE"
lscpu | grep "Model name" >> "$REPORT_FILE"
echo "レポートを作成しました: $REPORT_FILE"引数の処理
位置パラメータ
#!/bin/bash
echo "スクリプト名: $0"
echo "第1引数: $1"
echo "第2引数: $2"
echo "全引数: $@"
echo "引数の数: $#"実行例:
./script.sh apple banana
# 出力:
# スクリプト名: ./script.sh
# 第1引数: apple
# 第2引数: banana
# 全引数: apple banana
# 引数の数: 2オプション解析
#!/bin/bash
while getopts "f:v" opt; do
case $opt in
f)
filename="$OPTARG"
echo "ファイル: $filename"
;;
v)
verbose=true
echo "詳細モード有効"
;;
\?)
echo "無効なオプション: -$OPTARG"
exit 1
;;
esac
doneエラーハンドリング
終了ステータスの確認
#!/bin/bash
# コマンド実行
cp source.txt dest.txt
# 直前のコマンドの終了ステータス
if [ $? -eq 0 ]; then
echo "コピー成功"
else
echo "コピー失敗"
exit 1
fiset -e でエラー時に即終了
#!/bin/bash
# エラーが発生したら即座に終了
set -e
echo "処理開始"
cd /nonexistent/directory # ここでエラーが発生し終了
echo "この行は実行されない"エラートラップ
#!/bin/bash
cleanup() {
echo "クリーンアップ処理実行"
rm -f temp_file.txt
}
# エラー時にcleanup関数を実行
trap cleanup EXIT ERR
echo "処理開始"
# 何か処理
echo "処理完了"デバッグ技法
デバッグモード
#!/bin/bash
# -x オプションで実行内容を表示
set -x
name="太郎"
echo "Hello, $name"
# デバッグモード解除
set +x実行時デバッグ
# コマンドラインからデバッグ実行
bash -x script.shベストプラクティス
1. シェバンは必ず記述
#!/bin/bash2. 変数は引用符で囲む
# 良い例
if [ "$var" = "value" ]; then
# 悪い例(変数が空の場合エラー)
if [ $var = "value" ]; then3. エラーチェックを徹底
set -euo pipefail
# -e: エラーで終了
# -u: 未定義変数でエラー
# -o pipefail: パイプ中のエラーを検出4. コメントを適切に書く
# 何をするスクリプトか
# 引数は何か
# 前提条件は何か便利なワンライナー集
# ファイルの一括リネーム
for f in *.txt; do mv "$f" "${f%.txt}.bak"; done
# 特定の拡張子ファイルを検索して削除
find . -name "*.log" -type f -delete
# ディレクトリサイズのトップ10
du -sh * | sort -rh | head -10
# プロセスのメモリ使用量トップ10
ps aux | sort -rk 4 | head -10まとめ
シェルスクリプトは日常的な作業を劇的に効率化できる強力なツールです。
学んだこと
- 変数、条件分岐、ループの基本構文
- 関数の定義と使用
- 実用的なスクリプト例
- エラーハンドリングとデバッグ
- ベストプラクティス
次のステップ
- sedやawkでテキスト処理
- cronで定期実行
- systemdでサービス化
- より高度な制御構造