あれMacって大文字と小文字を区別しないのか

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。サービスグループの武田です。

突然ですが次のコマンドを確認してください。シェルはbashで、barディレクトリは存在するものとします。

ln -s "$(PWD)/../etc/foo.conf" bar/foo.conf

私の環境(Mac)だと実行できます。ぱっと見シンボリックリンクを作成しているコマンドですが、皆さんの環境ではどうでしょうか。

環境

次の環境で検証しています。

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.13.6
BuildVersion:	17G65

Unix系OSでのカレントディレクトリの絶対パス取得

さてmacOSなどのUnix系OSでは、カレントディレクトリの絶対パスを取得する方法としてpwdコマンドを使うのが一般的です。

$ pwd
/usr/local/bin

あるいは環境変数からも取得できます。

$ echo $PWD
/usr/local/bin

PWDの謎

それでは最初のコマンドはどちらでしょうか。一見$PWDを使用しているようにも見えますが、よく見てみるとそうでないことに気付きます(以下、再掲)。

ln -s "$(PWD)/../etc/foo.conf" bar/foo.conf

${PWD}なら環境変数なのですが、これは$(PWD)です。つまりPWDコマンドを実行していることになります。はて、そんなコマンドがあるんでしょうか?

$ which pwd
/bin/pwd

$ which PWD
/bin/PWD

$ ls /bin/
[		date		expr		ln		pwd		sync
bash		dd		hostname	ls		rm		tcsh
cat		df		kill		mkdir		rmdir		test
chmod		domainname	ksh		mv		sh		unlink
cp		echo		launchctl	pax		sleep		wait4path
csh		ed		link		ps		stty		zsh

whichコマンドではパスが出ますが、実際に/binを見ても存在しません。というか、いろいろ試していたらPWD以外も動作することに気付きました。

$ LS /BIN/
[		date		expr		ln		pwd		sync
bash		dd		hostname	ls		rm		tcsh
cat		df		kill		mkdir		rmdir		test
chmod		domainname	ksh		mv		sh		unlink
cp		echo		launchctl	pax		sleep		wait4path
csh		ed		link		ps		stty		zsh

うーん、これは……?

大文字と小文字の区別はAPFSのオプション

結論としてMacでは、大文字と小文字の区別は、ディスクフォーマット時に指定するオプションとなっています。macOS High Sierraから、デフォルトファイルシステムはApple File System(APFS)となっています。使用しているPCはAPFSの大文字/小文字区別なしでフォーマットされていました。

これで今回の謎は解けましたね。ちなみに途中で変更するのはおそらく無理で、再フォーマットが必要そうです。

まとめ

知っている人からすると常識なのでしょうが、Macは大文字と小文字を区別すると思い込んでいました。そうではないことが今回わかりましたが、こういう発見があると楽しいですね。