Shebang-less executable scripts do not run, but only on one system...

On my current system, running FreeBSD 11.1-RELEASE-p3, does not seem to want to let me run shebang-less executable scripts, even though a freshly installed FreeBSD in a VM will do so (and I can run them just fine on my server, which is also running FreeBSD 11.1-RELEASE-p3).

I created a dummy script, named test.sh, with a single line of echo "Hello world!" in it. If I run the script on a working FreeBSD system with ./test.sh, it correctly runs and outputs Hello world! as expected.

However, my current system does not. If I try to run the script the same way with my current shell, csh, it tells me Command not found., whereas if I go into sh and do the same thing, it tells me not found. If I run the script with sh ./test.sh, it runs as expected.

I have been unable to determine why this is happening, I cannot find any sort of issue with my environment causing it. But, I have a theory that may or may not be the reason. I have emulators/qemu-user-static installed on my system, and when I do binmiscctl list, along with the entries added by qemu-user-static's rc.d script, there is another entry with no name, no interpretter, set to enabled, with a magic size of 0, no magic and no mask. I don't get this inside a VM after installing qemu-user-static inside of it, so I don't know where this extra entry is coming from.
 
Put the she-bang line in there. That avoids any ambiguity (it might be a shell script, but which shell?). I'm actually surprised it sometimes works without it. So I'd avoid that in all cases.
 
That would be a great solution, but that doesn't help when I'm building software (typically a port) who's source tarball contains scripts that don't have a shebang in them but are being expected to run anyways.
 
It will depend how those scripts are started. Most of the rc(8) scripts for example don't need them because they're all sourced by another script. But you cannot expect a script to run 'stand-alone' without the shebang line. As I said, which shell should it run on? Bash? Bourne shell? C-shell? Zshell? Not all of them are compatible, you can run bourne shell scripts on Bash but not the other way around. Bourne shell scripts will not run on C-shell and vise versa. So simply assuming it will "automagically" do the right thing is the wrong solution.
 
Believe me, I understand that scripts lacking a shebang result in ambiguity in how they should run. I believe FreeBSD doesn't 100% conform to POSIX (I could be wrong on this), but what I've read says that POSIX says it will execute a the script as if it had been run by the shell, although one Stack Overflow answer says that while bash will run the scripts itself, zsh will invoke sh to run the script.

In any case, I decided to check on that theory I listed at the end of my original post, by running binmiscctl remove "" to get rid of that extra entry in binmiscctl's list. And once I did that, I could run the shebang-less script correctly. I'm still not sure where the empty entry is coming from, though, as I don't see it come up anywhere else, unless the system caches entries in the binmiscctl list between boots and it was somehow there previously.
 
Why do you believe that FreeBSD does not conform to Posix?

Ultimately, when you run any program, it will be started by execve(2). That is specified by Posix: either the file to be executed is executable (such as an elf or a.out file), or it shall be input for an interpreter, specified in a she-bang line. Tertium non datur as far as standards are concerned, at the system call level of Posix.

It is true that Unixes have, as a convenience, run files that look like shell scripts and don't have the magic for binary formats as shell scripts, with the default system shell. I don't know whether Posix makes that mandatory, or even talks about it (never looked at that level of detail).
 
Back
Top