Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If I may interject, does anyone have any idea why the `-S` flag is required? Testing this out on my machine with a BSD env, `/usr/bin/env -S uv run --python 3.11 python` and `/usr/bin/env uv run --python 3.11 python` do the same thing (launch a Python interactive shell). Man page for env doesn't clarify a lot to me, as the end result still seems to be the same("Split apart the given string into multiple strings, and process each of the resulting strings as separate arguments to the env utility...")


Its needed on my ubuntu 24.04 system

  $ cat test.sh
  #!/usr/bin/env bash -c "echo hello"
  $ ./test.sh
  /usr/bin/env: ‘bash -c "echo hello"’: No such file or directory
  /usr/bin/env: use -[v]S to pass options in shebang lines
  $ ./test.sh # with -S
  hello


Interesting, I guess it is indeed a BSD thing, cause this works for me with or without '-S' on Mac


There currently is a patch for adding '-S' to OpenBSD and in the discussion, the one who came originally up with it commented on how he added it to FreeBSD:

"IIRC, the catalyst for it was that early FreeBSD (1990's?) did split up the words on the '#!' line because that seemed convenient. Years later, someone else noticed that this behavior did not match '#!' processing on any other unix, so they changed the behavior so it would match. Someone else then thought that was a bug, because they had scripts which depended on the earlier behavior. I forget how many times the behavior of '#!' processing bounced back and forth, but I had some scripts which ran on multiple versions of Unix and one of these commits broke one of those scripts.

I read up on all the commit-log history, and fixed '#!' processing one more time so that it matched how other unixes do it, and I think I also left comments in the code for that processing to document that "Yes, '#!'-parsing is really supposed to work this way".

And then in an effort to help those people who depended on the earlier behavior, I implemented '-S' to the 'env' command.

I have no idea how much '-S' is used, but it's been in FreeBSD since June 2005, and somewhere along the line those changes were picked up by MacOS 10. The only linux I work on is RHEL, and it looks like Redhat added '-S' between RHEL7 and RHEL8." [https://marc.info/?l=openbsd-tech&m=175307781323403&w=2]


FWIW, GNU Coreutils env (as seen for example in my Linux Mint distribution) works the same way (no split by default, enabled by `-S`) and I definitely have used it locally to do things like `#!/usr/bin/env -S python -S -I`.



Thanks, but the main question is how come the behaviour is still the same whether you pass the flag or not? I would get it if it just failed without "-S" but it works as intended. I am wondering if this is cause I might not be using the GNU version of env, so this is less relevant? Edit: looks to be the version thing indeed, this doesn't work for someone on Ubuntu


At some point coreutils added -S in order to support the behavior of BSD and MacOS. I would guess that whatever implementation you're using then added -S as a noop in order to (at long last) permit the portable usage of multi-argument shebang lines. Until both of those things happened there was no portable way to pass multiple arguments in a shebang. You used to have to do really stupid things (ex https://unix.stackexchange.com/a/399698).

https://www.gnu.org/software/coreutils/manual/html_node/env-...


Actually, you might be onto something! If I test with explicit quoting in terminal, BSD and GNU produce the same behavior:(`env 'bash -c "echo hello"'` fails while `env -S 'bash -c "echo hello"'`) works. I wasn't aware of this:

"To test env -S on the command line, use single quotes for the -S string to emulate a single parameter. Single quotes are not needed when using env -S in a shebang line on the first line of a script (the operating system already treats it as one argument)"(from your second link).

This is different for shebang on Mac though:

GNU env works with or without '-S':

#!/opt/homebrew/bin/genv -S bash -v

echo "hello world!"

BSD env works with or without '-S' too:

#!/usr/bin/env -S bash -v

echo "hello world!"

To conclude, looks like adding `-S` is the safest option for comparability sake :).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: