¿Existe una utilidad POSIX (o al menos popular) para configurar el directorio de trabajo actual al invocar un programa?

20

Tenemos env (1) para modificar el entorno del comando que queremos ejecutar (por ejemplo env MANPAGER=more man dtrace). ¿Hay algo similar pero para modificar el directorio en el que se va a iniciar el comando?

Idealmente, me gustaría que se vea así:

theMagicCommand /new/cwd myProgram

De esta manera, podría "encadenarse" con otros comandos similares a env (1), por ejemplo,

daemon -p /tmp/pid env VAR=value theMagicCommand /new/cwd myProgram

Hasta ahora puedo pensar en la siguiente solución, que desafortunadamente no tiene la misma interfaz que env (1):

cd /new/cwd && myProgram

Además, puedo crear un script de shell simple como este:

#! /bin/sh -
cd "${1:?Missing the new working directory}" || exit 1
shift
exec "${@:?Missing the command to run}"

pero estoy buscando algo que ya existe (al menos en macOS y FreeBSD).

myProgramno es necesariamente una aplicación de escritorio (en cuyo caso podría usar la clave Path en un archivo .desktop ).

Mateusz Piotrowski
fuente
66
¿Por qué no cd /new/cwd && env VAR=value myProgramcumple con tus criterios?
jpaugh
Eso ya está en la pregunta, donde M. Piotrowski explicó que esa no es la misma interfaz que env. Mira env. Compararlo con rtprio, idprio, numactl, jexec, chrt, y de hecho los comandos de los conjuntos de herramientas menciona en las respuestas. Hay un patrón, y se está cargando en cadena.
JdeBP
3
¿Qué quieres decir con "interfaz"? ¿Y por qué no usar (cd the/cwd; cmd)?
Konrad Rudolph el
2
@KonradRudolph Por ejemplo, no puede pasar fácilmente (cd the/cwd; cmd)a env (1) sin envolverlo con sh (1).
Mateusz Piotrowski

Respuestas:

19

AFAIK, no existe tal utilidad dedicada en el cofre de herramientas POSIX. Pero es común invocar shpara configurar un entorno (cwd, límites, stdout / in / err, umask ...) antes de ejecutar un comando como lo hace en su shscript.

Pero no tiene que escribir esa secuencia de comandos en un archivo, solo puede insertarla:

sh -c 'CDPATH= cd -P -- "$1" && shift && exec "$@"' sh /some/dir cmd args

(suponiendo que el directorio no lo es -). Agregar CDPATH=(en caso de que haya uno en el entorno) y -Pque se comporte más como una escalera chdir().

Alternativamente, puede usar perlquién chdir()hace un directo chdir()de la caja.

perl -e 'chdir(shift@ARGV) or die "chdir: $!"; exec @ARGV or die "exec: $!"
         ' /some/dir cmd args
Stéphane Chazelas
fuente
Oh si. Esta es una variación muy útil del guión que incluí en mi pregunta. Temía que la utilidad que estoy buscando no exista ya que su funcionalidad ya está disponible con un línea de tiempo sh (1) relativamente corta.
Mateusz Piotrowski el
8
Si ya estás corriendo sh, también puedes hacerlo (cd /wherever && exec /my/command). La ()implícitamente abre un subnivel para ejecutar los comandos envueltos, y por supuesto, execse deshace del proceso de shell adicional tan pronto como /my/commandcomienza a funcionar.
jpaugh
2
Eso fue sugerido en una respuesta ahora eliminada. El interlocutor explicó que esa no era una respuesta a lo que preguntó xe.
JdeBP
15

Los conjuntos de herramientas utilizados en el mundo de daemontools y en otros lugares tienen esto y más; han tenido por muchos años; y están ampliamente disponibles

Todas estas son herramientas de carga de cadena, diseñadas para usarse exactamente en este tipo de cadenas. Hay una amplia selección de herramientas de carga en cadena en estos kits de herramientas para otros fines.

Otras lecturas

JdeBP
fuente
11

Hay un programa tan popular. Se llama ... aferrarse a la silla ... redoble de tambores ... env. La versión GNU, desde la versión 8.28, no POSIX, tiene la -Copción que le permite configurar el directorio tal como lo requiere:

    NOMBRE
           env: ejecuta un programa en un entorno modificado

    SINOPSIS
           env [OPCIÓN] ... [-] [NOMBRE = VALOR] ... [COMANDO [ARG] ...]

    DESCRIPCIÓN
           Establezca cada NOMBRE en VALOR en el entorno y ejecute COMANDO.

           Los argumentos obligatorios para las opciones largas también son obligatorios para las opciones cortas.

           -i , --no-ambiente
                  comenzar con un ambiente vacío

           -0 , - nulo
                  terminar cada línea de salida con NUL, no nueva línea

           -u , --unset = NOMBRE
                  eliminar variable del entorno

           -C , --chdir = DIR
                   cambia el directorio de trabajo a DIR

           - ayuda a mostrar esta ayuda y salir

           --versión
                  salida de información de versión y salida

           Un mero - implica -i . Si no hay COMANDO, imprima el entorno resultante.

norte. 'pronombres' m.
fuente
Genial, aunque no está disponible de fábrica en macOS y FreeBSD.
Mateusz Piotrowski
1

Ciertos programas tienen una opción para esto, como Git:

-C <path>

Ejecutar como si gitse iniciara en <path>lugar del directorio de trabajo actual.

y hacer:

-C dir, --directory=dir

Cambie al directorio dirantes de leer los archivos MAKE o hacer cualquier otra cosa.

y alquitrán:

-C, --directory=DIR

Cambie a DIRantes de realizar cualquier operación. Esta opción es sensible al orden, es decir, afecta a todas las opciones que siguen.

Steven Penny
fuente
Sí. Aunque mi pregunta es qué myProgrampasa si no ofrece esa opción ... Gracias por su contribución, pero me temo que no responde a mi pregunta en absoluto.
Mateusz Piotrowski