Поиск сценария будет запускать команды в текущем процессе оболочки.
Выполнение скрипта запустит команды в новом процессе оболочки.
Используйте исходный код, если вы хотите, чтобы скрипт изменил среду в текущей запущенной оболочке. используйте выполнить иначе.
Если вы все еще не уверены, читайте дальше.
терминология
Чтобы прояснить некоторую путаницу в отношении синтаксиса для выполнения и синтаксиса для источника:
./myscript
Это будет выполненоmyscript при условии, что файл является исполняемым и находится в текущем каталоге. Начальная точка и косая черта ( ./) обозначают текущий каталог. Это необходимо, потому что текущего каталога обычно нет (и обычно не должно быть) в $PATH.
myscript
Это будет выполнено,myscript если файл является исполняемым и расположен в некотором каталоге в $PATH.
source myscript
Это будет источникmyscript . Файл не обязательно должен быть исполняемым, но это должен быть допустимый скрипт оболочки. Файл может находиться в текущем каталоге или в каталоге в $PATH.
. myscript
Это также источникmyscript . Это «правописание» является официальным по определению POSIX . Bash определяется sourceкак псевдоним точки.
демонстрация
Рассмотрим myscript.shсо следующим содержанием:
#!/bin/sh# demonstrate setting a variable
echo "foo: "$(env | grep FOO)
export FOO=foo
echo "foo: "$(env | grep FOO)# demonstrate changing of working directory
echo "PWD: "$PWD
cd somedir
echo "PWD: "$PWD
Прежде чем выполнить скрипт, мы сначала проверяем текущую среду:
$ env | grep FOO
$ echo $PWD
/home/lesmana
Переменная FOOне определена, и мы находимся в домашнем каталоге.
Переменная FOOне установлена и рабочий каталог не изменился.
Выходные данные скрипта ясно показывают, что переменная была установлена, а каталог был изменен. Проверка позже показывает, что переменная не установлена и каталог не изменен. Что случилось? Изменения были сделаны в новой оболочке. Текущая оболочка породила новую оболочку для запуска сценария. Сценарий выполняется в новой оболочке, и все изменения в среде вступают в силу в новой оболочке. После выполнения скрипта новая оболочка уничтожается. Все изменения среды в новой оболочке уничтожаются новой оболочкой. Только текущий текст выводится в текущей оболочке.
Переменная FOO установлена, и рабочий каталог изменился.
Sourcing скрипт не создает новую оболочку. Все команды выполняются в текущей оболочке, а изменения в среде вступают в силу в текущей оболочке.
Обратите внимание, что в этом простом примере результат выполнения аналогичен поиску сценария. Это не всегда так.
Еще одна демонстрация
Рассмотрим следующий скрипт pid.sh:
#!/bin/sh
echo $$
(специальная переменная $$расширяется до PID текущего запущенного процесса оболочки)
Сначала выведите PID текущей оболочки:
$ echo $$
25009
Источник сценария:
$ source pid.sh
25009
Выполните скрипт, запишите PID:
$ ./pid.sh
25011
Источник снова:
$ source pid.sh
25009
Выполните снова:
$ ./pid.sh
25013
Вы можете видеть, что использование сценария выполняется в одном и том же процессе, а выполнение сценария каждый раз создает новый процесс. Этот новый процесс - новая оболочка, которая была создана для выполнения скрипта. Выбор сценария не создает новую оболочку, поэтому PID остается прежним.
Резюме
Как поиск, так и выполнение скрипта будут запускать команды в скрипте построчно, как если бы вы вводили эти команды вручную построчно.
Различия:
Когда вы выполняете скрипт, который вы открываете новую оболочку, введите команды в новой оболочке, скопируйте вывод обратно в вашу текущую оболочку, затем закройте новую оболочку. Любые изменения в среде вступят в силу только в новой оболочке и будут потеряны после закрытия новой оболочки.
Когда источник скрипта , который вы набираете команды в вашей текущей оболочке. Любые изменения в среде вступят в силу и останутся в вашей текущей оболочке.
Используйте исходный код, если вы хотите, чтобы скрипт изменил среду в текущей запущенной оболочке. используйте выполнить иначе.
Одним из способов использования источников является создание элементарной формы файла конфигурации для ваших сценариев. Вы начинаете с того, что устанавливаете различные переменные в значения по умолчанию, а затем исходите из чего-то вроде myscript.conf - и этот исходный скрипт может иметь операторы присваивания, которые переопределяют любые значения, которые вы хотите. Поскольку исходный скрипт не начинается с # / bin / bash, его не рекомендуется выполнять напрямую.
LawrenceC
Таким образом, источник вроде как запускает его в глобальной области видимости, а выполнение создает новую локальную область видимости. Можно ли распространить это на функцию в скрипте? выполнить функцию (обычно) или «получить» ее?
aliteralmind
2
Есть ли разница между использованием source myscript.shи . myscript.sh?
Holloway
2
практически без разницы, если использовать Bash. source это псевдоним в bash.
Лесмана
1
Мне нравится, когда люди приводят такие сложные примеры, чтобы даже новички в Linux, такие как я, могли понять. Спасибо!
Джулиус
21
Выполнение сценария запускает его в отдельном дочернем процессе, т. Е. Для обработки сценария вызывается отдельный экземпляр оболочки. Это означает, что любые переменные среды и т. Д., Определенные в сценарии, не могут быть обновлены в родительской (текущей) оболочке.
Выбор сценария означает, что он анализируется и выполняется самой текущей оболочкой. Это как если бы вы набрали содержимое скрипта. По этой причине исходный скрипт не обязательно должен быть исполняемым. Но он должен быть исполняемым, если вы выполняете его, конечно.
Если у вас есть позиционные аргументы в текущей оболочке, они неизменны.
хотя этот ответ верен во всех отношениях, мне очень трудно его понять, потому что он демонстрируется с использованием другой концепции (установка позиционных параметров), которая, на мой взгляд, еще более запутана, чем различие в поиске и выполнении самого себя.
Лесмана
9
sourcing - это то же самое, что вводить каждую строку скрипта в командной строке по одному ...
Выполнение запускает новый процесс, а затем запускает каждую строку сценария, изменяя только текущее окружение тем, что оно возвращает.
В дополнение к вышесказанному, выполнение сценария, как ./myscriptтребуется, требует разрешения на выполнение для файла myscript, в то время как поиск не требует разрешения на выполнение. Вот почему chmod +x myscriptне требуется раньшеsource myscript
Правда, но если это проблема, вы всегда можете запустить bash myscript.
Даниэль Бек
5
В источнике вы получите все дополнительные переменные, определенные в скрипте.
Поэтому, если у вас есть конфиги или определения функций, вы должны исходить, а не выполняться. Казни не зависят от родительской среды.
Если я правильно помню, выполнение сценария запускает исполняемый файл в #!строке с файлом сценария в качестве аргумента (как правило, запускает новую оболочку и эффективно использует сценарий в новой оболочке, как в случае с #!/bin/sh);
тогда как поиск сценария выполняет каждую строку в текущей среде оболочки, что полезно для изменения текущей оболочки (например, предоставления способа определения функций оболочки и экспорта переменных среды).
sourceКоманда выполняет предоставленный сценарий (разрешение на выполнение не является обязательным ) в текущей среде оболочки, а запускает./ предоставленный исполняемый сценарий в новой оболочке.
Ответы:
Краткий ответ
Поиск сценария будет запускать команды в текущем процессе оболочки.
Выполнение скрипта запустит команды в новом процессе оболочки.
Используйте исходный код, если вы хотите, чтобы скрипт изменил среду в текущей запущенной оболочке. используйте выполнить иначе.
Если вы все еще не уверены, читайте дальше.
терминология
Чтобы прояснить некоторую путаницу в отношении синтаксиса для выполнения и синтаксиса для источника:
Это будет выполнено
myscript
при условии, что файл является исполняемым и находится в текущем каталоге. Начальная точка и косая черта (./
) обозначают текущий каталог. Это необходимо, потому что текущего каталога обычно нет (и обычно не должно быть) в$PATH
.Это будет выполнено,
myscript
если файл является исполняемым и расположен в некотором каталоге в$PATH
.Это будет источник
myscript
. Файл не обязательно должен быть исполняемым, но это должен быть допустимый скрипт оболочки. Файл может находиться в текущем каталоге или в каталоге в$PATH
.Это также источник
myscript
. Это «правописание» является официальным по определению POSIX . Bash определяетсяsource
как псевдоним точки.демонстрация
Рассмотрим
myscript.sh
со следующим содержанием:Прежде чем выполнить скрипт, мы сначала проверяем текущую среду:
Переменная
FOO
не определена, и мы находимся в домашнем каталоге.Теперь мы выполняем файл:
Проверьте среду еще раз:
Переменная
FOO
не установлена и рабочий каталог не изменился.Выходные данные скрипта ясно показывают, что переменная была установлена, а каталог был изменен. Проверка позже показывает, что переменная не установлена и каталог не изменен. Что случилось? Изменения были сделаны в новой оболочке. Текущая оболочка породила новую оболочку для запуска сценария. Сценарий выполняется в новой оболочке, и все изменения в среде вступают в силу в новой оболочке. После выполнения скрипта новая оболочка уничтожается. Все изменения среды в новой оболочке уничтожаются новой оболочкой. Только текущий текст выводится в текущей оболочке.
Теперь мы поставляем файл:
Проверьте среду еще раз:
Переменная FOO установлена, и рабочий каталог изменился.
Sourcing скрипт не создает новую оболочку. Все команды выполняются в текущей оболочке, а изменения в среде вступают в силу в текущей оболочке.
Обратите внимание, что в этом простом примере результат выполнения аналогичен поиску сценария. Это не всегда так.
Еще одна демонстрация
Рассмотрим следующий скрипт
pid.sh
:(специальная переменная
$$
расширяется до PID текущего запущенного процесса оболочки)Сначала выведите PID текущей оболочки:
Источник сценария:
Выполните скрипт, запишите PID:
Источник снова:
Выполните снова:
Вы можете видеть, что использование сценария выполняется в одном и том же процессе, а выполнение сценария каждый раз создает новый процесс. Этот новый процесс - новая оболочка, которая была создана для выполнения скрипта. Выбор сценария не создает новую оболочку, поэтому PID остается прежним.
Резюме
Как поиск, так и выполнение скрипта будут запускать команды в скрипте построчно, как если бы вы вводили эти команды вручную построчно.
Различия:
Используйте исходный код, если вы хотите, чтобы скрипт изменил среду в текущей запущенной оболочке. используйте выполнить иначе.
Смотрите также:
источник
source myscript.sh
и. myscript.sh
?Выполнение сценария запускает его в отдельном дочернем процессе, т. Е. Для обработки сценария вызывается отдельный экземпляр оболочки. Это означает, что любые переменные среды и т. Д., Определенные в сценарии, не могут быть обновлены в родительской (текущей) оболочке.
Выбор сценария означает, что он анализируется и выполняется самой текущей оболочкой. Это как если бы вы набрали содержимое скрипта. По этой причине исходный скрипт не обязательно должен быть исполняемым. Но он должен быть исполняемым, если вы выполняете его, конечно.
Если у вас есть позиционные аргументы в текущей оболочке, они неизменны.
Так что, если у меня есть файл,
a.sh
содержащий:и я делаю:
Я получаю что-то вроде:
В то время как:
дает мне:
Надеюсь, это поможет.
источник
sourcing - это то же самое, что вводить каждую строку скрипта в командной строке по одному ...
Выполнение запускает новый процесс, а затем запускает каждую строку сценария, изменяя только текущее окружение тем, что оно возвращает.
источник
В дополнение к вышесказанному, выполнение сценария, как
./myscript
требуется, требует разрешения на выполнение для файла myscript, в то время как поиск не требует разрешения на выполнение. Вот почемуchmod +x myscript
не требуется раньшеsource myscript
источник
bash myscript
.В источнике вы получите все дополнительные переменные, определенные в скрипте.
Поэтому, если у вас есть конфиги или определения функций, вы должны исходить, а не выполняться. Казни не зависят от родительской среды.
источник
Если я правильно помню, выполнение сценария запускает исполняемый файл в
#!
строке с файлом сценария в качестве аргумента (как правило, запускает новую оболочку и эффективно использует сценарий в новой оболочке, как в случае с#!/bin/sh
);тогда как поиск сценария выполняет каждую строку в текущей среде оболочки, что полезно для изменения текущей оболочки (например, предоставления способа определения функций оболочки и экспорта переменных среды).
источник
source
Команда выполняет предоставленный сценарий (разрешение на выполнение не является обязательным ) в текущей среде оболочки, а запускает./
предоставленный исполняемый сценарий в новой оболочке.Также, проверьте этот ответ, например: https://superuser.com/a/894748/432100
источник