mkdir を効率良く使う

Cygwin PC-UNIX コード ハウツー 設定

[小ネタ]mkdir を効率良く使う

mkdirディレクトリ(フォルダ)作成コマンドです。Linux などの PC UNIX ユーザーには当たり前のコマンドですが、単体で使ってもあまり面白みのないコマンドです。
そこで、主に bash ユーザー限定にはなりますが、スクリプトと組み合わせて使う方法を復習してみます。
また、ディレクトリ確認のために tree コマンドもインストールしておくといいと思います(多くのシステムでは標準でインストールされます)。

参考までに、FreeBSD だと pkg install sysutils/tree で速攻インストールできます。今回のキモではないので、別にインストールしなくても問題はありません。

mkdir は -p オプションがキモ

早速、万人におすすめする結論ですが、mkdir コマンドを打つときは -p オプション込みで使うことを癖つけておくと、あまり面倒に巻き込まれないと思います。あくまで個人の経験則です。

ディレクトリが存在したら、mkdir しない

存在するディレクトリを作成しようとすると、よくエラーになります。

 bash
# ls
_test Gruntfile.js

すでに、_test というファイルもしくはディレクトリが存在するところに、_test というディレクトリを作成しようとすると

 bash
# mkdir _test
mkdir: _test: File exists

とエラーになります。
そんなときは、test コマンドと組み合わせて、

 bash
[ ! -d _test ] && mkdir _test

とやるのは、ほぼほぼ定石という感じでしょうか。スクリプトで不要な出力を避ける場合などは使うことがあります。
ただ、コマンドプロンプトやターミナルにタイプするときは面倒に感じるので、

 bash
# mkdir -p _test

と「-p」オプションを付けてやると、_test があろうがなかろうが、エラーは吐きません
_test_ があれば、何もしない、_test が無ければそのディレクトリを作成するという感じです。

サブディレクトリまでまとめて作成する

親ディレクトリとサブディレクトリを同時に作成する方法は簡単です。

 bash
# mkdir -p tmp/_test
# tree -d
|
-- tmp
    -- _test

つまり、tmp ディレクトリ下に _test ディレクトリができました

mkdir して作ったばかりのディレクトリに同時に移動したい

 bash
# cd 目的のディレクトリ

で目的のディレクトリに移動できますが、よくあるのが例えば tmp ディレクトリを速攻作成して、その中で素早くテスト作業したいというケースです。

普通に

 bash
# mkdir tmp
# cd tmp

とやるだけですが、 あまりスマートではありません。

この場合は

 bash
# mkdir tmp && cd $_

cd $_ をあとに付けてやると上の作業がまとまります。

ただ、 bash がこの場合はスペースをセパレーターとして解釈するケースがあるので、ディレクトリ名にスペース等を含む場合を考慮して、

 bash
# mkdir tmp && cd "$_"

cd "$_" という形にしておくのが無難です。スクリプトを記述するときは、スペースを含もうがそうでなくても、ダブルクォートしておきましょう。

おまけとして次の方法もあります。

 bash
# mkdir tmp
# cd !!$

一行ではやれませんが、「"$_"」ではなく引用符なしの「!!$」でやります。

!!$ は直前のコマンドの引数のことです。変数というより、コマンドの引数のみを取り出すということですので、引用符無しで動きます。

 bash
# mkdir "sapmle space"
# cd !!$

というようなスペース入のディレクトリでも大丈夫です。

複数のディレクトリを一気に作成する

個人的にはよく使う方法です。
シェルは bash です。
例のように、作成するつもりのディレクトリ名を「{」「}」で囲い「,」で区切って指定します。

 bash
# mkdir {images,js,css}

とやれば、現在のディレクトリ下に、images と js と css というディレクトリが作成されます。

 bash
# mkdir -p assets/{images,js,css}

とやれば、

現在のディレクトリにまず、assets ディレクトリが作成され、その assets ディレクトリ以下に、images と js と css というディレクトリが作成されます。

 bash
# mkdir -p {assets1,assets2}/{images,js,css}

とやれば、
現在のディレクトリにまず、assets1 と assets2 という2つのディレクトリが作成され、それぞれのディレクトリ以下に、images と js と css というディレクトリが作成されます。

 bash
# mkdir -p assets/{images,js,css} img/{jpg,png,tif}

とスペースを挟んで複数指定すれば、
現在のディレクトリにまず、assets と img ディレクトリが作成され、assets ディレクトリ以下には、images と js と css というディレクトリが作成され、img ディレクトリ以下には、jpg と png と tif ディレクトリが作成されます。

ディレクトリ作成が成功したかどうか表示してコマンド実行する

"-p" オプションは、ディレクトリが(すでに目的のディレクトリが存在するために)作成できなくても何の表示もしないので不安だという場合、"-v" オプションと併用します。
"-v" オプションは mkdir コマンドで、ディレクトリ作成がうまく行った場合のみ、作成したディレクトリを表示します

 bash
# mkdir -p -v tmp/sub/sub2
tmp
tmp/sub
tmp/sub/sub2

パーミッションを指定しディレクトリを作成する

ディレクトリ作成時に気になるのがパーミッション設定です。
最近の多くのシステムでは、何も設定しなくても普通にディレクトリ作成するだけで、そのサーバーに適したパーミッションが設定されるようにはなっています。
それでも、自分でパーミッションを設定してディレクトリ作成したい場合は

 bash
# mkdir -m 666 assets

これで、全ユーザに実行許可なし読み書き許可(パーミッション 666)の assets ディレクトリが作成されます。

mオプションの落とし穴

"-m" オプションはちょっとしたときは便利ですが、私個人として無オプションではディレクトリをとりあえず作成して、あとから chmod でパーミッションを指定するほうが、大きな間違いを犯さないと感じます。

 bash
# mkdir -pvm 700 tmp/sub/sub2

とやると、パーミッション 700 の sub2 ディレクトリを作成します。ちなみに"-pvm""-p -v -m"とやっても同じです。
ポイントは、パーミッション 700 になるのは新しく作成された sub2 だけです。
パーミッション設定が有効になるのは、複層のディレクトリの場合は、最下層の新しく作成されたディレクトリに限定されることを心得ておきましょう。

すでに他のパーミッションで作成された sub2 がある場合は、パーミッションは書き換えられません。
また、現在のディレクトリに tmp や tmp/sub ディレクトリがない場合、それぞれのディレクトリはデフォルトのパーミッションで作成されます。
つまり、パーミッション 700 で作成されるわけではないということです。

そのため、パーミッションの設定は確認も含めて、自分であとから chmod コマンドで確認しながら設定するほうが、設定ミスは防げると考えています。

mkdir したディレクトリのパーミッションを、効率よく変更する

find コマンドを使うのが簡単です。

まず、複層のディレクトリを作成します。
ここでは、所有者のみ読み書き可能なパーミッション600 のディレクトリ、img、images、js、css を作成します。

 bash
# mkdir -p -m 600 assets/{img,images,js,css}

ここで、img ディレクトリだけを誰でも読み書き可能なパーミッション666に設定し直します。

 bash
# find ./ -type d -name "img" -exec chmod 600 {} \;

数字がよくわからない場合は、

 bash
# find ./ -type d -name img -exec chmod og+rw {} \;

とやっても大丈夫です。

RECOMMEND

-Cygwin, PC-UNIX, コード, ハウツー, 設定
-, , ,