У меня есть сценарий, в котором я не хочу, чтобы он вызывался, exit
если он получен.
Я подумал о том, чтобы проверить, $0 == bash
есть ли проблемы, если сценарий получен из другого сценария или если пользователь получает его из другой оболочки, например ksh
.
Есть ли надежный способ определить, что сценарий был получен?
Ответы:
Это похоже на переносимость между Bash и Korn:
Строка, аналогичная этой, или подобное присвоение
pathname="$_"
(с более поздним тестом и действием) должна находиться в первой строке скрипта или в строке после шебанга (который, если используется, должен быть для ksh, чтобы он работал в большинство обстоятельств).источник
BASH_ENV
,$_
в верхней части скрипта будет последняя команда, запущенная изBASH_ENV
.$_
является проблемой.bash script
(вызов через исполняемый файл оболочки, о котором это решение неверно сообщает как источник ), и (b) (гораздо менее вероятно)echo bash; . script
(если он$_
совпадает с тем, что сценарий содержит оболочку, это решение представляет его как подоболочка ). Только специфичные для оболочки специальные переменные (например,$BASH_SOURCE
) допускают надежные решения (из этого следует, что не существует надежного POSIX-совместимого решения). Это является возможным, хотя и громоздким, чтобы выработать надежный тест кросса-оболочку.Если ваша версия Bash знает о переменной массива BASH_SOURCE, попробуйте что-то вроде:
источник
${BASH_SOURCE[0]}
вместо просто$BASH_SOURCE
? А${0}
против$0
?BASH_SOURCE
переменная массива (см. руководство ), которая содержит трассировку стека источников, где${BASH_SOURCE[0]}
находится самая последняя. Здесь используются скобки, чтобы сообщить bash, что является частью имени переменной. Они не нужны$0
в этом случае, но они также не причиняют вреда. ;)$array
вы получите${array[0]}
по умолчанию. Итак, опять же, есть ли причина [...]?Надежные решения для
bash
,ksh
,zsh
, в том числе кросс-оболочка один, плюс достаточно надежный POSIX-совместимые решения :Приведенные номера версий - это те, на которых была проверена функциональность - вероятно, эти решения работают и на гораздо более ранних версиях - обратная связь приветствуется .
Используя только функции POSIX (например, in
dash
, который действует как/bin/sh
в Ubuntu), не существует надежного способа определить, идет ли сценарий из источника - для получения наилучшего приближения см. Ниже .Последующие строки - пояснение ниже; версия с несколькими оболочками сложна, но она должна работать надежно:
bash (проверено в 3.57 и 4.4.19)
ksh (проверено на 93u +)
zsh (проверено на 5.0.5) - обязательно вызовите это вне функции
поперечная оболочка (bash, ksh, zsh)
POSIX-совместимый ; не однострочный (однотрубный) по техническим причинам и не полностью устойчивый (см. внизу):
Объяснение:
удар
Примечание: метод был адаптирован из ответа пользователя user5754163 , поскольку он оказался более надежным, чем исходное решение,
[[ $0 != "$BASH_SOURCE" ]] && sourced=1 || sourced=0
[1]Bash допускает
return
операторы только из функций и, в области видимости верхнего уровня скрипта, только если источник скрипта получен .return
используется в области верхнего уровня сценария без источников , выдается сообщение об ошибке и устанавливается код выхода1
.(return 0 2>/dev/null)
выполняетсяreturn
в подоболочке и подавляет сообщение об ошибке; затем код завершения указывает на то, был ли найденный скрипт (0
) или нет (1
), который используется с&&
и||
операторов , чтобы установитьsourced
переменную , соответственно.return
в области верхнего уровня сценария с исходным кодом приведет к его завершению.0
в качествеreturn
операнда; он отмечает: для каждой подсказкиreturn [N]
: «Если N опущено, возвращается статус последней команды». В результате более ранняя версия [которая использовалась простоreturn
, без операнда] дает неверный результат, если последняя команда в оболочке пользователя имеет ненулевое возвращаемое значение.КШ
Специальная переменная
${.sh.file}
чем-то аналогична$BASH_SOURCE
; обратите внимание, что это${.sh.file}
вызывает синтаксическую ошибку в bash, zsh и dash, поэтому обязательно выполняйте ее условно в сценариях с несколькими оболочками.В отличие от bash,
$0
и${.sh.file}
НЕ гарантируется, что они будут точно идентичными в случае без источников, поскольку это$0
может быть относительный путь, хотя${.sh.file}
он всегда является полным путем, поэтому$0
перед сравнением должен быть разрешен полный путь.ЗШ
$ZSH_EVAL_CONTEXT
содержит информацию о контексте оценки - вызывайте ее вне функции. Внутри исходного сценария [область верхнего уровня]$ZSH_EVAL_CONTEXT
заканчивается на:file
.Оговорка: Внутри команды замены, ЗШ Присоединяет
:cmdsubst
, поэтому тест$ZSH_EVAL_CONTEXT
на:file:cmdsubst$
там.Использование только функций POSIX
Если вы готовы сделать определенные предположения, вы можете сделать разумное, но не надежное предположение о том, что ваш сценарий получен, основываясь на знании двоичных имен файлов оболочек, которые могут выполнять ваш сценарий .
В частности, это означает, что этот подход не работает, если ваш сценарий получен из другого сценария .
Раздел «Как обрабатывать вызовы из источника» в этом моем ответе обсуждает крайние случаи, которые не могут быть обработаны только с помощью функций POSIX.
Это зависит от стандартного поведения
$0
, котороеzsh
, например, не демонстрирует.Таким образом, самый безопасный подход состоит в том, чтобы объединить надежные, специфичные для оболочки методы, описанные выше, с запасным решением для всех оставшихся оболочек.
Наконечник шляпы Стефану Десне и его ответу за вдохновение (преобразование моего выражения оператора через оболочку в
sh
-совместимоеif
выражение и добавление обработчика для других оболочек).[1] user1902689 обнаружил, что
[[ $0 != "$BASH_SOURCE" ]]
дает ложное срабатывание, когда вы выполняете скрипт, расположенный в,$PATH
путем передачи его простого имени файла вbash
двоичный файл; Например,bash my-script
потому что$0
тогда справедливоmy-script
, тогда как$BASH_SOURCE
это полный путь . В то время как вы обычно не использовать этот метод для вызова скриптов в$PATH
- вы бы просто ссылаться на них напрямую (my-script
) - это является полезным в сочетании с-x
для отладки .источник
После прочтения ответа @ DennisWilliamson, есть некоторые проблемы, см. Ниже:
Как этот вопрос означает КШ и ударесть другая часть в этом ответе, касающаяся КШ... увидеть ниже.
просто удар путь
Давайте попробуем (на лету, потому что bash может ;-):
source
Вместо этого я использую.
для удобства чтения (как.
псевдонимsource
):Обратите внимание, что номер процесса не меняется, пока процесс остается в источнике :
Почему бы не использовать
$_ == $0
сравнениеДля обеспечения многих случаев я начинаю писать настоящий скрипт:
Скопируйте это в файл с именем
testscript
:Теперь мы можем проверить:
Все нормально.
Все нормально.
Но для тестирования скрипта перед добавлением
-x
флага:Или использовать предопределенные переменные:
Это больше не будет работать.
Перемещение комментария с 5-й строки на 6-ю даст более читаемый ответ:
Сильнее: КШ сейчас...
Как я не пользуюсь КШ много, после некоторого прочтения на странице руководства, есть мои попытки:
Скопируйте это в
testfile.ksh
:Чем запустить его два раза:
и увидеть:
Существует некоторая переменная, унаследованная в исходном цикле, но ничего действительно не связанная ...
Вы могли бы даже проверить, что
$SECONDS
близко0.000
, но это гарантирует только ручные источники ...Вы даже можете попытаться проверить, кто является родителем:
Поместите это в свой
testfile.ksh
:чем:
или
ps ho cmd $PPID
, но эта работа только для одного уровня subsessions ...Извините, я не мог найти надежный способ сделать это, под КШ,
источник
[ "$0" = "$BASH_SOURCE" ] || [ -z "$BASH_SOURCE" ]
для скриптов читайте через pipe (cat script | bash
)..
это не псевдонимsource
, а наоборот.source somescript.sh
это Bash-ism и не переносимый,. somescript.sh
это POSIX и переносимый IIRC.BASH_SOURCE[]
Ответ (Баш-3,0 и выше) кажется простым, хотяBASH_SOURCE[]
это не документирован для работы вне тела функции (это в настоящее время происходит на работу, в несогласии со страницей человека).Самый надежный способ, как предлагает Wirawan Purwanto, - это проверка
FUNCNAME[1]
внутри функции :Затем:
Это эквивалентно проверке вывода
caller
значенийmain
иsource
различению контекста вызывающего. ИспользованиеFUNCNAME[]
экономит вам захват и анализcaller
выходных данных. Вы должны знать или рассчитать локальную глубину вызова, чтобы быть правильной, хотя. Случаи, подобные сценарию, полученному из другой функции или сценария, приведут к тому, что массив (стек) будет глубже. (FUNCNAME
это специальная переменная массива bash, она должна иметь смежные индексы, соответствующие стеку вызовов, если это не такunset
).(В bash-4.2 и позже вы можете использовать более простую форму
${FUNCNAME[-1]}
вместо последнего элемента в массиве. Улучшено и упрощено благодаря комментарию Денниса Уильямсона ниже.)Тем не менее, ваша проблема как заявлено: « У меня есть скрипт, в котором я не хочу, чтобы он вызывал« выход », если он получен ». Общая
bash
идиома для этой ситуации:Если сценарий получен, он
return
прервет исходный сценарий и вернется к вызывающей стороне.Если сценарий выполняется, он
return
вернет ошибку (перенаправлено) иexit
завершит работу сценария в обычном режиме. Обаreturn
иexit
могут взять код выхода, если требуется.К сожалению, это не работает в
ksh
(по крайней мере, не в производной версии AT & T, которую я имею здесь), оно рассматриваетсяreturn
как эквивалент,exit
если вызывается вне функции или скрипта с точечным источником.Обновлено : в современных версиях вы можете
ksh
проверить специальную переменную, для.sh.level
которой задана глубина вызова функции. Для вызванного скрипта это будет изначально не установлено, для скрипта с точечным источником будет установлено значение 1.Это не так надежно, как версия bash, вы должны вызывать
issourced()
в файле, который вы тестируете, на верхнем уровне или с известной глубиной функции.(Вас также может заинтересовать этот код на github, который использует функцию
ksh
дисциплины и некоторые хитрости для отладки ловушек для эмуляцииFUNCNAME
массива bash .)Канонический ответ здесь: http://mywiki.wooledge.org/BashFAQ/109 также предлагает в
$-
качестве еще одного (хотя и несовершенного) индикатора состояния оболочки.Ноты:
FUNCNAME[]
но пока проверяется только последний элемент в этом массиве, нет никакой неоднозначности.pdksh
. Самое близкое, что я могу найти, относится только к томуpdksh
, где каждый источник скрипта открывает новый дескриптор файла (начиная с 10 для оригинального скрипта). Почти наверняка не то, на что вы хотите положиться ...источник
${FUNCNAME[(( ${#FUNCNAME[@]} - 1 ))]}
получения последнего (нижнего) элемента в стеке? Тогда тестирование на «основной» (отрицание для ОП) было для меня самым надежным.PROMPT_COMMAND
набор, он отображается как последний индексFUNCNAME
массива, если я запускаюsource sourcetest.sh
. Обращая чек (ищем вmain
качестве последнего индекса) кажется более надежным:is_main() { [[ ${FUNCNAME[@]: -1} == "main" ]]; }
.FUNCNAME
это доступно только в функциях. Согласно моим тестамdeclare -p FUNCNAME
,bash
ведет себя по-разному. v4.3 выдает ошибку за пределами функций, а v4.4 выдаетdeclare -a FUNCNAME
. Оба (!) Возвращаютmain
for${FUNCNAME[0]}
в основной скрипт (если он выполняется), пока$FUNCNAME
ничего не дает. И: Есть так много сценариев "ab", использующих$BASH_SOURCE
внешние функции, что я сомневаюсь, что это может или будет изменено.Примечание редактора: решение этого ответа работает надежно, но - только
bash
. Это может быть упрощено до(return 2>/dev/null)
.TL; DR
Попробуйте выполнить
return
заявление. Если сценарий не получен, это вызовет ошибку. Вы можете поймать эту ошибку и продолжить, как вам нужно.Поместите это в файл и назовите его, скажем, test.sh:
Выполните это напрямую:
Источник это:
Для меня это работает в Zsh и Bash.
объяснение
return
Заявление вызовет ошибку , если вы пытаетесь выполнить его вне функции или если сценарий не получен. Попробуйте это из командной строки:Вам не нужно видеть это сообщение об ошибке, поэтому вы можете перенаправить вывод в dev / null:
Теперь проверьте код выхода. 0 означает, что все в порядке (ошибок не было), 1 означает, что произошла ошибка:
Вы также хотите выполнить
return
инструкцию внутри вложенной оболочки. Когдаreturn
оператор запускает его. , , хорошо . , , возвращается. Если вы выполните его в под-оболочке, он вернется из этой под-оболочки, а не из вашего скрипта. Чтобы выполнить в под-оболочке, оберните его$(...)
:Теперь вы можете увидеть код завершения вложенной оболочки, который должен быть 1, потому что внутри вложенной оболочки возникла ошибка:
источник
$ readlink $(which sh)
dash
$ . test.sh
This script is sourced.
$ ./test.sh
This script is sourced.
return
делать на верхнем уровне ( pubs.opengroup.org/onlinepubs/9699919799/utilities/… ). Вdash
оболочках лечатreturn
на верхнем уровнеexit
. Другие оболочки любятbash
илиzsh
не допускаютreturn
на верхнем уровне, что является особенностью подобной техники.$
перед оболочкой. То есть используйте(return >/dev/null 2>&1)
вместо$(return >/dev/null 2>&1)
- но тогда он перестает работать в bash.dash
, где это решение не работает, действует какsh
на Ubuntu, например, это решение не вообще работать сsh
. Решение работает для меня в Bash 3.2.57 и 4.4.5 - с или без$
ранее(...)
(хотя для этого никогда нет веских причин$
).return
При отсутствии скрипта возвращаемое значение explcit обрывается приsource
создании скриптов. Предложено улучшение редактирования.FWIW, прочитав все остальные ответы, я нашел следующее решение для меня:
Это работает для всех сценариев, которые начинаются с,
#!/bin/bash
но могут быть получены из различных оболочек, а также для изучения некоторой информации (например, настроек), которая хранится внеmain
функции.Вместо последних двух строк вы можете использовать следующий (на мой взгляд, менее читаемый) код, чтобы не устанавливать его
BASH_SOURCE
в других оболочках и разрешатьset -e
работать вmain
:Этот скрипт-рецепт имеет следующие свойства:
Если выполняется
bash
обычным способом,main
называется. Обратите внимание, что это не включает в себя вызов, какbash -x script
(гдеscript
не содержит путь), см. Ниже.Если источник
bash
,main
вызывается, только если вызывающий скрипт имеет одно и то же имя. (Например, если это источник или сам,bash -c 'someotherscript "$@"' main-script args..
гдеmain-script
должен быть, то, чтоtest
видит как$BASH_SOURCE
).Если источник / выполнен / прочитан /
eval
отредактирован оболочкой, отличной отbash
,main
неBASH_SOURCE
вызывается ( всегда отличается от$0
).main
не вызывается, еслиbash
читает сценарий из stdin, если вы не установили$0
пустую строку, например:( exec -a '' /bin/bash ) <script
Если это выполняется
bash
с помощьюeval
(eval "`cat script`"
все кавычки важны! ) Из другого скрипта, это вызываетmain
. Еслиeval
он запускается непосредственно из командной строки, это аналогично предыдущему случаю, когда скрипт читается из стандартного ввода. (BASH_SOURCE
пусто, хотя$0
обычно/bin/bash
если не принуждено к чему-то совершенно другому.)Если
main
не вызывается, он возвращаетtrue
($?=0
).Это не зависит от неожиданного поведения (ранее я писал недокументированное, но я не нашел документации, которую вы не можете
unset
ни изменить, ни изменитьBASH_SOURCE
):BASH_SOURCE
является Баш зарезервирован массив . Но разрешениеBASH_SOURCE=".$0"
изменить его открыло бы очень опасную банку червей, поэтому я ожидаю, что это не должно иметь никакого эффекта (за исключением, возможно, какого-то ужасного предупреждения, которое появится в какой-то будущей версииbash
).BASH_SOURCE
работала вне функций. Однако обратное (то, что он работает только в функциях) не задокументировано. Наблюдение состоит в том, что это работает (протестировано сbash
v4.3 и v4.4, к сожалению, у меня больше нетbash
v3.x), и что слишком много сценариев сломалось бы, если$BASH_SOURCE
перестало работать, как наблюдалось. Следовательно, я ожидаю, что онаBASH_SOURCE
останется такой же и для будущих версийbash
.( return 0 )
, что дает,0
если получены и1
если не получены. Это приходит немного неожиданно не только для меня , и (согласно показаниям там) POSIX говорит, чтоreturn
от subshell есть неопределенное поведение (аreturn
здесь явно от подоболочек). Возможно, эта функция в конечном итоге получит достаточно широкое использование, так что ее уже нельзя будет изменить, но AFAICS имеет гораздо более высокий шанс того, что какая-то будущаяbash
версия случайно изменит поведение возврата в этом случае.К сожалению
bash -x script 1 2 3
, не работаетmain
. (Сравните,script 1 2 3
гдеscript
нет пути). Следующее может быть использовано в качестве обходного пути:bash -x "`which script`" 1 2 3
bash -xc '. script' "`which script`" 1 2 3
bash script 1 2 3
что не работает,main
можно считать особенностью.Обратите внимание, что
( exec -a none script )
вызовыmain
(bash
не передаются$0
в сценарий, для этого вам нужно использовать,-c
как показано в последнем пункте).Таким образом, за исключением некоторых некоторых угловых случаев,
main
вызывается только тогда, когда скрипт выполняется обычным способом. Обычно это то, что вы хотите, особенно потому , что ему не хватает сложного, трудного для понимания кода.Почему я думаю, что это хороший общий способ решения проблемы
Если у вас есть что-то, что может быть получено из нескольких оболочек, это должно быть совместимо. Однако (прочитайте другие ответы), поскольку не существует (легко реализуемого) переносимого способа обнаружения данных
source
, вам следует изменить правила .Обеспечивая выполнение сценария
/bin/bash
, вы точно делаете это.Это решает все случаи, кроме следующих: в этом случае скрипт не может работать напрямую:
/bin/bash
не установлен или не работает (т.е. в среде загрузки)curl https://example.com/script | $SHELL
bash
продукт достаточно свежий. Сообщается, что этот рецепт не подходит для некоторых вариантов. Поэтому убедитесь, что он работает для вашего случая.)Однако я не могу думать ни о какой реальной причине, где вам это нужно, а также о возможности параллельно создавать один и тот же сценарий! Обычно вы можете обернуть его, чтобы выполнить
main
вручную. Как это:$SHELL -c '. script && main'
{ curl https://example.com/script && echo && echo main; } | $SHELL
$SHELL -c 'eval "`curl https://example.com/script`" && main'
echo 'eval "`curl https://example.com/script`" && main' | $SHELL
Ноты
Этот ответ не был бы возможен без помощи всех других ответов! Даже неправильные - которые изначально заставили меня опубликовать это.
Обновление: отредактировано из-за новых открытий, найденных в https://stackoverflow.com/a/28776166/490291
источник
/bin/sh
эффективно находитсяbash
в режиме POSIX, сопоставляяBASH_SOURCE
брейков сценарий. В других оболочках (dash
,ksh
,zsh
), ссылаясь на свой скрипт, передав его в качестве файлового аргумента непосредственно к оболочке исполняемым неисправностям (например,zsh <your-script>
сделает ваш сценарий ошибочно думать , что это источники ). (Вы уже отметить , что обжигающе неисправность , код во всех оболочках.). <your-script>
(sourcing) в принципе работает из всех POSIX-подобных оболочек, имеет смысл только, если сценарий явно написан для использования только функций POSIX, чтобы предотвратить прерывание выполнения функциями, специфичными для одной оболочки. в других снарядах; поэтому использование линии Bash Shebang (а не#!/bin/sh
) сбивает с толку - по крайней мере, без заметного комментария. И наоборот, если ваш сценарий предназначен для запуска только из Bash (даже если только из-за того, что он не учитывает, какие функции могут быть не переносимыми), лучше отказаться от выполнения в оболочках, отличных от Bash.main
, но он делает это в этом случае! И когда источником является то/bin/sh
, чтоbash --posix
то же самое происходит в этом случае, и это также явно неправильно.Это работает позже в скрипте и не зависит от переменной _:
или
источник
Я дам BASH-специфичный ответ. Корн скорлупа, извините. Предположим, что ваш скрипт называется
include2.sh
; затем сделать функцию внутриinclude2.sh
называетсяam_I_sourced
. Вот моя демо-версияinclude2.sh
:Теперь попробуйте выполнить это многими способами:
Так что это работает без исключения и не использует хрупкие
$_
вещи. Этот трюк использует средство самоанализа BASH, то есть встроенные переменныеFUNCNAME
иBASH_SOURCE
; см. их документацию на странице руководства bash.Только два предостережения:
1) вызов
am_I_called
должен выполняться в исходном скрипте, но не внутри какой-либо функции, чтобы не${FUNCNAME[1]}
возвращалось что-то еще. Да ... ты мог бы проверить${FUNCNAME[2]}
- но ты просто усложнил свою жизнь.2) функция
am_I_called
должна находиться в исходном скрипте, если вы хотите узнать, какое имя включаемого файла.источник
Я хотел бы предложить небольшую поправку к очень полезному ответу Денниса , чтобы сделать его немного более портативным, я надеюсь:
потому что
[[
не распознается (несколько анального удерживающий ИМХО) Debian POSIX совместимой оболочкой,dash
. Кроме того, могут потребоваться кавычки для защиты от имен файлов, содержащих пробелы, опять же в указанной оболочке.источник
$_
довольно хрупкий Вы должны проверить это как первое, что вы делаете в сценарии. И даже в этом случае не обязательно будет содержать имя вашей оболочки (если оно получено) или имя скрипта (если оно выполнено).Например, если пользователь установил
BASH_ENV
, то в верхней части скрипта$_
содержится имя последней команды, выполненной вBASH_ENV
скрипте.Лучший способ, который я нашел, это использовать
$0
так:К сожалению, этот способ не работает из коробки в zsh из-за того, что
functionargzero
опция делает больше, чем предполагает ее имя, и включена по умолчанию.Чтобы обойти это, я вставил
unsetopt functionargzero
свой.zshenv
.источник
Я следовал за компактным выражением mklement0 .
Это здорово, но я заметил, что он может потерпеть неудачу в случае ksh, когда вызывается так:
(он думает, что это источник, и это не потому, что он выполняет подоболочку) Но выражение будет работать, чтобы обнаружить это:
Кроме того, даже если выражение компактно, синтаксис не совместим со всеми оболочками.
Итак, я закончил со следующим кодом, который работает для bash, zsh, dash и ksh
Не стесняйтесь добавлять поддержку экзотических оболочек :)
источник
ksh 93+u
,ksh ./myscript.sh
прекрасно работает для меня (с моим заявлением) - какую версию вы используете?/proc/$$/cmdline
) и фокусируетсяdash
только на ней (которая также действует, какsh
, например, в Ubuntu). Если вы готовы сделать определенные предположения, вы можете проверить$0
приемлемый, но неполный тест, который является переносимым.sh
/,dash
также, в добавлении к моему ответу.Я не думаю, что есть какой-либо переносимый способ сделать это как в ksh, так и в bash. В bash вы можете обнаружить это, используя
caller
выходные данные, но я не думаю, что в ksh существует эквивалент.источник
$0
работаетbash
,ksh93
иpdksh
. Мне не нужноksh88
проверять.Мне нужна была одна строка, которая работает на [mac, linux] с bash.version> = 3, и ни один из этих ответов не отвечал всем требованиям.
источник
bash
Решение работает хорошо (можно упростить$BASH_SOURCE
), ноksh
решение не является надежным: если ваш скрипт быть получен по другому сценарию , вы получите ложную положительный результат .Прямо к делу: вы должны оценить, равна ли переменная «$ 0» названию вашей оболочки.
Как это:
Через ОБОЛОЧКУ :
Через ИСТОЧНИК :
Довольно сложно иметь 100% -ый портативный способ определения, был ли скрипт создан или нет.
Что касается моего опыта (7 лет с Shellscripting) , единственным безопасным способом (не полагаясь на переменные окружения с PID и т. Д., Который небезопасен из-за того, что это что-то переменное ), вы должны:
Оба параметра не могут быть автоматически масштабированы, но это более безопасный способ.
Например:
при создании сценария через сеанс SSH значением, возвращаемым переменной «$ 0» (при использовании источника ), является -bash .
ИЛИ
источник
/bin/bash -c '. ./check_source.sh'
даетThe script WAS NOT sourced.
. Та же ошибка:ln -s /bin/bash pumuckl; ./pumuckl -c '. ./check_source.sh'
->The script WAS NOT sourced.
Я закончил с проверкой
[[ $_ == "$(type -p "$0")" ]]
При использовании
curl ... | bash -s -- ARGS
для запуска удаленного сценария «на лету», $ 0 будет простоbash
вместо обычного/bin/bash
при запуске реального файла сценария, поэтому я использую,type -p "$0"
чтобы показать полный путь bash.тест:
источник
Это ответ на некоторые другие ответы, касающиеся «универсальной» поддержки кросс-оболочек. По общему признанию это очень похоже на https://stackoverflow.com/a/2942183/3220983 в частности, хотя немного отличается. Недостатком этого является то, что клиентский скрипт должен учитывать, как его использовать (т.е. сначала экспортировать переменную). Сила в том, что это просто и должно работать "где угодно". Вот шаблон для вашего удовольствия:
Примечание: я использую
export
только для того, чтобы этот механизм можно было распространить на подпроцессы.источник