POSIX Utilities – How to Set Current Working Directory When Invoking a Program

cwdfreebsdshell

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).

Best Answer

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
Related Question