Linux скрипт текущая директория
Иногда нужно знать, в каком каталоге находится запущенный скрипт. Ну, например, в этом же каталоге лежат другие скрипты, которые должны быть запущены текущим выполняющемся скриптом. Для того, чтобы он их запустил, ему было бы неплохо знать, где их искать, потому что вы могли запустить скрипт находясь в совершенно произвольной директории, или воспользоваться для запуска не самим файлом скрипта, а символической ссылкой, лежащей в другом каталоге, которая указывает на файл скрипта.
Можно, конечно, поступить просто и в самом скрипте в переменной жёстко прописать полный путь до каталога, в котором этот скрипт лежит. Получится что-то вроде этого:
Вполне рабочий вариант и две обозначенные выше проблемы будут решены, но если надо будет переместить скрипт в другой каталог, то и значение переменной придётся руками поменять в самом скрипте. Не очень удобно.
Для красивого решения проблемы нужно знать всего три вещи:
- Путь до выполняющегося скрипта можно узнать с помощью $0, но проблема в том, что он относительный, т.е. если вы запустите скрипт как ./script.sh, то и $0 будет содержать ./script.sh
- Команда readlink с параметром -e решит сразу две проблемы: во-первых она вернет полный путь до файла скрипта, если вы воспользовались для запуска символической ссылкой (даже если это была цепочка симлинков), а во-вторых преобразует относительный путь, если такой получен с помощью $0, в абсолютный
- Чтобы избавиться от имени файла скрипта в конце абсолютного пути, нужно воспользоваться командой dirname
Пример:
13 комментариев:
А если не воспользовались для запуска символической ссылкой?
Да и к чему городить огород.
Проще так:
DIRSCRIPT=$(pwd) # Текущая директория
echo «$
Поправка.. Короче, разобрался. Все это туфта и то и другое.
Вот универсальное отличное решение, особенно, если учитывать, что во фряхе нет «readlink»..
И запускайте скрипт как хотите..
> А если не воспользовались для запуска символической ссылкой?
Отработает всё совершенно корректно
А вы уверены, что называть туфтой решение в котором вы так и не разобрались хорошая идея?
> во фряхе нет «readlink»
Где я писал что это должно работать во фрибсд? Прочитайте название блога и сообщения.
Я не использую фрибсд, но позволю себе поинтересоваться, а какой интерпретатор команд вы используете в ней? На сколько мне известно, по умолчанию там tcsh или csh, а совсем не bash.
> И запускайте скрипт как хотите
Да что вы? Оукей. Тогда создайте символьную ссылку на свой скрипт в другом каталоге (не в том в котором лежит скрипт), войдите в этот каталог и выполните симлинк. Сильно удивитесь. Ваше решение вернет путь до каталога, в котором находится симлинк, вместо каталога в котором находится сам скрипт. Надеюсь доступно объяснил.
А еще поясните, пожалуйста, чем решение из двух команд, приведенное мной, «огороднее» вашего решения из трёх команд? Кроме того, переход в каталог для того что бы узнать путь до него немножко попахивает костылем, вам так не кажется? Но это я уже придираюсь, конечно, т. к. в баше без костылей никуда.
Источник
[bash] Как изменить текущий каталог?
Собственно вопрос чрезвычайно прост — как изменить текущий каталог с помощью bash-скрипта? Ведь, как-то это делает cd.
Suntechnic> Ведь, как-то это делает cd.
да уж. Твой интерактивный шелл и есть bash
а по существу вопроса:
cd — встроенная команда shell-а, одна из немногих, которые должны быть встроенными и не могут быть реализованы внешними программами.
а поподробнее можно почему cd не устраивает?
>как изменить текущий каталог с помощью bash-скрипта?
[code=bash] cd $DIRECTORY [/code]
>Ведь, как-то это делает cd.
«Ведь» не является вводным словом и запятыми не выделяется.
>Собственно вопрос чрезвычайно прост — как изменить текущий каталог с помощью bash-скрипта
Перед прямым вопросом, включённым в состав бессоюзного сложного предложения, ставится двоеточие, а не тире.
Спасибо, anonymous.
Ваши замечания чрезвычайно ценны и познавательны, но вопрос касался другого языка. Жаль, что выучив русский язык вы так и не научились читать на нём.
P.S.
Расставьте пожалуйста запятые — я не осилил.
Потому, что он его не изменяет.
Вопрос скорее относится к логике обращения с окружением и может звучать так: как изменить переменную родительского процесса?
P.S. anonymous, теперь правильно?
Что-то у вас не так.
> cd — встроенная команда shell-а, одна из немногих, которые должны быть встроенными и не могут быть реализованы внешними программами.
Я это подозревал, особенно после того как не нашёл файла cd.
Текущий каталог является свойством каждого процесса. bash запускает процессы и у процессов свой текущий каталог. Поэтому оно и встроено в bash, потому что запуски других процессов (вроде исполняемого файла cd) не повлияют на текущий каталог самого процесса bash.
Нужно вписать
В чью-то тетрадь
Кровью, как в метрополетене:
«Выхода нет».
Выхода нет.
Вопрос скорее относится к логике обращения с окружением и может звучать так: как изменить переменную родительского процесса?
не знаю, есть ли более простой способ.
А вообще может подойдёт такое:
На самом деле климатит то, что команда cd не создаёт каталог, если он отсутствует. Хочется иметь команду которая рекурсивно создавала бы каталог и делала его текущим.
> [ -d $PAATH ] || mkdir -p $PAATH
Да, извиняюсь. Системную переменную использовал.
Вообще как бы весь топик посвящен тому, как это сделать, потому, что код
Работает. Естественно, внутри скрипта. Т.к. скрипт запускается в отдельной сессии bash. А сменить текущую директорию в bash’е, из которого вызывался скрипт, из скрипта нельзя. Да и зачем это? Если так уж хочется, можно сделать alias mycd=«cd $(sript)», где script — ваш скрипт, который что-то делает, а затем выводит имя директории, в которую нужно перейти по окончании работы скрипта.
Источник
Как установить текущий рабочий каталог скрипта?
Я пишу bash-скрипт. Мне нужно, чтобы текущий рабочий каталог всегда был каталогом, в котором находится скрипт.
поведение по умолчанию заключается в том, что текущий рабочий каталог в скрипте-это оболочка, из которой я его запускаю, но я не хочу этого поведения.
10 ответов
синтаксис подробно описан в этой ответ StackOverflow.
попробуйте следующие простые выражения:
для всех UNIX / OSX / Linux
Примечание: двойная тире ( — ) используется в командах для обозначения конца параметров команды, поэтому файлы, содержащие тире или другие специальные символы, не нарушат команду.
для Linux, Mac и других *BSD:
С поддержкой пробелов:
Примечание.: realpath должен быть установлен в самом популярном дистрибутиве Linux по умолчанию (например, Ubuntu), но в некоторых он может отсутствовать, поэтому вам придется установить его.
в противном случае вы могли бы попробовать что-то подобное (он будет использовать существующий инструмент):
для Linux specific:
использование GNU readlink на *BSD / Mac:
Примечание: Вы должны иметь coreutils установленные (например, 1. Установить доморощенного, 2. brew install coreutils ).
в bash
в bash, вы можете использовать Разложений Параметра чтобы достичь этого, например:
но это не работает, если скрипт запускается из той же директории.
в качестве альтернативы вы можете определить следующую функцию в bash:
эта функция принимает 1 аргумент. Если аргумент уже имеет абсолютный путь, распечатайте его как есть, иначе print $PWD переменная + аргумент filename (без ./ префикс).
Источник
Получение исходного каталога скрипта Bash изнутри
Как получить путь к каталогу, в котором Баш сценарий находится, внутри этот скрипт?
например, предположим, я хочу использовать скрипт Bash в качестве запуска для другого приложения. Я хочу изменить рабочий каталог на тот, где находится скрипт Bash, чтобы я мог работать с файлами в этом каталоге, например:
30 ответов
является полезным однострочным, который даст вам полное имя каталога скрипта независимо от того, откуда он вызывается.
он будет работать до тех пор, пока последний компонент пути, используемый для поиска скрипта, не является символической ссылкой (ссылки каталога в порядке). Если вы также хотите разрешить любые ссылки на сам скрипт, вам нужно многострочное решение:
этот последний будет работать с любой комбинацией псевдонимы, source , bash -c , симлинки, так далее.
остерегайтесь: если вы cd в другой каталог перед запуском этого фрагмента, результат может быть неправильным! Кроме того, следите за $CDPATH gotchas.
чтобы понять, как это работает, попробуйте запустить этот более подробном виде:
и он напечатает что-то вроде:
используя pwd один не будет работать, если вы не запускаете скрипт из каталога, в котором он содержится.
команда dirname является самой простой, просто разбирая путь до имени файла с переменной $0 (имя скрипта):
, а как Мэтт б указал, возвращаемый путь отличается в зависимости от того, как вызывается скрипт. pwd не выполняет эту работу, потому что это говорит вам только о текущем каталоге, а не о том, в каком каталоге находится скрипт. Кроме того, если выполняется символическая ссылка на скрипт ,вы получите (возможно, относительную) путь к тому, где находится ссылка, а не фактический скрипт.
некоторые другие упомянули более ранних версий команда, но в самом простом виде вы можете использовать:
readlink разрешит путь скрипта к абсолютному пути от корня файловой системы. Таким образом, любые пути, содержащие одиночные или двойные точки, Тильды и/или символические ссылки, будут разрешены до полного пути.
вот сценарий, демонстрирующий каждый из них, whatdir.sh:
запуск этого скрипта в моем домашнем каталоге, используя относительный путь:
снова, но используя полный путь к скрипту:
теперь изменение каталогов:
и, наконец, используя символическую ссылку, чтобы выполнить скрипт:
работает для всех версий,в том числе
- при вызове через мягкую ссылку multple depth,
- когда файл
- когда скрипт вызывается командой » source » ака . (точка) оператор.
- когда arg изменяется от абонента.
- «./script»
- «/full/path/to/script»
- «/some/path/../../another/path/script»
- «./some/folder/script»
альтернативно, если сценарий bash сам относительная ссылка вы хочу чтобы следовать за ним и вернуть полный путь связанного скрипта:
SCRIPT_PATH дается в полном пути, независимо от того, как он называется.
Просто убедитесь, что вы нашли это в начале сценария.
этот комментарий и код Copyleft, выбираемая лицензия под GPL2.0 или более поздней версии или CC-SA 3.0 (CreativeCommons Share Alike) или более поздней версии. c) 2008 год. Все права защищены. Никаких гарантий. Вы были warned.
http://www.gnu.org/licenses/gpl-2.0.txt
http://creativecommons.org/licenses/by-sa/3.0/
18eedfe1c99df68dc94d4a94712a71aaa8e1e9e36cacf421b9463dd2bbaa02906d0d6656
вы можете использовать $BASH_SOURCE
обратите внимание, что вы должны использовать #!/ bin / bash, а не #!/bin / sh с его расширением bash
Это должно сделать это:
работает с символическими ссылками и пробелами в path. Видеть страницах dirname и более ранних версий.
из комментария, похоже, не работает с Mac OS. Понятия не имею почему. Есть предложения?
pwd можно использовать для поиска текущего рабочего каталога и dirname найти каталог конкретного файла (команда, которая была запущена, составляет , так что dirname должен дать вам каталог текущего скрипта).
, dirname дает точно часть каталога имени файла, которая, скорее всего, будет относительно текущего рабочего каталога. Если вашему скрипту по какой-то причине нужно изменить каталог, то вывод из dirname становиться бессмысленным.
Я предлагаю следующее:
таким образом, вы получите абсолютный, а не относительный путь.
поскольку скрипт будет запущен в отдельном экземпляре bash, нет необходимости восстанавливать рабочий каталог после этого, но если вы по какой-то причине хотите вернуться в свой скрипт, вы можете легко назначить значение pwd в переменную перед изменением каталога для дальнейшего использования.
решает конкретный сценарий в вопросе, я считаю, что абсолютный путь более полезен в целом.
Я не думаю, что это так просто, как другие сделали это. pwd не работает, так как текущий каталог не обязательно является каталогом со скриптом. $0 также не всегда имеет информацию. Рассмотрим следующие три способа вызова скрипта.
в первом и третьем способах $0 не имеет полной информации о пути. Во втором и третьем pwd не работают. Единственный способ получить dir третьим способом — это запустить путь и найти файл с правильное совпадение. В основном код должен был бы переделать то, что делает ОС.
один из способов сделать то, что вы просите, — это просто жестко закодировать данные в каталоге /usr/share и ссылаться на него полным путем. В любом случае данные не должны быть в каталоге /usr/bin, так что это, вероятно, то, что нужно сделать.
это получает текущий рабочий каталог на Mac OS X 10.6.6:
это специально для Linux, но вы можете использовать:
вот POSIX совместимый однострочный:
Я пробовал каждый из них, и ни один из них не работал. Один был очень близко, но имел крошечный жучок, который сломал его плохо; они забыли обернуть путь в кавычки.
также многие люди предполагают, что вы запускаете скрипт из оболочки, поэтому забудьте, когда вы открываете новый скрипт, он по умолчанию используется в вашем доме.
попробуйте этот каталог для размера:
/ var / No one / Thought/About Spaces Being/in a Directory/Name / и вот ваш файл.текст
это получает правильно, независимо от того, как и где вы его запускаете.
поэтому, чтобы сделать его действительно полезным, вот как перейти в каталог запущенного скрипта:
надеюсь, что это поможет
Я бы использовал что-то вроде этого:
небольшое изменение решения e-satis и 3bcdnlklvc04a указано в ответ
Это должно работать во всех случаях, которые они перечислили.
EDIT: предотвращение popd после неудачного pushd, благодаря konsolebox
вот простой, правильный путь:
$ — полный путь к скрипту. Значение этого будет правильным даже тогда, когда скрипт находится в исходном состоянии, например source печать Баш, при замене его на $
readlink -f — Рекурсивно разрешает любые символические ссылки в указанном пути. Это расширение GNU и недоступно (например) в системах BSD. Если вы используете Mac, вы можете использовать Homebrew для установки GNU coreutils и замените это на greadlink -f .
и конечно dirname получает родительский каталог путь.
$_ стоит упомянуть в качестве альтернативы $0. Если вы запускаете скрипт из bash, принятый ответ может быть сокращен до:
обратите внимание, что это должен быть первый оператор в вашем скрипте.
я сравнил многие из приведенных ответов и придумал несколько более компактных решений. Они, кажется, обрабатывать все сумасшедшие случаи края, которые возникают из вашей любимой комбинации:
- абсолютные пути или относительные пути
- файл и каталог ссылок
- вызов как script , bash script , bash -c script , source script или . script
- пробелы, вкладки, новые строки, unicode и т. д. в каталогах и/или именем
- имена файлов, начинающиеся с дефиса
если вы работаете с Linux, кажется, что с помощью proc handle-лучшее решение для поиска полностью разрешенного источника текущего запущенного скрипта (в интерактивном сеансе ссылка указывает на соответствующий /dev/pts/X ):
в этом есть немного уродства, но исправление компактно и легко понять. Мы не используем только примитивы bash, но я в порядке с этим потому что readlink значительно упрощает задачу. The echo X добавляет X до конца строки переменной, так что любые конечные пробелы в имени файла не съедаются, а подстановка параметров $ в конце строки избавляется от X . Потому что readlink добавляет свою собственную новую строку (которая обычно была бы съедена в замене команды, если бы не наш предыдущий обман), мы должны избавиться от этого тоже. Это легче всего сделать с помощью $» схема цитирования, которая позволяет использовать escape-последовательности, такие как \n для представления новых строк (это также, как вы можете легко сделать хитро именованные каталоги и файлы).
выше должно охватывать ваши потребности в поиске текущего сценария на Linux, но если у вас нет proc файловая система в вашем распоряжении, или если вы пытаетесь найти полностью разрешенный путь к какому-либо другому файлу, возможно, вы найдете приведенный ниже код полезным. Это только небольшая модификация от выше один-лайнер. Если вы играете со странным каталогом / именами файлов, проверьте вывод с помощью обоих ls и readlink информативно, как ls выведет «упрощенные» пути, подставляя ? для таких вещей, как newlines.
Источник