Existe-t-il un utilitaire POSIX (ou au moins un utilitaire populaire) pour définir le répertoire de travail actuel lors de l'appel d'un programme?

20

Nous avons env (1) pour modifier l'environnement de la commande que nous voulons exécuter (par exemple env MANPAGER=more man dtrace). Y a-t-il quelque chose de similaire, mais pour modifier le répertoire dans lequel la commande va être lancée?

Idéalement, je voudrais qu'il ressemble à ceci:

theMagicCommand /new/cwd myProgram

De cette façon, il pourrait être "enchaîné" avec d'autres commandes de type env (1), par exemple,

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

Jusqu'à présent, je peux penser à la solution suivante, qui n'a malheureusement pas la même interface que env (1):

cd /new/cwd && myProgram

De plus, je peux simplement créer un simple script shell comme celui-ci:

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

mais je cherche quelque chose qui existe déjà (au moins sur macOS et FreeBSD).

myProgramn'est pas nécessairement une application de bureau (auquel cas je pourrais simplement utiliser la clé Path dans un fichier .desktop ).

Mateusz Piotrowski
la source
6
Pourquoi ne cd /new/cwd && env VAR=value myProgramrépond pas à vos critères?
jpaugh
C'est déjà dans la question, où M. Piotrowski a expliqué que ce n'est pas la même interface que env. Regardez env. Comparer à rtprio, idprio, numactl, jexec, chrt, et en effet les commandes dans les boîtes à outils mentionnés dans les réponses. Il y a un modèle et c'est le chargement de la chaîne.
JdeBP
3
Qu'entendez-vous par «interface»? Et pourquoi ne pas utiliser (cd the/cwd; cmd)?
Konrad Rudolph
2
@KonradRudolph Par exemple, vous ne pouvez pas facilement passer (cd the/cwd; cmd)à env (1) sans l'envelopper avec sh (1).
Mateusz Piotrowski

Réponses:

19

AFAIK, il n'y a pas un tel utilitaire dédié dans le coffre à outils POSIX. Mais il est courant d'invoquer shpour configurer un environnement (cwd, limites, stdout / in / err, umask ...) avant d'exécuter une commande comme vous le faites dans votre shscript.

Mais vous n'êtes pas obligé d'écrire ce script dans un fichier, vous pouvez simplement l'intégrer:

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

(en supposant que le répertoire ne l'est pas -). Ajout CDPATH=(au cas où il y en a un dans l'environnement) et -Ppour qu'il se comporte plus comme une ligne droite chdir().

Alternativement, vous pouvez utiliser le perldont sort chdir()directement chdir()de la boîte.

perl -e 'chdir(shift@ARGV) or die "chdir: $!"; exec @ARGV or die "exec: $!"
         ' /some/dir cmd args
Stéphane Chazelas
la source
Oh oui. C'est une variante très pratique du script que j'ai inclus dans ma question. J'avais peur que l'utilitaire que je cherche n'existe pas car sa fonctionnalité est déjà disponible avec un oneliner sh (1) relativement court.
Mateusz Piotrowski
8
Si vous êtes déjà en cours d'exécution sh, vous pouvez également le faire (cd /wherever && exec /my/command). Le ()ouvre implicitement un sous-shell pour exécuter les commandes encapsulées, et bien sûr, execse débarrasse du processus de shell supplémentaire aussi rapidement qu'il /my/commandcommence à s'exécuter.
jpaugh
2
Cela a été suggéré dans une réponse désormais supprimée. L'interrogateur a expliqué que ce n'était pas une réponse à ce que xe a demandé.
JdeBP
15

Les jeux d'outils utilisés dans le monde des daemontools, et ailleurs, ont cela et plus encore; ont depuis de nombreuses années; et sont largement disponibles.

  • Le perp de Wayne Marshall a runtool:

    runtool -c / new / cwd myProgram
  • La ligne exécutive de Laurent Bercot a cd:

    cd / nouveau / cwd myProgram
  • ma trousse à outils nosh a chdir:

    chdir / new / cwd myProgram

Ce sont tous des outils de chargement de chaîne, conçus pour être utilisés exactement dans ces types de chaînes. Il existe une large sélection d'outils de chargement de chaîne dans ces boîtes à outils à d'autres fins.

Lectures complémentaires

JdeBP
la source
11

Il existe un programme très populaire. Il est appelé ... sur votre chaise prise ... ... drumroll env. La version GNU, depuis la version 8.28, pas POSIX, a l' -Coption qui vous permet de définir le répertoire comme vous le souhaitez:

    NOM
           env - exécuter un programme dans un environnement modifié

    SYNOPSIS
           env [OPTION] ... [-] [NOM = VALEUR] ... [COMMANDE [ARG] ...]

    LA DESCRIPTION
           Définissez chaque NOM sur VALUE dans l'environnement et exécutez COMMAND.

           Les arguments obligatoires pour les options longues sont également obligatoires pour les options courtes.

           -i , --ignore-environnement
                  commencer avec un environnement vide

           -0 , --null
                  terminer chaque ligne de sortie par NUL, pas par une nouvelle ligne

           -u , --unset = NOM
                  supprimer une variable de l'environnement

           -C , --chdir = DIR
                   changer le répertoire de travail en DIR

           --help afficher cette aide et quitter

           --version
                  Affiche les informations de version et quitte

           Un simple - implique -i . Si aucune COMMANDE, imprimez l'environnement résultant.

n. «pronoms» m.
la source
Cool, bien qu'il ne soit pas disponible dès le départ sur macOS et FreeBSD.
Mateusz Piotrowski
1

Certains programmes ont une option pour cela, comme Git:

-C <path>

Exécuter comme si a gitété démarré à la <path>place du répertoire de travail actuel.

et fais:

-C dir, --directory=dir

Passez au répertoire diravant de lire les makefiles ou de faire autre chose.

et Tar:

-C, --directory=DIR

Passez à DIRavant d'effectuer toute opération. Cette option est sensible à l'ordre, c'est-à-dire qu'elle affecte toutes les options qui suivent.

Steven Penny
la source
Oui. Bien que ma question soit de savoir si myProgramne propose pas une telle option ... Merci pour votre contribution mais je crains qu'elle ne réponde pas du tout à ma question.
Mateusz Piotrowski