空のファイルを作るには touch コマンド一択です。ファイルが存在しなければ0バイトの新規ファイルとして作成し、すでに存在すれば中身はそのままでタイムスタンプのみを現在時刻に更新します。シンプルなコマンドですが、ロックファイル・プレースホルダー・ログローテーション後の空ファイル準備など、実務での用途は幅広いです。
まず結論:空ファイルを作る最短コマンド
touch /path/to/newfile.txt
作成できたかどうかは ls -l で確認します。ファイルサイズが 0 と表示されているのが空ファイルの証拠です。
$ touch /tmp/flag.txt
$ ls -l /tmp/flag.txt
-rw-r--r-- 1 operator operator 0 Jul 22 10:30 flag.txt
ディレクトリが存在しない場合はエラーになります。事前に mkdir -p でパスを作っておくのが基本です。
mkdir -p /srv/app/logs && touch /srv/app/logs/app.log
タイムスタンプを指定した日時に変更する
既存ファイルの更新時刻(mtime)を任意の日時に変更したい場面があります。-d オプションが最も読みやすい方法です。
# 絶対日時で指定
touch -d "2024-03-01 09:00:00" /var/log/myapp/access.log
# 相対指定も使える
touch -d "yesterday" /tmp/test.txt
touch -d "2 days ago" /tmp/old_flag.txt
スクリプト内で使う場合は -t オプションのほうが書式が固定されているため扱いやすいです。書式は [[CC]YY]MMDDhhmm[.ss] です。
# 2024年3月1日 09:00 に設定
touch -t 202403010900 /var/log/myapp/access.log
なお、touch はデフォルトでmtime(更新時刻)とatime(アクセス時刻)の両方を変更します。mtimeだけを変更したい場合は -m、atimeだけなら -a を付けます。rsync などのバックアップツールはmtimeを差分検出の基準にするため、意図しない全量転送を防ぐには -m を明示するほうが安全です。
# mtimeのみ更新してatimeはそのまま
touch -m /var/log/myapp/access.log
実務でよく出るシナリオ3選
シナリオ1:ロックファイルで多重起動を防ぐ
cronジョブやバッチ処理の多重起動防止には、ロックファイルがシンプルで確実な手段です。以下のパターンが実務でよく使われます。
#!/bin/bash
LOCKFILE=/var/run/myjob.lock
if [ -f "$LOCKFILE" ]; then
echo "Already running. Exiting." >&2
exit 1
fi
touch "$LOCKFILE"
trap "rm -f $LOCKFILE" EXIT
# 本処理をここに書く
/usr/local/bin/myjob.sh
trap で EXIT シグナルを捕捉しておくと、スクリプトが異常終了したときもロックファイルが自動で削除されます。これを入れないと、次回以降の実行が永久にブロックされるという事故につながります。本番環境での痛い経験からこのパターンを採用した運用チームは多くあります。
シナリオ2:ログローテーション後の空ファイル準備
logrotate がログを退避させた後、アプリがすぐ書き込めるよう空ファイルを手動で準備したい場面があります。logrotate の create オプションでも同等のことはできますが、オーナーやパーミッションを細かく制御したい場合はスクリプト側で処理する方法がよく取られます。
# logrotateのpostrotateセクションから呼び出す例
touch /var/log/myapp/app.log
chown appuser:appgroup /var/log/myapp/app.log
chmod 640 /var/log/myapp/app.log
シナリオ3:Gitで空ディレクトリを追跡する
Gitは空ディレクトリを追跡できません。cache/ や tmp/ などのディレクトリをリポジトリに含めたい場合、慣例として .gitkeep という空ファイルを置きます。
# 複数ディレクトリに一括で.gitkeepを配置
touch /srv/app/{cache,logs,tmp}/.gitkeep
# Gitに追加して追跡開始
git add /srv/app/{cache,logs,tmp}/.gitkeep
ブレース展開を使うと複数パスをまとめて処理でき、繰り返しのコマンド入力を省けます。
複数ファイルをまとめて作成する
touch はスペース区切りで複数ファイルを同時に作成できます。ブレース展開と組み合わせると、連番ファイルの一括生成も一行で済みます。
# 個別指定
touch file1.txt file2.txt file3.txt
# 連番ファイルを10個一括作成
touch config_{01..10}.conf
# 拡張子違いで複数作成
touch report.{csv,json,log}
テスト環境の初期セットアップや、スクリプトで生成するファイル群のプレースホルダーをまとめて用意するときに便利です。
注意点とよくある落とし穴
rootで作成したファイルのオーナーを確認する
sudo touch /etc/myapp/flag で作成したファイルのオーナーはrootになります。アプリがそのファイルを書き込み対象にする場合、chown で適切なユーザーに変更しないと「Permission denied」が発生します。
sudo touch /etc/myapp/flag
sudo chown appuser:appgroup /etc/myapp/flag
タイムスタンプ変更は監査ログに残る
auditdが有効な環境では、touch -t によるタイムスタンプの変更がセキュリティログに記録されます。ファイルの改ざん検知と見なされることもあるため、目的と実施者を事前にチームへ共有しておくとトラブルを防げます。また、改ざんを目的とした過去日時へのタイムスタンプ書き換えは重大なセキュリティ事案です。作業の正当性を必ず確認してから実行してください。
既存ファイルへの touch は中身を消さない
touch 既存ファイル は中身を削除しません。ファイルを空にしたい場合は truncate -s 0 ファイル名 または > ファイル名 を使います。意図せずファイルの内容を消したくない場合は、touch と混同しないよう注意が必要です。
# 既存ファイルを空にする(中身を削除する)方法
truncate -s 0 /var/log/myapp/app.log
# または
> /var/log/myapp/app.log
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
