概要
指定されたファイルパス(文字列)から、末尾のファイル名を取り除き、ディレクトリ部分(親パス)だけを表示するコマンドです。
basename コマンドの対となる存在で、主にシェルスクリプトにおいて「対象ファイルが置かれているディレクトリに移動したい」場合や、「スクリプト自身の格納場所」を特定する際に不可欠なツールです。
仕様(引数・オプション)
構文
dirname 文字列
dirname [オプション]... 文字列...
主な引数・オプション
dirname には複雑なオプションはほとんどありません。
| オプション | 説明 |
-z | 出力の区切り文字を改行ではなくヌル文字(\0)にします(zero)。 |
--help | ヘルプを表示します。 |
基本の使い方
ファイルパスを引数として渡すと、そのファイルが含まれるディレクトリのパスを返します。
コマンド
# パスからディレクトリ部分を抽出
dirname /var/www/html/index.php
実行結果
/var/www/html
実践コマンド
コマンドの実体があるディレクトリを表示する
which コマンドと組み合わせることで、特定のコマンドがインストールされているディレクトリパスのみを取得します。
# lsコマンドが格納されているディレクトリを表示
dirname $(which ls)
/usr/bin
シェルスクリプト内で対象ファイルの場所に移動する
変数に入っているファイルパスからディレクトリ部分を取り出し、そこへ cd で移動します。ログファイルの処理などでよく使われる手法です。
#!/bin/bash
LOG_FILE="/var/log/apache2/access.log"
# ログファイルがあるディレクトリへ移動
cd "$(dirname "$LOG_FILE")"
# 移動できたか確認
pwd
/var/log/apache2
複数のパスを一括処理する
引数に複数のパスを指定すると、それぞれに対してディレクトリ名を返します。
dirname /usr/bin/python3 /etc/nginx/nginx.conf
/usr/bin
/etc/nginx
カスタムポイント
- 相対パスの扱い: 引数が
script.shのようにパスを含まない場合、カレントディレクトリを表す.を返します。 - ルートディレクトリ: 引数が
/の場合、結果も/となります。 - basenameとの併用: ファイル名だけが欲しいときは
basename、場所が欲しいときはdirnameと使い分けます。
注意点
- 文字列操作のみ:basename と同様、指定されたパスが実際に存在するかどうかはチェックしません。単に文字列として「最後のスラッシュより前」を切り出しています。
- 末尾のスラッシュ:dirname /var/www/ のように末尾にスラッシュがある場合、それはファイル名(ディレクトリ名)の一部とみなされ、その一つ上の階層(/var)が返されます。
- コマンド置換の必須性:スクリプト内で cd dirname $VAR と書いても動作しません。cd “$(dirname “$VAR”)” のように、必ずコマンド置換 $() で囲む必要があります。
応用
スクリプト自身のディレクトリを取得して移動する(鉄板テクニック)
シェルスクリプトがどこから実行されても、必ず「スクリプトファイルがある場所」を起点に処理を行えるようにする、最も重要なイディオムです。
#!/bin/bash
# このスクリプトが置かれているディレクトリの絶対パスを取得
SCRIPT_DIR=$(cd $(dirname "$0") && pwd)
echo "スクリプトの場所: $SCRIPT_DIR"
# 外部の設定ファイルを読み込む際などに安全に使用できる
# source "$SCRIPT_DIR/config.env"
まとめ
dirnameコマンドは、単体で使うことよりも、シェルスクリプト内のパス操作(特に cd との組み合わせ)で真価を発揮します。手動操作ではあまり使いませんが、自動化スクリプトを書く際には「ファイルの場所を特定して移動する」という動作が頻出するため、basename、readlink と並んでパス操作の三種の神器として覚えておくべきコマンドです。
