Linuxでファイルパスからディレクトリ部分だけを取り出したいときは、dirnameコマンドを使用します。
たとえば、/home/user/logs/app.logというパスから、ファイル名のapp.logを除いた/home/user/logsだけを取り出したい場面があります。
このようなときに便利なのがdirnameコマンドです。
dirnameは、実際にディレクトリを作成したり移動したりするコマンドではありません。指定したパス文字列から、末尾のファイル名やディレクトリ名を除いた部分を表示するコマンドです。
シェルスクリプトでファイルの保存先ディレクトリを取得したいとき、バックアップ先を作りたいとき、ログファイルの親ディレクトリを確認したいときなどによく使われます。
この記事では、Linux初心者でも理解できるように、dirnameコマンドの基本構文、basenameとの違い、相対パス・絶対パスでの使い方、シェルスクリプトでの活用例、よくある注意点まで実例付きで解説します。
- dirnameコマンドとは
- dirnameコマンドの基本構文
- パスからディレクトリ部分を取り出す方法
- 相対パスでも使用できる
- ファイル名だけを指定した場合
- ルート直下のファイルを指定した場合
- 末尾にスラッシュがある場合
- basenameコマンドとの違い
- ファイルが存在しなくても処理できる
- 複数のパスをまとめて処理する方法
- dirnameコマンドの主なオプション
- -zオプションでNUL区切りにする方法
- シェルスクリプトでdirnameを使う方法
- スペースを含むパスを処理する方法
- 親ディレクトリを作成してからファイルを保存する例
- バックアップ先ディレクトリを取得する例
- スクリプト自身の場所を取得する例
- findコマンドと組み合わせる方法
- 重複したディレクトリをまとめる例
- dirname・basename・realpathの違い
- dirnameコマンドでよくある注意点
- dirnameコマンドでよくあるエラー
- よくある質問
- まとめ
dirnameコマンドとは
dirnameは、指定したパスからディレクトリ部分を取り出すLinuxコマンドです。
たとえば、次のようなパスがあるとします。
/home/user/document/report.txt
dirnameを使うと、末尾のreport.txtを除いたディレクトリ部分だけを取得できます。
dirname /home/user/document/report.txt
実行結果です。
/home/user/document
ファイル名を取り出すbasenameとは反対に、dirnameはディレクトリ部分を取り出すコマンドです。
dirnameコマンドの基本構文
dirnameコマンドの基本構文は次のとおりです。
dirname パス
複数のパスを指定することもできます。
dirname パス1 パス2 パス3
指定したパスごとに、ディレクトリ部分が表示されます。
パスからディレクトリ部分を取り出す方法
最も基本的な使い方は、ファイルパスからディレクトリ部分を取り出す方法です。
dirname /home/user/document/report.txt
実行結果です。
/home/user/document
末尾のreport.txtが取り除かれ、親ディレクトリのパスだけが表示されます。
相対パスでも使用できる
dirnameは、絶対パスだけでなく相対パスにも使用できます。
dirname ./logs/app.log
実行結果です。
./logs
現在のディレクトリを基準にしたパスでも、ファイル名を除いた部分を取得できます。
ファイル名だけを指定した場合
ディレクトリ部分を含まないファイル名だけを指定した場合、dirnameは.を返します。
dirname sample.txt
実行結果です。
.
.は現在のディレクトリを意味します。
つまり、sample.txtは現在のディレクトリにあるファイルとして扱われるため、ディレクトリ部分は.になります。
ルート直下のファイルを指定した場合
ルートディレクトリ直下のファイルを指定した場合は、/が返ります。
dirname /sample.txt
実行結果です。
/
これは、/sample.txtの親ディレクトリがルートディレクトリ/だからです。
末尾にスラッシュがある場合
末尾にスラッシュがあるパスを指定した場合、最後の要素を取り除いたディレクトリ部分が表示されます。
dirname /home/user/project/
実行結果です。
/home/user
/home/user/project/の末尾要素はprojectとして扱われるため、その親ディレクトリである/home/userが表示されます。
basenameコマンドとの違い
dirnameとよく一緒に使われるのがbasenameコマンドです。
この2つは、どちらもパス文字列を分解するためのコマンドですが、取り出す部分が異なります。
| コマンド | 取り出す部分 | 例 |
|---|---|---|
basename |
末尾のファイル名・ディレクトリ名 | report.txt |
dirname |
末尾を除いたディレクトリ部分 | /home/user/document |
次のパスで確認します。
/home/user/document/report.txt
basenameを実行します。
basename /home/user/document/report.txt
実行結果です。
report.txt
dirnameを実行します。
dirname /home/user/document/report.txt
実行結果です。
/home/user/document
ファイル名だけが欲しい場合はbasename、保存されているディレクトリ部分が欲しい場合はdirnameを使用します。
ファイルが存在しなくても処理できる
dirnameは、実際にファイルやディレクトリが存在するかどうかを確認しません。
dirname /not/exist/path/sample.txt
実行結果です。
/not/exist/path
存在しないパスであっても、文字列として処理されます。
ファイルやディレクトリの存在確認をしたい場合は、testコマンドや[ -e パス ]を使います。
if [ -e /not/exist/path/sample.txt ]; then
echo "存在します"
else
echo "存在しません"
fi
複数のパスをまとめて処理する方法
dirnameは、複数のパスを一度に処理できます。
dirname /home/user/a.txt /var/log/app.log /tmp/test/file.dat
実行結果です。
/home/user
/var/log
/tmp/test
それぞれのパスから、ディレクトリ部分だけが表示されます。
dirnameコマンドの主なオプション
| オプション | 説明 |
|---|---|
-z |
出力の区切りを改行ではなくNUL文字にする |
--help |
ヘルプを表示する |
--version |
バージョン情報を表示する |
dirnameは比較的シンプルなコマンドなので、よく使うオプションは多くありません。
-zオプションでNUL区切りにする方法
-zオプションを使用すると、出力の区切りが改行ではなくNUL文字になります。
dirname -z /home/user/a.txt /home/user/b.txt
通常の画面表示では分かりにくいですが、ファイル名に改行などの特殊文字が含まれる可能性がある場合に、安全な処理へつなげやすくなります。
一般的な手作業ではあまり使いませんが、シェルスクリプトで堅牢に処理したい場合に使われます。
シェルスクリプトでdirnameを使う方法
dirnameは、シェルスクリプト内で親ディレクトリを取得したいときによく使います。
たとえば、ファイルパスからディレクトリ部分だけを変数へ入れる例です。
path="/var/log/app/app.log"
dir=$(dirname "$path")
echo "$dir"
実行結果です。
/var/log/app
変数を扱う場合は、パスをダブルクォートで囲むのが基本です。
スペースを含むパスを処理する方法
ファイル名やディレクトリ名にスペースが含まれている場合は、必ずクォートします。
dirname "/home/user/My Documents/report.txt"
実行結果です。
/home/user/My Documents
変数に入っている場合も同様です。
path="/home/user/My Documents/report.txt"
dirname "$path"
クォートを忘れると、スペースで別々の引数として扱われ、意図しない結果になる可能性があります。
親ディレクトリを作成してからファイルを保存する例
dirnameは、ファイル保存前に親ディレクトリを作成する処理でよく使われます。
output="/tmp/report/2026/result.txt"
dir=$(dirname "$output")
mkdir -p "$dir"
echo "結果を保存します" > "$output"
この例では、まず/tmp/report/2026を作成し、その後にresult.txtへ書き込みます。
シェルスクリプトで出力先ディレクトリが存在しない場合に便利です。
バックアップ先ディレクトリを取得する例
バックアップ処理でもdirnameは便利です。
src="/etc/nginx/nginx.conf"
dir=$(dirname "$src")
echo "$dir"
実行結果です。
/etc/nginx
元ファイルが存在するディレクトリを取得して、同じ場所にバックアップファイルを作ることもできます。
src="/etc/nginx/nginx.conf"
dir=$(dirname "$src")
base=$(basename "$src")
cp "$src" "$dir/${base}.bak"
この例では、/etc/nginx/nginx.conf.bakを作成します。
スクリプト自身の場所を取得する例
シェルスクリプトでは、自分自身が置かれているディレクトリを取得したいことがあります。
script_dir=$(dirname "$0")
echo "$script_dir"
ただし、$0は実行方法によって相対パスになることがあります。
絶対パスとして扱いたい場合は、cdやpwdと組み合わせる方法が使われます。
script_dir=$(cd "$(dirname "$0")" && pwd)
echo "$script_dir"
より厳密なパス解決が必要な場合は、realpathコマンドの利用も検討します。
findコマンドと組み合わせる方法
findコマンドで見つけたファイルから、親ディレクトリだけを取り出すこともできます。
find /var/log -name "*.log" -type f
この結果をwhile文で処理します。
find /var/log -name "*.log" -type f | while read path; do
dirname "$path"
done
ファイル名にスペースや特殊文字が含まれる可能性がある場合は、-print0とread -d ''を使う方法が安全です。
find /var/log -name "*.log" -type f -print0 | while IFS= read -r -d '' path; do
dirname "$path"
done
重複したディレクトリをまとめる例
複数ファイルの親ディレクトリを取得すると、同じディレクトリが重複して表示されることがあります。
find /var/log -name "*.log" -type f | while read path; do
dirname "$path"
done | sort | uniq
sortとuniqを組み合わせると、重複を取り除いて一覧化できます。
dirname・basename・realpathの違い
パス操作でよく使うコマンドには、dirname、basename、realpathがあります。
| コマンド | 役割 | 例 |
|---|---|---|
dirname |
パスのディレクトリ部分を取り出す | /home/user/document |
basename |
パス末尾のファイル名を取り出す | report.txt |
realpath |
相対パスを絶対パスへ変換する | /home/user/document/report.txt |
親ディレクトリを取り出したい場合はdirname、ファイル名だけを取り出したい場合はbasename、正規化された絶対パスが欲しい場合はrealpathを使います。
dirnameコマンドでよくある注意点
実際のディレクトリ存在確認はしない
dirnameは、パス文字列を処理するだけです。
存在しないパスを指定しても、文字列としてディレクトリ部分を表示します。
dirname /not/exist/sample.txt
実行結果です。
/not/exist
実際に存在するか確認したい場合は、次のようにします。
dir=$(dirname "/not/exist/sample.txt")
if [ -d "$dir" ]; then
echo "ディレクトリは存在します"
else
echo "ディレクトリは存在しません"
fi
ファイル名だけを指定するとドットが返る
ファイル名だけを指定した場合は、現在のディレクトリを意味する.が返ります。
dirname sample.txt
実行結果です。
.
エラーではなく、正常な動作です。
変数は必ずクォートする
シェルスクリプトで変数を使う場合は、次のようにダブルクォートで囲みます。
dirname "$path"
スペースや記号を含むパスで問題が起きるのを防げます。
dirnameコマンドでよくあるエラー
missing operand
dirname: missing operand
引数を指定せずに実行した場合に表示されます。
対象のパスを指定して実行してください。
dirname /home/user/sample.txt
意図したパスと違う結果になる
末尾にスラッシュがある場合や、相対パスを指定している場合、想定と異なるように見える結果になることがあります。
dirname ./sample.txt
実行結果です。
.
./sample.txtは現在のディレクトリにあるファイルを意味するため、ディレクトリ部分は.になります。
スペースを含むパスで分割される
変数をクォートしていない場合、スペースでパスが分割されます。
path="/home/user/My Documents/report.txt"
dirname $path
安全に処理するには、必ず次のように書きます。
dirname "$path"
よくある質問
dirnameコマンドは何に使いますか?
ファイルパスからディレクトリ部分だけを取り出すために使います。シェルスクリプトで親ディレクトリを取得したいときによく利用されます。
dirnameはファイルが存在しなくても使えますか?
はい。dirnameはパス文字列を処理するコマンドなので、指定したファイルやディレクトリが存在しなくても結果を表示できます。
ファイル名だけを指定するとどうなりますか?
現在のディレクトリを意味する.が表示されます。
dirname sample.txt
basenameとの違いは何ですか?
basenameはパス末尾のファイル名やディレクトリ名を取り出します。dirnameは、その末尾を除いたディレクトリ部分を取り出します。
複数のパスをまとめて処理できますか?
はい。複数のパスを指定すると、それぞれのディレクトリ部分が表示されます。
dirname /tmp/a.txt /var/log/app.log
スペースを含むパスではどうすればよいですか?
パスや変数をダブルクォートで囲みます。
dirname "$path"
dirnameで絶対パスに変換できますか?
いいえ。dirnameは指定されたパス文字列からディレクトリ部分を取り出すだけです。絶対パスへ変換したい場合はrealpathを使用します。
UbuntuやCentOS Streamでも使えますか?
はい。Ubuntu、Debian、CentOS Stream、Rocky Linux、AlmaLinuxなど、一般的なLinuxディストリビューションで利用できます。
まとめ
dirnameコマンドは、Linuxでパスからディレクトリ部分だけを取り出すためのコマンドです。
基本的な使い方は次のとおりです。
dirname /home/user/sample.txt
実行結果です。
/home/user
ファイル名だけを指定した場合は、現在のディレクトリを意味する.が表示されます。
dirname sample.txt
実行結果です。
.
basenameはファイル名部分を取り出し、dirnameはディレクトリ部分を取り出します。
basename /home/user/sample.txt
dirname /home/user/sample.txt
シェルスクリプトでは、親ディレクトリを作成してからファイルへ書き込む処理や、バックアップファイルを作成する処理でよく使われます。
output="/tmp/report/result.txt"
dir=$(dirname "$output")
mkdir -p "$dir"
echo "保存します" > "$output"
dirnameはファイルやディレクトリを直接操作するのではなく、パス文字列を処理するコマンドです。
basenameやrealpathとあわせて覚えておくと、Linuxでのパス操作やシェルスクリプト作成がかなり楽になります。




コメント