【Linux】touch・mkdirの使い方|ファイル/フォルダ作成・-pで入れ子を一気に作る

【Linux】touch・mkdirの使い方|ファイル/フォルダ作成・-pで入れ子を一気に作る Linux

touchmkdirは、ファイルとディレクトリ(フォルダ)を作るための最も基本的なコマンドです。touch ファイル名で空のファイル、mkdir ディレクトリ名でフォルダを作れます。どちらも単純ですが、実務でよく使う「深い階層のディレクトリを一気に作りたい」「ファイルの日時だけ操作したい」といった場面で、知っておくと便利なオプションがあります。

特にmkdirには、「入れ子になったディレクトリを一度に作ろうとすると、そのままでは失敗する」という、初心者が必ずぶつかる落とし穴があります。この記事では、実機のLinux(WSLのDebian)でこの罠を実際に再現しながら、touchmkdirの基本と、-pをはじめとする便利オプションを整理します。

先に結論

  • touch ファイル名で空ファイルを作成、複数指定も可能です。
  • touchは既存ファイルなら中身を変えずタイムスタンプだけ更新します。
  • mkdir入れ子(a/b/c)をそのままでは作れずエラーになります。
  • mkdir -pで入れ子を一気に作成でき、しかも既存でもエラーになりません
  • touch -tで任意の日時、touch -rで別ファイルの日時をコピーできます。
  • ブレース展開({src,test,docs})と組み合わせると複数を一度に作れます。

作成したファイルのコピー・移動・削除はcp・mv・rm、日時を保ってコピーする話はdu・dfや同記事、権限の設定はchmodもあわせて参考になります。

スポンサーリンク

touchの基本:空ファイル作成とタイムスタンプ更新

touchには2つの顔があります。ファイルが無ければ空ファイルを作り、既にあれば中身を変えずにタイムスタンプ(更新日時)だけを現在時刻に更新します。

touch の基本
# 空ファイルを作成
touch a.txt

# 複数ファイルを一度に作成
touch f1.txt f2.txt f3.txt

# 既存ファイルに touch すると…中身は変えず日時だけ更新
echo "hello" > b.txt      # サイズ 6 バイト
touch b.txt               # サイズは 6 のまま、更新日時だけ「今」になる

実機でも、touch a.txtサイズ0の空ファイルが作られ、touch f1.txt f2.txt f3.txt3つのファイルを一度に作成できました。そしてhello(6バイト)が入ったb.txttouchすると、サイズは6バイトのまま変わらず、更新日時(mtime)だけが現在時刻に変わることを確認しました。この「日時だけ更新する」性質は、Makefileでのビルド制御(ファイルを更新扱いにして再ビルドを促す)や、ログローテーションの目印ファイル作成などで実際に活用されます。

【最重要】mkdirの入れ子の罠と-p

mkdirで最もつまずくのがこれです。mkdir parent/child/grandchildのように、まだ存在しない親ディレクトリを含む深い階層を一度に作ろうとすると、エラーになりますmkdirは既定では「1階層だけ」しか作れないためです。

入れ子は-pが必要
# NG: 親ディレクトリが無いのに孫まで作ろうとする
mkdir parent/child/grandchild
# mkdir: cannot create directory 'parent/child/grandchild': No such file or directory
#   ↑ parent が無いので失敗する

# OK: -p を付けると、途中の階層ごと一気に作成する
mkdir -p parent/child/grandchild
# parent, parent/child, parent/child/grandchild が全部できる
-pなしでは入れ子を作れない(実証)

実機で、存在しないparentを含むmkdir parent/child/grandchildを実行すると、mkdir: cannot create directory ... : No such file or directoryというエラーになりました。「No such file or directory(そんなファイルやディレクトリは無い)」というメッセージは一見分かりにくいですが、「作ろうとしている場所のが存在しない」という意味です。-p(parents)を付けると、途中に無いディレクトリを自動的に補いながら、指定した深さまで一気に作成してくれます。実機でもmkdir -p parent/child/grandchildで3階層すべてが作られました。深いディレクトリ構造を用意するときは、迷わず-pを付けるのが定番です。

-pのもう一つの便利さ:既存でもエラーにならない

-pにはもう一つ重要な性質があります。すでに存在するディレクトリに対して実行してもエラーにならないことです。これは、スクリプトの中で「無ければ作る」という処理を書くときに非常に役立ちます。

既存ディレクトリでの挙動の違い
# -p なし: 既存のディレクトリだとエラー
mkdir parent
# mkdir: cannot create directory 'parent': File exists

# -p あり: 既存でもエラーにならず、静かに成功する
mkdir -p parent
# (何も起きない・エラーも出ない)

# スクリプトでの定番: あってもなくても確実に用意する
mkdir -p /path/to/output    # 出力先を確保してから処理を続ける

実機でも、既存のparentディレクトリにmkdir parent-pなし)を実行するとFile existsエラーになりましたが、mkdir -p parentエラーを出さずに静かに成功しました。シェルスクリプトで「出力先ディレクトリを確保してから処理する」といった場面では、mkdir -pなら、ディレクトリの有無をifで確認する必要すらなく、1行で確実に用意できます。これは-pが実務で多用される大きな理由です。

touchで日時を操作する(-t / -r)

touchは、タイムスタンプを「今」ではなく任意の日時に設定することもできます。-tで日時を直接指定、-rで別ファイルの日時をコピーします。

