conやnulが使えない理由|Windows 11では作れてしまう

マイクロソフト(Microsoft Corporation)

フォルダの名前を「con」にしようとして、Windowsに突き返された経験はないでしょうか。

私がやったのは、コンテンツ置き場を作ろうとして「con」と打ったときでした。素直に「contents」でよかったのに、短くしたい欲が出たんです。返ってきたのは「指定されたデバイス名は無効です」。デバイス名? フォルダを作りたいだけなのに、どこからデバイスの話が出てきたのか…。

この「con」、じつはWindowsが昔から特別扱いしている名前です。仲間には「prn」「aux」「nul」「com1」あたりがいて、どれもMS-DOS時代から続く由緒ある予約語。40年以上も破られなかった聖域でした。

しかもこの手の名前、狙わなくても踏みます。「con」「aux」「prn」はどれも略語として使いたい長さなので、共有フォルダを整理していると普通に候補に上がってくるんです。

この記事では、Windowsで「con」や「nul」が使えない理由をMS-DOS時代までさかのぼって整理し、そのうえでWindows 11では扱いが変わっていることを実際にコマンドで検証した結果まで、まとめて紹介します。

そして今回いちばん面白かったのが、手元のWindows 11で試したら「con」フォルダも「con」ファイルもあっさり作れてしまったこと。あの鉄壁ルール、いつの間にか緩んでいました。

とはいえ全面解禁ではありません。「nul」だけは今も別格だったり、作れたのにPowerShellからは「存在しない」と言われたり、なかなかクセが強い。順番に見ていきます。

そもそも「con」や「nul」は何者なのか

まずは前提の整理から。

Windowsには「予約デバイス名」と呼ばれる名前のグループがあります。ファイル名やフォルダ名に使うと弾かれる、いわば名前の指定席です。

マイクロソフトの公式ドキュメントが挙げているのは、次の名前たちです。

  • CON(コンソール。画面とキーボードのこと)
  • PRN(プリンター)
  • AUX(補助デバイス)
  • NUL(書き込んでも何も起きない、捨て先)
  • COM1〜COM9(シリアルポート)
  • LPT1〜LPT9(パラレルポート。昔のプリンター端子)

大文字でも小文字でも扱いは同じです。「Con」でも「cOn」でも結果は変わりません。

さらに公式ドキュメントには、拡張子を付けてもごまかせないと書かれています。「NUL.txt」も「NUL.tar.gz」もNULと同じ扱いになる、というのが本来のルールでした。

ちょっと笑ったのが上付き文字の扱いです。ドキュメントには「COM¹」「COM²」「COM³」も数字として認識されるので予約名だ、と真顔で書かれています。いったい誰がその名前を付けようとしたんでしょうw

参考:公式ドキュメント

理由はMS-DOSが「機器もファイル」だったから

では、なぜこんな名前が予約されているのか。

答えはMS-DOSの設計思想にあります。当時のDOSは、プリンターや画面といった機器を「特別なファイル」として扱っていました。

だから紙に印刷したいときは、プリンターという名前のファイルに文字を書き込む。そういう発想です。実際、今のコマンドプロンプトでも次のように打つと、画面に文字が出ます。

echo hello > con

ファイルに書き出す構文なのに、出てくるのは画面。CONが「画面という名前のファイル」だからです。

同じ理屈で、PRNに書けば印刷、NULに書けば何も起きずに消える。この仕組みがあったおかげで、DOSはプログラムを書き換えずに出力先を切り替えられました。今のリダイレクトの原型ですね。

そして初期のDOSにはフォルダ(ディレクトリ)の概念すらなく、名前の衝突を避ける必要がありました。デバイス名と同じファイル名を許すと「印刷したつもりがファイルに書かれていた」という事故が起きます。だから最初から立入禁止にした、というわけです。

この名残がWindows 95、XP、7、10と受け継がれ、2020年代まで生き残りました。40年以上前の周辺機器の名前が、いまだにフォルダ名を制限している。互換性というのは、こうやって地層のように積み上がっていくものなんですね。

ところがWindows 11では作れてしまった

ここからが今回の本題です。

実はWindows 11で、この予約名の扱いが静かに変わっています。マイクロソフトの.NET向けドキュメントには、こう書かれています。Windows 11以前は、レガシデバイス名で始まるパスは常にデバイスとして解釈されていた。しかしWindows 11ではそれが当てはまらなくなったので、デバイスを指したいなら完全なパスで書きなさい、と。

つまり「con.txt」のような名前は、もうデバイス扱いされない。ならば本当に作れるのでは…と気になったので、手元のWindows 11(ビルド26200)で片っ端から試してみました。

コマンドプロンプトでフルパスを指定してファイルを作った結果がこちらです。

echo TEST > C:\test\con      → 作れた
echo TEST > C:\test\con.txt  → 作れた
echo TEST > C:\test\aux      → 作れた
echo TEST > C:\test\com1     → 作れた
echo TEST > C:\test\nul      → 作れない

見事に通ってしまいました。フォルダも同じで、md con でも md prn でも作成できます。長年「絶対に無理」と思い込んでいた名前があっさり通るのは、軽く衝撃でした。

