はじめに
テスト業務の効率化でbatファイルとシェルスクリプトを初めて作成しました。作成時に学んだポイントや注意点を備忘録としてまとめます。
作業環境
- OS: Windows11
- テスト環境: Linux
batファイル作成で学んだこと
普段はMacユーザーのため、batファイル作成は初体験でした。
技術記事やAIを参考に進めて学んだポイントです。
基本的なポイント
- メモ帳で作成可能
- 処理内容の出力を非表示にするには、ファイル先頭に
echo offを記載 - batの構文は複雑なので、内部で
powershell Commandを活用するのが効率的
PowerShell活用のメリット
- batファイル内なら、PowerShellの権限制限があっても
powershell Commandで実行可能 - PowerShellコマンド使用時は以下の書き方で行継続できる
- ダブルクォーテーションで行毎に囲む
- 行末尾に
^を記載
ファイル操作での注意点
サーバー間でのファイル移動
- Linuxテスト環境からローカルへのファイル移動は
WinSCPが便利
権限関連
- ファイル編集ができない場合は所有者と権限を確認する
ファイル比較
Windows
リポジトリ管理でGitなどを使用していない場合は WinMerge が便利
業務で使用したコマンド
Windows
-
dir- ファイルやディレクトリを一覧表示する -
net user- ローカルPCに登録されているユーザーアカウントの一覧を確認できる -
icacls- ファイルやフォルダーに設定されているアクセス権を確認できる -
del- ファイルやディレクトリを削除する -
cls- コマンドプロンプトの画面に出力されている内容をクリアする -
chkdsk- ディスクの状態を確認する -
systeminfo- OSの構成を確認する -
ping- ネットワークの疎通確認する -
ipconfig- TCP/IPのネットワーク設定を確認する
Linux
-
ls -l- 詳細なファイル一覧表示、権限と所有者の確認ができる -
su- ユーザー切り替え -
chmod- ファイル権限変更 -
chown- ファイル所有者変更 -
id- ユーザーIDとグループIDの確認 -
whoami- 現在ログインしているユーザーの名前を表示 -
uname -n- ホスト名の確認 -
>>- 出力結果を追記 -
find . -type f | wc -l- カレントディレクトリの総ファイル数の確認(各ファイルパスの行数をカウント) -
du -s- ディレクトリのサイズを確認 -
find . -type f | sort > size.txt- ファイル一覧をテキストに出力 -
xargs- 前のコマンドの出力を、次のコマンドの引数として渡す -
awk- テキストを列(フィールド)ごとに分割して処理 -
sed- 文字列の置換・削除・抽出 -
rsync -a- ファイルやディレクトリをアクセス権限もそのままコピー - ファイル一覧の差分
find . -type f | sort > before.txt
find *_backup_* -type f | sort > after.txt
diff before.txt after.txt
shスクリプトの作成で学んだこと
- ダブルクォーテーション (") の中で
$変数名と書くことで変数の値が展開される -
set -eやexit 1でエラー処理を行う -
#!/bin/bashのシバンをファイルの1行目に書く必要がある - 実行するときは
bash ./シェルスクリプト名と書く
shスクリプト作成例
想定ディレクトリ構造
project/
├── logs/
│ ├── app.log
│ └── error.log
├── data/
│ └── temp/
│ ├── cache1.tmp
│ └── cache2.tmp
└── src/
└── debug/
└── trace.log
具体例
コードを表示
# ファイル出力版
diff <(find folder_a -type f | xargs ls -l | awk '{print $9":"$1}' | sort) <(find folder_b -type f | xargs ls -l | awk '{print $9":"$1}' | sort) > 権限差分.txt
# 具体例: originalとbackupの比較
diff <(find original -type f | xargs ls -l | awk '{print $9":"$1}' | sort) <(find backup -type f | xargs ls -l | awk '{print $9":"$1}' | sort)
コードを表示
#!/bin/bash
set -e # エラー時終了(明示的なエラーハンドリングを追加したため一部無効化)
# 設定
CURRENT_DIR=$(pwd)
BACKUP_DIR="${CURRENT_DIR}_backup_$(date +%Y%m%d_%H%M%S)"
ARCHIVE_NAME="$(basename "$CURRENT_DIR")_$(date +%Y%m%d_%H%M%S).zip"
EXTERNAL_SCRIPT="./external_script.sh"
CLEAR_TARGET_DIRS=("logs" "temp" "cache" "output" "data/temp" "src/debug") # ネストしたディレクトリも対応
CLEAR_TARGET_EXTENSIONS=("*.java" "*.tmp" "*.log" "*.bak")
EXCLUDE_PATTERNS=("*.zip" "*_backup_*" "*.log") # 除外するファイル・パターン
# ステップ1: スクリプト実行
echo "1. スクリプト実行中..."
if [ -f "$EXTERNAL_SCRIPT" ]; then
[ ! -x "$EXTERNAL_SCRIPT" ] && chmod +x "$EXTERNAL_SCRIPT"
bash "$EXTERNAL_SCRIPT" 2>&1
echo " 外部スクリプト実行完了"
else
echo " エラー: 外部スクリプトが見つかりません ($EXTERNAL_SCRIPT)"
echo " 処理終了"
exit 1
fi
echo ""
# ステップ2: フォルダ複製
echo "2. フォルダ複製中..."
cp -a "$CURRENT_DIR" "$BACKUP_DIR"
echo " 複製完了: $BACKUP_DIR"
# ステップ2: フォルダ複製
echo "2. フォルダ複製中..."
# rsyncで除外パターンを指定してコピー
EXCLUDE_ARGS=""
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude=$pattern"
done
if rsync -a $EXCLUDE_ARGS "$CURRENT_DIR/" "$BACKUP_DIR/"; then
echo " 複製完了: $BACKUP_DIR"
echo " 除外パターン: ${EXCLUDE_PATTERNS[*]}"
else
echo " フォルダ複製に失敗しました"
echo " 処理終了"
exit 1
fi
# クリーンアップ処理
echo "クリーンアップ処理中"
CLEANUP_COUNT=0
# 特定フォルダ内ファイルを削除する
for dir in "${CLEAR_TARGET_DIRS[@]}"; do
TARGET_PATH="$BACKUP_DIR/$dir"
[ ! -d "$TARGET_PATH" ] && continue
FILE_COUNT=$(find "$TARGET_PATH" -type f 2>/dev/null | wc -l)
[ "$FILE_COUNT" -eq 0 ] && continue
if find "$TARGET_PATH" -type f -delete 2>/dev/null; then
CLEANUP_COUNT=$((CLEANUP_COUNT + FILE_COUNT))
fi
done
# 特定拡張子ファイルを削除
for ext in "${CLEAR_TARGET_EXTENSIONS[@]}"; do
FOUND_FILES=$(find "$BACKUP_DIR" -name "$ext" -type f 2>/dev/null)
[ -z "$FOUND_FILES" ] && continue
FILE_COUNT=$(echo "$FOUND_FILES" | wc -l)
if find "$BACKUP_DIR" -name "$ext" -type f -delete 2>/dev/null; then
CLEANUP_COUNT=$((CLEANUP_COUNT + FILE_COUNT))
fi
done
echo " クリーンアップ完了: $CLEANUP_COUNT 個のファイルを処理"
echo ""
# ステップ3: フォルダ圧縮(一部ファイル除外)
echo "3. フォルダ圧縮中..."
if zip -r "${ARCHIVE_NAME}" "$(basename "${CURRENT_DIR}") -x './test1.txt' './test2.txt' "; then
echo " 圧縮完了: ${ARCHIVE_NAME}"
else
echo " フォルダ圧縮に失敗しました"
echo " 処理終了"
exit 1
fi
echo ""
# 結果
echo "=== 処理完了 ==="
echo "複製フォルダ: ${BACKUP_DIR}"
echo "圧縮フォルダ: ${ARCHIVE_NAME}"
echo "実行時刻: $(date)"
学んだこと
-
batファイル
PowerShellとの組み合わせが効果的 -
シェルスクリプト
エラーハンドリングと変数展開が特徴的 -
権限管理
Linux環境では所有者・権限確認が必須 -
ファイル転送
WinSCPでのファイル転送が便利 -
ファイル比較
WinMergeでのファイル比較が便利
まとめ
初めて業務でスクリプト作成しましたが、段階的に機能を追加しながら学習することができました。特にエラーハンドリングの重要性を実感できる良い経験でした。
参考サイト