On 26/04/18 00:17, Assaf Gordon wrote:
> Hello,
>
> Attached an updated patch, hopefully addressing all the issues below.
> Initial documentation also included (seperated into several commits to ease
> review).
>
> A rendered html page is available here:
> http://housegordon.org/files//tmp/env-invocation.html
>
> It's rather long, but I hope it is helpful and justified, to address
> all sorts of subtleties with examples.
Excellent.
> I also added a short blurb to the man page, mentioning the
> "-S" option and directing to the full documentation for details.
>
> On Tue, Apr 24, 2018 at 10:09:41PM -0700, Pádraig Brady wrote:
>>>> For example it looks buggy that -u TERM
>>>> is just ignored in this example:
>>>>
>>>> src/env -v -u TERM -S sh -c "echo \$TERM"
>
> This is fixed now. It requried a minor change to the 'unset' flow,
> which is done in the first commit. Review welcomed.
>
>> Well according to the FreeBSD docs it should output 'xAAAx ==' in both cases.
>> I'd have a slight preference for being consistent there rather than being
>> bug for bug compat with FreeBSD here.
>
> The code now behaves in the above consistent way, and thus deviate from
> FreeBSD in this respect.
>
>>>> Another gotcha is that portably specifying -v
>>>> with -S (i.e. with only one option) requires:
>>>> src/env '-vS sh -c "echo \$TERM"'
> [...]
>>>> So I would document two forms in the man page/--help like:
>>>>
>>>> env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
>>>> env -[v]S '[OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]'
>
> The 'usage' has been updated, and I also added explicit
> section about it in the documentation.
>
>>>> and make it clear usage() that -S is only needed with shebang lines.
>>>> The quotes above are important to document too,
>>>> as otherwise consistent processing (like interpolation etc.) wouldn't
>>>> be done on operating systems that did split shebangs
>>>> (or when used in a standard command invocation).
>
> The quotes are tricky: they are needed when running 'env -S' on the command
> line,
> but should not be used on a shebang line.
>
> For example, the following results in an infloop (both on FreeBSD and in my
> implementation):
>
> $ cat bad.sh
> #!/usr/bin/env -S'A=B uname'
>
> This is because the kernel already passes -S'A=B uname' as a single argument,
> and then env sees the single-quotes. It then sets the envar "A" to the value
> of "B uname". lastly, the kernel adds "./bad.sh" as the last parameter.
> The result is that 'env' sets envvar "A" and runs "bad.sh" again... forever.
>
> So when using 'env -S' on the command line - use quotes.
> When using 'env -S' in a shebang line - don't use quotes (unless
> when explicitly setting values that contain spaces).
>
> I have added an explicit section about this in the documentation.
OK all this is very subtle.
Thanks for documenting and matching FreeBSD.
We might consider in future having -S process subsequent parameters
so that scripts would be portable to systems that presplit shebang lines.
Let's not over engineer for now.
Scripts wouldn't be portable when using /usr/bin/env on these systems anyway
as MacOS currently doesn't support -S.
Given -S'with quotes' is only used for debugging
outside the shebang context, and that debugging mode is
adequately documented in the info docs, let's remove the
separate -S mode from the synopsis. I've done that
and also tweaked the -S explanation a little wrt punctuation.
I also removed exdent from the info as my texinfo version
warns about it, and added static to the two new vars
as indicated by make syntax-check.
All tweaks are attached.
> Lastly, this update does not yet address Kaz's suggestion
> of having a placeholder for the command-line arguments.
>
> I understand this might be useful in some cases, but I'm
> not sure we want to create yet another GNU extension (compared to FreeBSD).
If we do we should probably do it in a separate patch anyway.
> Are there concrete cases where the interpreter (like awk)
> requires argument in specific order, and the script filename
> can't be last?
>
> For example in this case:
>
> #!/usr/bin/env -S lang -f ${ENV_COMMAND} -x
>
> Would 'lang' fail to execute if we just reorder it like:
>
> #!/usr/bin/env -S lang -x -f
Yes, lang may fail with -x not supported,
or if lang did support -x it would not pass it on to the script.
Though as mentioned previously one can use ${_} to
get awk to behave appropriately.
anyway for future consideration.
thank you!
Pádraig
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 332896d..d568bab 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -16902,7 +16902,7 @@ env -[v]S'[@var{option}]@dots{} [@var{name}=@var{value}]@dots{} @c
env
@end example
-@exdent @command{env} is commonly used on first line of scripts (shebang line):
+@command{env} is commonly used on first line of scripts (shebang line):
@example
#!/usr/bin/env @var{command}
#!/usr/bin/env -[v]S[@var{option}]@dots{} [@var{name}=@var{value}]@dots{} @c
diff --git a/src/env.c b/src/env.c
index 68dcf88..53d2934 100644
--- a/src/env.c
+++ b/src/env.c
@@ -37,8 +37,8 @@
/* array of envvars to unset. */
static const char** usvars;
-size_t usvars_alloc;
-size_t usvars_used;
+static size_t usvars_alloc;
+static size_t usvars_used;
/* Annotate the output with extra info to aid the user. */
static bool dev_debug;
@@ -68,10 +68,7 @@ usage (int status)
else
{
printf (_("\
-Usage: %s [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]\n"),
- program_name);
- printf (_("\
- or: %s -[v]S'[OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]'\n"),
+Usage: %s [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]\n"),
program_name);
fputs (_("\
Set each NAME to VALUE in the environment and run COMMAND.\n\
@@ -88,8 +85,8 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\
-C, --chdir=DIR change working directory to DIR\n\
"), stdout);
fputs (_("\
- -S, --split-string=S process and split S into separate arguments\n\
- used to pass multiple arguments on shebang lines\n\
+ -S, --split-string=S process and split S into separate arguments;\n\
+ used to pass multiple arguments on shebang lines\n\
-v, --debug print verbose information for each processing step\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);