touchとmkdirは、ファイルとディレクトリ(フォルダ)を作るための最も基本的なコマンドです。touch ファイル名で空のファイル、mkdir ディレクトリ名でフォルダを作れます。どちらも単純ですが、実務でよく使う「深い階層のディレクトリを一気に作りたい」「ファイルの日時だけ操作したい」といった場面で、知っておくと便利なオプションがあります。
特にmkdirには、「入れ子になったディレクトリを一度に作ろうとすると、そのままでは失敗する」という、初心者が必ずぶつかる落とし穴があります。この記事では、実機のLinux(WSLのDebian)でこの罠を実際に再現しながら、touch・mkdirの基本と、-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 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.txtで3つのファイルを一度に作成できました。そしてhello(6バイト)が入ったb.txtにtouchすると、サイズは6バイトのまま変わらず、更新日時(mtime)だけが現在時刻に変わることを確認しました。この「日時だけ更新する」性質は、Makefileでのビルド制御(ファイルを更新扱いにして再ビルドを促す)や、ログローテーションの目印ファイル作成などで実際に活用されます。
【最重要】mkdirの入れ子の罠と-p
mkdirで最もつまずくのがこれです。mkdir parent/child/grandchildのように、まだ存在しない親ディレクトリを含む深い階層を一度に作ろうとすると、エラーになります。mkdirは既定では「1階層だけ」しか作れないためです。
# 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 が全部できる
実機で、存在しない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で別ファイルの日時をコピーします。
# -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.txtでold.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}でsrc・test・docsの3ディレクトリが一度に作られました。ブレース展開はtouchやcp・mvなど多くのコマンドで使えるシェルの機能で、{}の中をカンマで区切ると、それぞれに展開されます。mkdir -pと組み合わせれば、複雑なディレクトリ構造もコマンド1行で構築できます。
主な書き方一覧
touch・mkdirの要点をまとめます。
| 書き方 | 働き |
|---|---|
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}と詰めて書きます。
よくある質問
mkdir -pを使います。mkdir a/b/cのように親(a)が存在しない状態で入れ子を作ろうとすると、実機でも「No such file or directory」エラーになります。mkdir -p a/b/cとすれば、途中の階層を補いながら一気に作成できます。-pを付けると、すでに存在するディレクトリに対して実行してもエラーになりません。実機でも、-pなしでは「File exists」エラーになるところが、-pありでは静かに成功することを確認しています。スクリプトで「無ければ作る」処理を書くときに、有無を確認せず1行で済むため便利です。touch -tで任意の日時を設定できます。形式はtouch -t 202001010000 ファイル名のように、年月日時分を続けて書きます。またtouch -r 基準ファイル 対象ファイルとすれば、基準ファイルと同じ日時をコピーできます。実機でも、2020年の日時設定とコピーが正しく動くことを確認しています。mkdir -p project/{src,test,docs}のように書くと、src・test・docsを一度に作れます。{}の中をカンマで区切り、スペースは入れないのがポイントです。ネストさせることもでき、プロジェクトの雛形作成に便利です。まとめ
touchは空ファイル作成、既存なら中身を変えず日時だけ更新します。mkdirは入れ子をそのままでは作れず、-pが必要です。mkdir -pは既存でもエラーにならないため、スクリプトで安全に使えます。touch -t/-rで日時を自在に操作できます。- ブレース展開
{a,b,c}で複数を一度に作成できます。
touchとmkdirは、Linuxを触れば毎日のように使う基本コマンドです。「入れ子にはmkdir -p」という一点さえ押さえれば、ファイルとディレクトリの準備でつまずくことはなくなります。作ったファイルはcp・mv・rmで操作し、chmodで権限を整えていきましょう。
- grep(文字列検索)
- find(ファイル検索)
- sed(置換・行編集)
- awk(列抽出・集計)
- cut(列の切り出し)
- chmod(パーミッション)
- tar(圧縮・解凍)
- リダイレクトとパイプ
- ps・kill(プロセス管理)
- 環境変数とPATH
- ln(シンボリックリンク)
- cp・mv・rm(コピー/移動/削除)
- touch・mkdir(ファイル/フォルダ作成)
- history(コマンド履歴)
- curl(HTTP通信・API)
- jq(JSON処理)
- vim(基本操作・終了方法)
- cron・crontab(定期実行)
- sort・uniq・wc(並べ替え/集計)
- xargs(一括処理)
- chown・chgrp(所有者/グループ変更)
- diff(ファイル比較)
- du・df(ディスク使用量)
- head・tail(先頭/末尾・ログ監視)
- cat・less(ファイル表示)
- alias(コマンドの別名)
- nohup(SSH切断対策)
- tmux(セッション管理)
- よく使うコマンドまとめ
- cd(ディレクトリ移動)