そして唯一はじかれ続けたのがNULです。nulだけはファイルもフォルダも作れませんでした。ドキュメントの記述どおり、NULはパスの末尾でも特別扱いが残っているようです。

もうひとつ面白い違いがありました。フルパスではなく、そのフォルダに移動してから echo hello > con と打つと、こちらは今でも画面に出るだけでファイルは作られません。同じ「con」なのに、書き方ひとつで運命が変わるわけです。

参考:公式ドキュメント

作れるけれど、作ると地味に厄介

では喜んで「con」フォルダを量産していいのか。答えはノーです。

作った直後に気づいたのですが、アプリによって見え方が違います。Windows PowerShell(5.1)で同じファイルを確認したら、こうなりました。

Test-Path C:\test\con
→ False(存在しない)

[System.IO.File]::Exists("C:\test\con")
→ True(存在する)

同じファイルなのに、片方は「無い」、片方は「ある」。PowerShellのGet-Contentで開こうとすると「そのパスは存在しません」と怒られるのに、.NETの関数で読むと中身がちゃんと返ってきます。

理由は単純で、OSが許すようになっても、アプリ側の古い判定ロジックがそのまま残っているからです。OSが解禁しても周りのソフトが追いついていなければ、「あるのに読めないファイル」が完成してしまいます。

バックアップソフトや同期ツールがこの名前を嫌う可能性も十分あります。おまけにmacOSやLinux、Gitのリポジトリ、クラウドストレージなど、Windows以外を経由するときも予約名は事故のもと。ZIPを解凍したら1ファイルだけ消えている、みたいな地味に嫌なトラブルにつながります。

おまけ:消せないフォルダはこうして生まれる

ここまで来たら、もうひとつ試したくなりました。

パスの先頭に \?\ を付けると、Windowsは名前のチェックを飛ばして、そのままファイルシステムに渡します。これを使うと、本来禁止のNULすら作れてしまいます。

\?\C:\test\nul
\?\C:\test\hidden.

実際に両方できました。「hidden.」は末尾がピリオドの名前で、これも通常なら作れないものです。

問題はここからです。コマンドプロンプトで普通に削除しようとすると、こう返ってきます。

del C:\test\nul
ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。

作れたのに消せない…。ネットでときどき話題になる「削除できないフォルダ」の正体は、だいたいこれです。悪意なく生まれることもあるので、原因を知っておくと落ち着いて対処できます。

消し方も同じ理屈で、\?\ を付けて指定すれば削除できます。私の環境でも一発で消えました。試すときは一時フォルダで、業務データのある場所ではやらないのが賢明です。

ファイル名で事故らないためのチェックリスト

せっかく調べたので、実用の形に落としておきます。名前を決めるときに見返せる項目です。

  • 予約名(con、prn、aux、nul、com1〜9、lpt1〜9)は、作れる環境でも避ける
  • 使えない記号は9種類。< > : ” / \ | ? *
  • 名前の末尾にスペースやピリオドを付けない(先頭のピリオドはOK)
  • 半角スペースは使わず、ハイフンかアンダースコアでつなぐ
  • 大文字と小文字は区別されないので、大小の違いだけで別ファイルにしない
  • Windows以外に渡す予定があるなら、英数字とハイフンに寄せる

とくに末尾のスペースは厄介です。公式ドキュメントも「決して作成しないでください」と強い口調で書いていて、開けなくなることがあるからだと説明されています。

関連記事:Webサイト制作時に役立つディレクトリ名とファイル名の英語リスト

まとめ

「con」が使えない理由をたどると、MS-DOSがプリンターや画面をファイルとして扱っていた時代に行き着きます。

紙に印刷することが「PRNというファイルに書く」ことだった。だからその名前は最初から予約席になり、40年以上かけてWindowsに受け継がれてきました。フォルダ名を弾かれてイラッとする瞬間の裏に、こんな歴史が埋まっているわけです。

そしてWindows 11では、その扱いが静かに緩みました。手元で試したかぎり、conもprnもauxもcom1も、ファイルでもフォルダでも作れてしまう。ただしnulだけは今も鉄壁で、相対パスで > con と書けば変わらず画面に出力されます。

使えるようになったからといって使っていいわけではない、というのが今回いちばんの結論です。

実際、作った「con」ファイルはPowerShellから「存在しない」と言われました。OSが許してもアプリが追いついていない領域で、バックアップや同期、Mac、Gitをまたいだ瞬間に事故のもとになります。歴史的に「触るな」と言われてきた名前は、やっぱり避けておくのが平和です。

それでも知識として持っておく価値は高いと思っています。原因不明の「ファイルが消える」「開けない」に出くわしたとき、ファイル名を疑えるかどうかで解決までの時間がまるで変わりますから。今回の検証でも、フルパスか相対パスかの違いだけで結果がひっくり返るのを目の前で見て、これは相当ハマる人がいそうだと感じました。

自分の環境の一時フォルダで md con を打ってみると、作れるか弾かれるかでそのWindowsの世代がわかります。ちょっと変わったバージョン判定として、なかなか味わい深い一行ですw