Related: Which shell interpreter runs a script with no shebang?
The script does not have a shebang/hashbang/#!
line, simply because a double dash is not #!
.
However, the script will be executed by a shell (see above linked question and answers), and in that shell, if -
is a valid character in a function name, the line declares a shell function called --
that does nothing (well, it runs :
, which does nothing) and which is never called.
The function, in the more common multi-line notation (just to make it more obvious what it looks like, as its odd name kinda obscures the fact that it's in fact a function):
-- () {
:
}
The sole purpose of the function definition is to have a line that is valid in a shell script and at the same time a valid SQL command (a comment). This sort of code is called a polyglot.
After declaring the bogus shell function, the script, when executed by a shell script interpreter, uses exec
to replace the current shell with the process resulting from running db2 -txf "$0"
, which would be the same as using db2 -txf
on the pathname of the script from the command line.
This trick would probably not work reliably on systems where dash
or other ash
-based shells, yash
, the Bourne shell, ksh88
or ksh93
is used as /bin/sh
, as these shell do not accept functions whose name contains dashes.
Also related:
I suppose the following would also work (not really tested):
--() { exec db2 -txf "$0"; }; --
ENOEXEC
if you try to. Try running the script understrace
to see what I mean. – kasperd Dec 15 '18 at 13:40exec()
doesn't work on it. "If the execl() function fails due to an error equivalent to the [ENOEXEC] error, the shell shall execute a command equivalent to having a shell invoked with the command name as its first operand, ... " (see http://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/V3_chap02.html#tag_18_09_01_01) – ilkkachu Dec 15 '18 at 14:13exec()
it directly from something other than a shell. But what would that case be? You might want to run the script fromcron
or such, but I think it runs everything through a shell anyway, and even if not, it's easy to just spell outdb2 -txf /path/to/script
in that case, since you only need to do it once. Having the shorthand work is mostly useful on an interactive shell. But sure, a separate wrapper script might be more robust. – ilkkachu Dec 15 '18 at 15:01execvp
andexeclp
library functions (which means that it could be used withxargs
,find
, etc). You're either completely missing the point ("a script which is valid as either shell or sql") or have some kind of agenda (you don't think the wayexecvp
works is "right", so any use of it should be "invalid"). It doesn't matter if strace cannot run it directly; neither can gdb, so what? – Dec 15 '18 at 19:39#! /bin/cmd
) are in any way standard you're sorely mistaken; using execvp or execlp is the only way to portably run an executable script. – Dec 15 '18 at 19:48execvp
orexeclp
run a script with out#!
? They certainly won't on Linux. – kasperd Dec 15 '18 at 21:45echo '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` – Dec 16 '18 at 00:00p
variants which have this behavior though. So a script without#!
still won't be a substitute for an executable if it is called through any of the other functions. – kasperd Dec 16 '18 at 00:49