あれMacって大文字と小文字を区別しないのか
こんにちは。サービスグループの武田です。
突然ですが次のコマンドを確認してください。シェルはbashで、barディレクトリは存在するものとします。
1 | ln -s "$(PWD)/../etc/foo.conf" bar/foo.conf |
私の環境(Mac)だと実行できます。ぱっと見シンボリックリンクを作成しているコマンドですが、皆さんの環境ではどうでしょうか。
環境
次の環境で検証しています。
1 2 3 4 | $ sw_versProductName: Mac OS XProductVersion: 10.13.6BuildVersion: 17G65 |
Unix系OSでのカレントディレクトリの絶対パス取得
さてmacOSなどのUnix系OSでは、カレントディレクトリの絶対パスを取得する方法としてpwdコマンドを使うのが一般的です。
1 2 | $ pwd/usr/local/bin |
あるいは環境変数からも取得できます。
1 2 | $ echo $PWD/usr/local/bin |
PWDの謎
それでは最初のコマンドはどちらでしょうか。一見$PWDを使用しているようにも見えますが、よく見てみるとそうでないことに気付きます(以下、再掲)。
1 | ln -s "$(PWD)/../etc/foo.conf" bar/foo.conf |
${PWD}なら環境変数なのですが、これは$(PWD)です。つまりPWDコマンドを実行していることになります。はて、そんなコマンドがあるんでしょうか?
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ which pwd/bin/pwd$ which PWD/bin/PWD$ ls /bin/[ date expr ln pwd syncbash dd hostname ls rm tcshcat df kill mkdir rmdir testchmod domainname ksh mv sh unlinkcp echo launchctl pax sleep wait4pathcsh ed link ps stty zsh |
whichコマンドではパスが出ますが、実際に/binを見ても存在しません。というか、いろいろ試していたらPWD以外も動作することに気付きました。
1 2 3 4 5 6 7 | $ LS /BIN/[ date expr ln pwd syncbash dd hostname ls rm tcshcat df kill mkdir rmdir testchmod domainname ksh mv sh unlinkcp echo launchctl pax sleep wait4pathcsh ed link ps stty zsh |
うーん、これは……?
大文字と小文字の区別はAPFSのオプション
結論としてMacでは、大文字と小文字の区別は、ディスクフォーマット時に指定するオプションとなっています。macOS High Sierraから、デフォルトファイルシステムはApple File System(APFS)となっています。使用しているPCはAPFSの大文字/小文字区別なしでフォーマットされていました。
これで今回の謎は解けましたね。ちなみに途中で変更するのはおそらく無理で、再フォーマットが必要そうです。
まとめ
知っている人からすると常識なのでしょうが、Macは大文字と小文字を区別すると思い込んでいました。そうではないことが今回わかりましたが、こういう発見があると楽しいですね。