touch -t と -r
# -t: 任意の日時を設定(形式は [[CC]YY]MMDDhhmm)
touch -t 202001010000 old.txt
# old.txt の日時が 2020-01-01 00:00 になる

# -r: 別ファイルと同じ日時にする(reference)
touch -r old.txt copy_ts.txt
# copy_ts.txt の日時が old.txt と同じ(2020-01-01)になる

実機でも、touch -t 202001010000 old.txtファイルの日時を2020年1月1日に設定でき、touch -r old.txt copy_ts.txtold.txtと同じ日時(2020年)をcopy_ts.txtにコピーできることを確認しました。-tの日時形式は年月日時分を続けて書きます(例: 202001010000)。テスト用に「古い日付のファイル」を用意したいときや、findで更新日を条件にする処理を検証したいときに便利です。

ブレース展開で複数を一度に作る

シェルのブレース展開({...}と組み合わせると、似た名前のディレクトリ・ファイルを一度に作成できます。プロジェクトの初期構造を用意するときなどに効果的です。

ブレース展開との組み合わせ
# プロジェクトの雛形ディレクトリを一気に作る
mkdir -p project/{src,test,docs}
# project/src, project/test, project/docs ができる

# ネストと組み合わせることもできる
mkdir -p app/{src/{main,util},test}
# app/src/main, app/src/util, app/test

# touch でも使える
touch file_{1,2,3}.txt
# file_1.txt, file_2.txt, file_3.txt

実機でも、mkdir -p project/{src,test,docs}srctestdocsの3ディレクトリが一度に作られました。ブレース展開はtouchcp・mvなど多くのコマンドで使えるシェルの機能で、{}の中をカンマで区切ると、それぞれに展開されます。mkdir -pと組み合わせれば、複雑なディレクトリ構造もコマンド1行で構築できます。

主な書き方一覧

touchmkdirの要点をまとめます。

書き方 働き
touch ファイル 空ファイル作成 / 既存なら日時更新
touch -t 日時 ファイル 任意の日時を設定
touch -r 基準 ファイル 別ファイルと同じ日時にする
mkdir ディレクトリ ディレクトリ作成(1階層のみ)
mkdir -p a/b/c 入れ子を一気に / 既存でもエラーなし
mkdir -p dir/{a,b,c} ブレース展開で複数作成

よくある失敗

mkdirで入れ子を作ろうとしてエラーになる

親ディレクトリが無いと失敗します。-pを付けて途中の階層ごと作成します。

既存ディレクトリへのmkdirでエラーが出る

-pを付ければ既存でもエラーになりません。スクリプトでは-pが安全です。

touchしたのに中身が消えたと勘違いする

touchは既存ファイルの中身を変えません。日時だけを更新します。

touch -tの日時形式を間違える

形式は年月日時分を続けて書きます(例: 202001010000)。

ブレース展開で余分なスペースを入れる

{src, test}のように,の後にスペースを入れると意図どおり展開されません。{src,test}と詰めて書きます。

よくある質問

Qtouchは何に使うコマンドですか?
A空のファイルを作成するのが主な用途ですが、既存のファイルに対して実行すると、中身を変えずにタイムスタンプ(更新日時)だけを現在時刻に更新します。実機でも、6バイトのファイルにtouchしてもサイズは変わらず日時だけ更新されることを確認しています。ビルド制御や目印ファイルの作成にも使われます。
Qmkdirで深い階層のフォルダを一度に作れませんか?
Amkdir -pを使います。mkdir a/b/cのように親(a)が存在しない状態で入れ子を作ろうとすると、実機でも「No such file or directory」エラーになります。mkdir -p a/b/cとすれば、途中の階層を補いながら一気に作成できます。
Qmkdir -pは既存のディレクトリに使っても大丈夫ですか?
Aはい。-pを付けると、すでに存在するディレクトリに対して実行してもエラーになりません。実機でも、-pなしでは「File exists」エラーになるところが、-pありでは静かに成功することを確認しています。スクリプトで「無ければ作る」処理を書くときに、有無を確認せず1行で済むため便利です。
Qファイルの日時を過去の日付に設定できますか?
Atouch -tで任意の日時を設定できます。形式はtouch -t 202001010000 ファイル名のように、年月日時分を続けて書きます。またtouch -r 基準ファイル 対象ファイルとすれば、基準ファイルと同じ日時をコピーできます。実機でも、2020年の日時設定とコピーが正しく動くことを確認しています。
Q複数のディレクトリを一度に作るには?
Aシェルのブレース展開を使い、mkdir -p project/{src,test,docs}のように書くと、src・test・docsを一度に作れます。{}の中をカンマで区切り、スペースは入れないのがポイントです。ネストさせることもでき、プロジェクトの雛形作成に便利です。

まとめ

  • touchは空ファイル作成、既存なら中身を変えず日時だけ更新します。
  • mkdir入れ子をそのままでは作れず-pが必要です。
  • mkdir -pは既存でもエラーにならないため、スクリプトで安全に使えます。
  • touch -t/-rで日時を自在に操作できます。
  • ブレース展開{a,b,c}で複数を一度に作成できます。

touchmkdirは、Linuxを触れば毎日のように使う基本コマンドです。「入れ子にはmkdir -p」という一点さえ押さえれば、ファイルとディレクトリの準備でつまずくことはなくなります。作ったファイルはcp・mv・rmで操作し、chmodで権限を整えていきましょう。