В чем разница между этими двумя командами?
. filename # (A)
и
filename # (B)
А как связана эта команда?
./filename # (C)
Примечание. Знак # и оставшаяся часть строки после него являются комментариями.
Команда (A) называется поиском файла, который состоит из команд оболочки. Его нельзя использовать для двоичных исполняемых файлов (см. man file
для получения информации о том, как определить тип файла). Это заставляет команды в файле выполняться в текущей среде, как если бы они были введены в приглашении оболочки. Результаты влияют на текущую среду и, таким образом, могут делать такие вещи, как установка значений переменных среды и изменение каталогов, добавление определений функций, среди прочего. Нет необходимости устанавливать бит выполнения с помощью chmod. Файл должен находиться в текущем каталоге, либо должен быть включен полный или относительный путь *, либо файл может находиться в месте, которое находится в PATH
переменная среды (зависит от того, sourcepath
вариант shopt
установлено). Нет необходимости указывать текущий каталог, если в нем находится файл. Все они эквивалентны:
$ ls
filename
$ . filename
results
$ ls /some/directory/filename
/some/directory/filename
$ . /some/directory/filename
results
$ cd /elsewhere
$ echo $PATH
/some/directory
$ . filename
results
Команда (B) заставляет оболочку выполнять файл только в том случае, если бит выполнения установлен для прав пользователя (см. man chmod
). Файл может быть сценарием оболочки, исполняемым двоичным файлом или другим сценарием, например Perl или Python (или написанным в другой оболочке). Если в имени нет косой черты (каталог не указан), то файл должен находиться в каталоге, который включен в PATH
переменная окружения. Можно включить текущий каталог в путь, но я не рекомендую это, потому что это угроза безопасности. Они эквивалентны:
$ echo $PATH
/some/directory
$ filename
results
$ /some/directory/filename
results
Команда (C), по сути, такая же, как команда (B), но указывает текущий каталог, который называется "." (так же, как родительский каталог упоминается как "..". ПУТЬ не будет искать, чтобы найти файл, поскольку каталог указан.
[*] Относительный путь - это путь, который не начинается с косой черты (/). Он указывает расположение относительно текущего каталога. «this / is / a / subdir» существует как путь к каталогу под текущим, как и «./this/is/a/subdir» (который указывает тот же каталог). "../another/set/of/dirs" - это набор каталогов ниже родительского для текущего.
Если вы исходите скрипт с
# . script
или
# source script
означает, что сценарий выполняется в текущей оболочке.
Если ты бежишь
# ./script
Он будет работать в новой оболочке и не будет иметь доступа к переменным, установленным в текущей оболочке, которые не были экспортированы в среду с помощью «экспорта».
Используя ". <executable>"
запускает исполняемый файл в контексте запущенной оболочки. Если вы установите переменные в скрипте, они будут сохраняться в оболочке, из которой вы их получили.
Нормальным поведением при выполнении программы или сценария является создание экземпляра новой оболочки и запуск процесса. (Вот почему скрипты начинаются с #!/bin/sh
, #!/bin/perl -w
и т. д. - который предписывает оболочку и параметры использования)
«Источник» сценария полезен для загрузки переменных среды, специфичных для приложения, обычно базы данных или среды разработки. Если вы запускаете несколько экземпляров Oracle или других баз данных, у вас может быть набор сценариев «источника» или «среды» для производственной среды, среды разработки и среды контроля качества. Если у вас есть ферма компиляции, нацеленная на несколько платформ (т. Е. Создание двоичных файлов Solaris из фермы Linux), у вас могут быть эти сценарии для простой загрузки соответствующих переменных среды.
А. имя файла
Выполняет файл сценария в текущем контексте. В основном используется для экспорта переменных из сценария оболочки в текущую запущенную оболочку. Поэтому, если экспортировать новую переменную в файл "~ / .bash_profile" и мы хотим применить изменения в текущей оболочке без выхода из системы, мы можем использовать команду
. ~/.bash_profile
для повторного выполнения "~ / .bash_profile" в текущем контексте и экспорта новых переменных.
Б. имя файла
Если команда присутствует в пути поиска, она будет выполнена. Файл с именем команды в текущей папке не будет выполнен, если текущая папка не включена в путь поиска. Чтобы увидеть текущий путь, используйте
echo $PATH
Если исполняемый файл с именем "filename" присутствует более чем в одной папке в пути. Исполняемый файл в первой указанной папке в пути будет выполнен. Чтобы увидеть, где находится исполняемый файл, введите "имя файла", используйте
which filename
C. ./filename
Он используется для выполнения исполняемого файла с именем файла, находящегося в текущем рабочем каталоге.