On Mon, Jan 22, 2024 at 12:17:12PM +0200, Oğuz wrote: > On Monday, January 22, 2024, Martin D Kealey <mar...@kurahaupo.gen.nz> > wrote: > > > > You seem to have created an invalid executable. It seems that scripts > > without a #! can only be run with help from the debugger library > > > > Hi Martin, POSIX shells interpret such executables as shell scripts, I > don't think bash would take a hacky approach like that for implementing > this basic functionality. It must be something else
Bash attempts to execute the command normally, and when the kernel returns ENOEXEC, bash decides to try a different approach. It opens the file, reads a hundred or so bytes, and scans them for NUL bytes. If it doesn't find a NUL, it forks a subshell of itself, and uses that to read the file as a script. If a NUL is found, bash aborts with an error message. Without a NUL: unicorn:~$ printf 'echo foo' > foo unicorn:~$ strace -f bash -c ./foo execve("/usr/bin/bash", ["bash", "-c", "./foo"], 0x7ffe1badab60 /* 53 vars */) = 0 [...] execve("./foo", ["./foo"], 0x562def3ca230 /* 53 vars */) = -1 ENOEXEC (Exec format error) openat(AT_FDCWD, "./foo", O_RDONLY) = 3 read(3, "echo foo", 128) = 8 close(3) = 0 [...] With a NUL: unicorn:~$ printf 'echo foo\0' > foo unicorn:~$ bash -c ./foo bash: line 1: ./foo: cannot execute binary file: Exec format error I don't currently have a build of bash-5.3 (prerelease) to test the original bug report, so I can neither confirm nor deny it. But in any case, writing a "script" without a shebang and then counting on the shell to work around the broken script is not ideal. You get differing behaviors depending on which shell you're currently in. Bash forks a subshell. Zsh and GNU find fork /bin/sh. Systemd will just report the original error and will not do any workarounds.