Команда dirname является самой простой, просто анализируя путь к имени файла из переменной $ 0 (имя скрипта):
dirname "$0"
Но, как указал matt b , возвращаемый путь отличается в зависимости от того, как вызывается скрипт. pwd не выполняет эту работу, потому что она говорит только о том, что является текущим каталогом, а не в каком каталоге находится скрипт. Кроме того, если выполняется символическая ссылка на скрипт, вы получите (возможно, относительный) путь где находится ссылка, а не фактический скрипт.
Некоторые другие упоминали команду readlink , но в простейшем случае вы можете использовать:
dirname "$(readlink -f "$0")"
readlink разрешит путь сценария к абсолютному пути от корня файловой системы. Таким образом, любые пути, содержащие одинарные или двойные точки, тильды и / или символические ссылки, будут преобразованы в полный путь.
Вот скрипт, демонстрирующий каждый из них, whatdir.sh:
#!/bin/bash
echo "pwd: `pwd`"
echo "\$0: $0"
echo "basename: `basename $0`"
echo "dirname: `dirname $0`"
echo "dirname/readlink: $(dirname $(readlink -f $0))"
Запуск этого скрипта в моей домашней директории с использованием относительного пути:
>>>$ ./whatdir.sh
pwd: /Users/phatblat
$0: ./whatdir.sh
basename: whatdir.sh
dirname: .
dirname/readlink: /Users/phatblat
Опять же, но с использованием полного пути к сценарию:
>>>$ /Users/phatblat/whatdir.sh
pwd: /Users/phatblat
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
Теперь смена каталогов:
>>>$ cd /tmp
>>>$ ~/whatdir.sh
pwd: /tmp
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
И наконец, используя символическую ссылку для выполнения скрипта:
>>>$ ln -s ~/whatdir.sh whatdirlink.sh
>>>$ ./whatdirlink.sh
pwd: /tmp
$0: ./whatdirlink.sh
basename: whatdirlink.sh
dirname: .
dirname/readlink: /Users/phatblat