linux-labs

Вики / Базовые команды

Пути — basename, dirname, realpath

Команда GNU coreutils БазовоеФайлы

Разобрать путь на имя и каталог, получить абсолютный путь; устойчивый каталог скрипта.

Утилиты для работы с путями как со строками — незаменимы в скриптах:

  • basename — имя файла без каталога (и, опц., без расширения).
  • dirname — каталог без имени файла.
  • realpath — абсолютный путь после раскрытия ., .. и симлинков.
basename /var/log/syslog          # syslog
basename /var/log/app.log .log    # app           (убрать суффикс)
dirname  /var/log/syslog          # /var/log
realpath ../../etc/nginx          # /etc/nginx    (абсолютный, без ../)
realpath -m /nope/x               # посчитать путь, даже если его нет (-m)

Классика — узнать каталог самого скрипта, чтобы пути не зависели от того, откуда его запустили:

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"     # переносимо
# или короче через realpath:
SCRIPT_DIR="$(dirname "$(realpath "$0")")"

Разобрать путь на части:

path=/srv/www/site/index.html
dir=$(dirname  "$path")           # /srv/www/site
base=$(basename "$path")          # index.html
name=$(basename "$path" .html)    # index

В чистом bash то же дают подстановки: ${path##*/} (basename) и ${path%/*} (dirname) — без вызова внешней программы. См. bash-scripting.

Путь с пробелами «разъехался»

Всегда в кавычках: dirname "$path". Без кавычек пробел разобьёт аргументы.

realpath: No such file or directory

По умолчанию realpath требует существования пути. Для несуществующих — -m (посчитать чисто строкой) или -e (наоборот, требовать существования всех частей).

Нужен путь без раскрытия симлинков

realpath идёт по симлинкам. Чтобы оставить как есть — realpath -s (или readlink для самой ссылки, см. ln).

basename /a/b/c.txt          # c.txt
basename /a/b/c.txt .txt     # c
dirname  /a/b/c.txt          # /a/b
realpath ../x                # абсолютный путь
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"   # каталог скрипта

См. также