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.

Tags:

Shell

Freebsd

Cwd