Связанный: Какой интерпретатор оболочки выполняет сценарий без Шебанга?
Скрипт не имеет #!
строки shebang / hashbang / , просто потому что двойной тире нет #!
.
Однако сценарий будет выполняться оболочкой (см. Выше связанный вопрос и ответы), и в этой оболочке, если -
допустимый символ в имени функции, строка объявляет вызываемую функцию оболочки --
, которая ничего не делает (хорошо, она запускается :
, который ничего не делает ) и который никогда не называется.
Функция в более распространенной многострочной нотации (просто чтобы сделать ее более очевидной, как она выглядит, так как ее нечетное имя как бы скрывает тот факт, что это на самом деле функция):
-- () {
:
}
Единственная цель определения функции - иметь строку, которая действительна в сценарии оболочки и в то же время является допустимой командой SQL (комментарий). Этот вид кода называется полиглотом .
После объявления фиктивной функции оболочки сценарий при выполнении интерпретатором сценария оболочки использует exec
для замены текущей оболочки процесс, полученный в результате выполненияdb2 -txf "$0"
, который будет аналогичен использованию db2 -txf
в имени пути сценария из командной строки.
Этот трюк, вероятно, не будет надежно работать в системах, где используются dash
или другие ash
оболочки на основе, оболочка yash
Борна ksh88
или ksh93
используется как/bin/sh
, поскольку эти оболочки не принимают функции, имя которых содержит тире.
Также связано:
Я полагаю, что следующее также будет работать (не проверено):
--() { exec db2 -txf "$0"; }; --
Как уже сказал @Kusalananda, этот трюк сломан, и он не будет работать во всех оболочках.
Вот мой взгляд на это:
Первая команда должна завершиться ошибкой, даже если файл / каталог с именем
--
в текущем каталоге существует указанный каталог и любые ошибки будут закрыты командой2>/dev/null
; Затем оболочка продолжит выполнение второй командыexec
.источник
ENOEXEC
если вы попытаетесь это сделать. Попробуйте запустить скрипт,strace
чтобы понять, что я имею в виду.exec()
не работает на нем. «Если функция execl () завершается ошибкой из-за ошибки, эквивалентной ошибке [ENOEXEC], оболочка должна выполнить команду, эквивалентную вызову оболочки с именем команды в качестве первого операнда, ...» (см. Pubs.opengroup .org / onlinepubs / 9699919799.2018 / редакция / утилиты /… )exec()
это непосредственно из чего-то другого, кроме оболочки. Но что это будет за случай? Возможно, вы захотите запустить сценарийcron
или что-то подобное, но я думаю, что он в любом случае запускает все через оболочку, и даже если нет,db2 -txf /path/to/script
в этом случае просто разобраться , так как вам нужно сделать это только один раз. Работа с сокращениями в основном полезна для интерактивной оболочки. Но, конечно, отдельный скрипт-обертка может быть более надежным.echo 'int main(int c,char**a){execvp(a[1],a+1);}' | cc -include unistd.h -xc -; echo echo yeah > a.sh; chmod 755 a.sh; ./a.out ./a.sh; PATH=`pwd` ./a.out a.sh