Is there a POSIX (or at least a popular) utility to set the current working directory when invoking a program?
AFAIK, there is no such dedicated utility in the POSIX tool chest. But it's common to invoke sh
to set up an environment (cwd, limits, stdout/in/err, umask...) before running a command as you do in your sh
script.
But you don't have to write that script in a file, you can just inline it:
sh -c 'CDPATH= cd -P -- "$1" && shift && exec "$@"' sh /some/dir cmd args
(assuming the directory is not -
). Adding CDPATH=
(in case there's one in the environment) and -P
for it to behave more like a straight chdir()
.
Alternatively, you could use perl
whose chdir()
does a straight chdir()
out of the box.
perl -e 'chdir(shift@ARGV) or die "chdir: $!"; exec @ARGV or die "exec: $!"
' /some/dir cmd args
The toolsets used in the daemontools world, and elsewhere, have this and more besides; have had for many years; and are widely available.
- Wayne Marshall's perp has
runtool
:runtool -c /new/cwd myProgram
- Laurent Bercot's execline has
cd
:cd /new/cwd myProgram
- my nosh toolset has
chdir
:chdir /new/cwd myProgram
All of these are chain-loading tools, designed to be used in exactly these sorts of chains. There is a wide selection of chain-loading tools in these toolkits for other purposes.
Further reading
- https://unix.stackexchange.com/a/353698/5132
- Laurent Bercot (2018-08-01). "Reference". execline. skarnet.org.
- Laurent Bercot (2018-11-08). "Reference". s6. skarnet.org.
- Jonathan de Boyne Pollard (2018). "Command and tool list". nosh Guide. Softwares.
There is such a popular program. It is called ... hold onto your chair... drumroll... env
. The GNU version, since version 8.28, not POSIX, has the -C
option which lets you set the directory just as you require:
NAME env - run a program in a modified environment SYNOPSIS env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...] DESCRIPTION Set each NAME to VALUE in the environment and run COMMAND. Mandatory arguments to long options are mandatory for short options too. -i, --ignore-environment start with an empty environment -0, --null end each output line with NUL, not newline -u, --unset=NAME remove variable from the environment -C, --chdir=DIR change working directory to DIR --help display this help and exit --version output version information and exit A mere - implies -i. If no COMMAND, print the resulting environment.