Переменная $ 0 содержит информацию о пути скрипта.
- Как я могу изменить информацию о пути к абсолютному пути? Я имею в виду, как обрабатывать ~,., .. или подобное?
- Как я могу разбить информацию о пути на каталог и имя файла?
Я мог бы использовать python / perl для этого, но я хочу использовать bash, если это возможно.
Ответы:
Вам не нужно обрабатывать такие вещи, как
~
оболочка делает это за вас. Вот почему вы можете перейти~/filename
к любому сценарию или программе, и это работает - все эти программы не обрабатывают~
себя, ваша оболочка преобразует аргумент/home/username/filename
и передает его программе:Если вам нужно каноническое имя файла (которое не включает в себя такие вещи, как
..
), используйтеrealpath
(спасибо Нил ):Что касается разделения пути на имя каталога и имя файла, используйте
dirname
иbasename
:источник
realpath
лучше, но,readlink
кажется, работает, когда я пробую это; Вы знаете пример, где это терпит неудачу?cd /tmp; touch foo; ln -s foo bar; cd; readlink /tmp/bar
, Это возвращаетсяfoo
иrealpath
возвращается/tmp/foo
, что вы хотите.readlink -f
(примечание-f
) почти эквивалентенrealpath
и более переносим:readlink -f
в GNU coreutils и существует также в нескольких других системах;realpath
упакован отдельно и может быть не установлен (например, только 5 нестандартных пакетов зависят от него в Ubuntu 10.04 или Debian lenny).Использование dirname и basename, как было упомянуто Майклом, должно быть самым безопасным способом получить то, что вы хотите.
В любом случае, если вы действительно хотите сделать это с помощью инструментов «bash only», вы можете использовать подстановку параметров:
Этот пример взят из Руководства по расширенному написанию сценариев, которое стоит посмотреть.
Объяснение довольно простое:
Посмотрите на шаблон как на регулярное выражение
#
или##
как на жадный / не жадный модификатор.Это может стать полезным, если вам придется делать более сложные извлечения части пути.
источник
${...##...}
и друзей , а неdirname
и ,basename
что они не работают во всех случаях. Например, оба${0##*/}
и${0%/*}
расширить до того же, как$0
будто$0
не содержит/
.${0%/*}
это не хорошая альтернативаdirname
. Однако, что не так с использованием${0##*/}
вместоbasename
?$0
имя каталога с завершающим/
. Но я сожалею о своем совете, потомуdirname
что не делает лучше.realpath
это команда, которая говорит вам реальный путь (удаляет .. и символические ссылки и т. д.)Это стандартно с FreeBSD. Согласно этому обсуждению это также доступно для Linux:
http://www.unix.com/shell-programming-scripting/89294-geting-real-path.html
Это обсуждение также предлагает решение Bash:
источник