We have env(1) to modify the environment of the command we want to run (for example env MANPAGER=more man dtrace). Is there something similar but for modifying the directory that the command is going to be started in?
Ideally, I would like it to look like this:
theMagicCommand /new/cwd myProgram
This way it could be “chained” with other env(1)-like commands, e.g.,
daemon -p /tmp/pid env VAR=value theMagicCommand /new/cwd myProgram
So far I can think of the following solution, which unfortunately does not have the same interface as env(1):
cd /new/cwd && myProgram
Also, I can just create a simple shell script like this:
#! /bin/sh -
cd "${1:?Missing the new working directory}" || exit 1
shift
exec "${@:?Missing the command to run}"
but I am looking for something that already exists (at least on macOS and FreeBSD).
myProgram is not necessarily a desktop application (in which case I could just use the Path key in a .desktop file).
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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 "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fbdfbb">[email protected]</a>"' 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(<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d5a6bdbcb3a19594879283">[email protected]</a>) or die "chdir: $!"; exec @ARGV or die "exec: $!"
' /some/dir cmd args
Method 2
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.
Method 3
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.
Method 4
Certain programs have an option for this, like Git:
-C <path>Run as if
gitwas started in<path>instead of the current working
directory.
and Make:
-C dir,--directory=dirChange to directory
dirbefore reading the makefiles or doing anything else.
and Tar:
-C,--directory=DIRChange to
DIRbefore performing any operations. This option is
order-sensitive, i.e. it affects all options that follow.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0