The content of this article does not apply to Windows at all.
Confirmed on Linux (Debian stretch) / macOS (10.14).
According to https://linuxjm.osdn.jp/html/LDP_man-pages/man3/exec.3.html etc., only execvp has a function to interpret it as a shell script when ENOEXEC occurs. Will this feature work if I run an external program in a scripting language without a shell?
$ cat lsscript
ls
Ruby
--Direct execution (example): popen argument is an array, system argument is 2 or more elements
ruby -e 'p IO.popen(["./lsscript"]).read'
process.c proc_exec_cmd Try execve, add / bin / sh for ENOEXEC and try again
Python
--Direct execution (example): The argument of check_call (etc.) is an array
python -c 'import subprocess;subprocess.check_call(["./lsscript"])'
Modules/_posixsubprocess.c child_exec Try execve. ** Fail for ENOEXEC **
The same is true for Python 3. If shell = True, it will not fail, but pipes.quote and shlex.quote are required. (If you are a reader of this article, you know the need for this)
Perl
--Direct execution (example): Two or more elements of system () argument
perl -e 'print system("./lsscript","dummy")'
doio.c Perl_do_aexec5 Try execvp.
PHP
--Direct execution: pcntl_exec
php -r 'pcntl_exec("./lsscript");'
ext/pcntl/pcntl.c pcntl_exec Try execve. ** Fail for ENOEXEC **
(Because the above is exec, you need to call fork etc. to make it a subprocess. There is a standard execution system in ext / standard / exec.c that does not need that side, but it seems to be fixed to popen (that is, a shell is always included))
When I try to execute it in Python / PHP without going through the shell, sh is not added automatically. Please be careful when throwing C language shebang-like.