Есть несколько способов выполнить скрипт, известные мне:
/path/to/script # using the path (absolute or relative)
. script # using the . (dot)
source script # using the `source` command
Чем больше это? Каковы различия между ними? Есть ли ситуации, в которых я должен использовать одно, а не другое?
shell-script
executable
phunehehe
источник
источник
Ответы:
Другой способ - вызвать интерпретатор и передать ему путь к скрипту:
Точка и источник эквивалентны. (РЕДАКТИРОВАТЬ: нет, это не так: как указывает KeithB в комментарии к другому ответу, «.» Работает только в оболочках, связанных с bash, где «source» работает как в оболочках, связанных с bash, так и csh.) Он выполняет сценарий в -place (как будто вы скопировали и вставили скрипт прямо там). Это означает, что все функции и нелокальные переменные в скрипте остаются. Это также означает, что если скрипт вставит компакт-диск в каталог, вы все равно будете там, когда это будет сделано.
Другие способы запуска скрипта будут запускать его в своей собственной оболочке. Переменные в скрипте еще не живы, когда это сделано. Если скрипт изменил каталоги, то это не влияет на среду вызова.
/ path / to / script и / bin / sh script немного отличаются. Как правило, в начале скрипта есть «шебанг», который выглядит так:
Это путь к интерпретатору сценария. Если он указывает на интерпретатор, отличный от того, который вы делаете при его выполнении, он может вести себя по-другому (или вообще не работать).
Например, сценарии Perl и сценарии Ruby начинаются с (соответственно):
а также
Если вы запустите один из этих сценариев
/bin/sh script
, то они не будут работать вообще.Ubuntu на самом деле не использует оболочку bash, но очень похожую, называемую dash. Скрипты, которые требуют bash, могут работать немного неправильно при вызове,
/bin/sh script
потому что вы только что вызвали bash-скрипт, используя интерпретатор dash.Еще одно небольшое отличие между непосредственным вызовом сценария и передачей пути сценария интерпретатору заключается в том, что сценарий должен быть помечен как исполняемый для непосредственного запуска, а не для запуска путем передачи пути к интерпретатору.
Еще один незначительный вариант: вы можете использовать любой из этих способов выполнения скрипта с помощью eval, так что вы можете иметь
и так далее. На самом деле это ничего не меняет, но я подумал, что включу это для тщательности.
источник
sh
соответствуетdash
, но не кbash
.Большинство людей отлаживают сценарии оболочки, добавляя следующие сценарии отладки в сценарий:
Но это означает, что вам нужно открыть файл в редакторе (при условии, что у вас есть права на редактирование файла), добавить строку, например
set -x
, сохранить файл, а затем выполнить файл. Затем, когда вы закончите, вам нужно выполнить те же шаги и удалить иset -x
т. Д. И т. Д. Это может быть утомительно.Вместо того, чтобы делать все это, вы можете установить флаги отладки в командной строке:
источник
emulate sh 2>/dev/null
верхнюю часть моих сценариев оболочки. При запуске с zsh это переводит его в POSIX-совместимый режим. При запуске с другими оболочками линия не имеет никакого эффекта. Тогда я могу запустить скрипт сzsh -x /path/to/script
. Мне здесь нравится zsh, потому что он обеспечивает лучшие трассировки, чем bash или ksh.Шон Дж. Гофф сделал много хороших замечаний, но не включил всю историю:
Многие системные скрипты (например, в init.d, в / etc и т. Д.) Имеют шебанг
#!/bin/sh
, но/bin/sh
на самом деле являются символической ссылкой на другую оболочку - в прежние времена/bin/bash
, в настоящее время/bin/dash
. Но когда один из них вызывается как/bin/sh
, они ведут себя по-разному, то есть придерживаются режима совместимости с POSIX.Как они это делают? Ну, они проверяют, как они были вызваны.
Может ли сам шеллскрипт проверить, как он вызывался, и делать разные вещи, в зависимости от этого? Да, оно может. То, как вы вызываете его, всегда может привести к разным результатам, но, конечно, это редко делается, чтобы вас раздражать. :)
Практическое правило. Если вы изучаете конкретную оболочку, например bash, и пишете команды из учебника по bash, вставьте
#!/bin/bash
заголовок, но#!/bin/sh
только если не указано иное. Иначе ваши команды могут потерпеть неудачу. И если вы сами не написали скрипт, вызовите его напрямую (./foo.sh
,bar/foo.sh
), а не угадывайте оболочку (sh foo.sh
,sh bar/foo.sh
). Шебанг должен вызывать правильную оболочку.И вот два других вида вызова:
источник
.
иsource
эквивалентны тем, что они не порождают подпроцесс, а выполняют команды в текущей оболочке. Это важно, когда скрипт устанавливает переменные среды или изменяет текущий рабочий каталог.Использование пути или его указание
/bin/sh
создает новый процесс, в котором выполняются команды.источник
Я размышляю, есть ли еще ...
.
иsource
такие же. После выполнения любые изменения окружения вscript
будут сохранены. Обычно она используется для создания библиотеки Bash, поэтому ее можно повторно использовать во многих различных сценариях.Также это хороший способ сохранить текущий каталог. Если вы измените каталог в скрипте, он не будет применен в оболочке, в которой вы выполняете этот скрипт. Но если вы его запустите, после выхода из скрипта текущий каталог будет сохранен.
источник
.
работает только в sh / bash и связанных оболочках.source
также работает в csh и связанных оболочках.Считается ли " userland exec " другим способом? Пользовательская область exec загружает код и заставляет его выполняться без использования системного вызова execve ().
источник
Запускает скрипт в текущей оболочке, когда каталог не находится в пути.
источник
, и источник немного отличается в Zsh по крайней мере (это то, что я использую), потому что
Работы, в то время как
не нужно
источник