[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Feature suggestion: env --nopath
From: |
Simon Tatham |
Subject: |
Feature suggestion: env --nopath |
Date: |
Fri, 22 Nov 2024 14:15:54 +0000 |
User-agent: |
Sup/git |
I think it would be useful if 'env' had an option which would cause it
to treat its COMMAND argument as _necessarily_ a pathname to an
executable file, rather than the usual semantics of considering it to be
either that or a command to search for on PATH.
In other words, to run the command using execv() rather than execvp().
For the discussion below I've spelled the option "--nopath", but that
was just the first thing that sprang to mind. I have no strong opinion
on whether that's the right name.
Why it's useful at all
----------------------
This option would be useful in any situation where you know the exact
location of the executable file you want to run, via some pathname that
might be either absolute or relative.
As an example, suppose a shell script has a variable $script containing
a location where it wants to _create_ a secondary script, and then
immediately run it from the same place, along the lines of
sed 'some sed commands' script.template > "$script"
chmod +x "$script"
env --nopath "$script" "arguments"
With the suggested --nopath option, this works equally well if the
variable $script is a bare name, a cwd-relative path, or an absolute
path. The two other obvious ways to run the script fail in at least one
of those cases:
- "$script" by itself treats a bare name wrongly, either failing to
execute anything at all, or worse, finding an unrelated thing of the
same name on PATH
- "./$script" fails if $script is an absolute path, accidentally
turning it into a relative one, because the initial ".//" is treated
the same as "./" by the kernel.
Another use case for the same kind of thing is a Makefile rule that
wants to run a program from the source tree:
output-file: script.py
env --nopath $< -o $@
This method of running the script would work equally well if 'make' is
run in the source tree so that $< expands to the plain filename, or if
it's run from out of tree using VPATH so that $< expands to an absolute
path. Without env --nopath, I don't know of any convenient way to make
both cases work at once. As far as I can see the current options are to
mess about with 'realpath', or to check the pathname for an initial '/'
first and split into two cases.
Why I think it fits in 'env'
----------------------------
The 'env' utility already has several options that don't directly relate
to modifying the environment of the executed program. --chdir modifies
its cwd, and -a modifies its argv[0]. It seems like more of a general
tool for 'execute my program in a custom way' than the name suggests. I
think --nopath would go well with those other options.
Also, if I want to run a program by its filename, I may well want to
customise its execution in some of these other ways too, so it's helpful
to have them all together, minimising further execs.
The necessary code change
-------------------------
As far as I can see, the behaviour change itself is a one-liner. It's
enough to turn the execvp() call into execv() at the end of env's
main(). The bulk of the patch would be adding the command-line option to
select it, and updating the help and man page.
I haven't written the actual patch, because I understand that
contributing it myself will require copyright assignment to the FSF, and
I'd rather find out first whether it's worth doing the paperwork. But
I'm happy to start that process if I get a positive response.
Cheers,
Simon
--
for k in [pow(x,37,0x1a1298d262b49c895d47f) for x in [0x50deb914257022de7fff,
0x213558f2215127d5a2d1, 0x90c99e86d08b91218630, 0x109f3d0cfbf640c0beee7,
0xc83e01379a5fbec5fdd1, 0x19d3d70a8d567e388600e, 0x534e2f6e8a4a33155123]]:
print("".join([chr(32+3*((k>>x)&1))for x in range(79)])) # <anakin@pobox.com>
- Feature suggestion: env --nopath,
Simon Tatham <=