Gibt es ein POSIX-Dienstprogramm (oder zumindest ein beliebtes), um das aktuelle Arbeitsverzeichnis beim Aufrufen eines Programms festzulegen?


20

Wir haben env (1) , um die Umgebung des Befehls zu ändern, den wir ausführen möchten (zum Beispiel env MANPAGER=more man dtrace). Gibt es etwas Ähnliches, nur um das Verzeichnis zu ändern, in dem der Befehl gestartet werden soll?

Im Idealfall möchte ich, dass es so aussieht:

theMagicCommand /new/cwd myProgram

Auf diese Weise könnte es mit anderen env (1) -ähnlichen Befehlen "verkettet" werden, z.

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

Bisher kann ich mir folgende Lösung vorstellen, die leider nicht das gleiche Interface wie env (1) hat:

cd /new/cwd && myProgram

Außerdem kann ich einfach ein einfaches Shell-Skript wie das folgende erstellen:

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

aber ich suche etwas, das es schon gibt (zumindest unter macOS und FreeBSD).

myProgramist nicht unbedingt eine Desktop-Anwendung (in diesem Fall könnte ich einfach den Pfadschlüssel in einer .desktop-Datei verwenden ).


6
Warum entspricht es cd /new/cwd && env VAR=value myProgramnicht Ihren Kriterien?
Jpaugh

Das steht schon in der Frage, wo M. Piotrowski erklärt hat, dass das nicht die gleiche Schnittstelle ist wie env. Schau mal env. Vergleichen Sie es mit rtprio, idprio, numactl, jexec, chrt, und in der Tat die Befehle in den Toolsets in den Antworten erwähnt. Es gibt ein Muster und es ist Kettenladen.
JdeBP

3
Was meinst du mit "Schnittstelle"? Und warum nicht benutzen (cd the/cwd; cmd)?
Konrad Rudolph

2
@KonradRudolph Sie können beispielsweise nicht einfach (cd the/cwd; cmd)zu env (1) übergehen , ohne es mit sh (1) zu umschließen .
Mateusz Piotrowski

Antworten:


19

AFAIK, es gibt kein spezielles Hilfsprogramm in der POSIX-Werkzeugkiste. Es ist jedoch üblich, sheine Umgebung (cwd, limits, stdout / in / err, umask ...) einzurichten, bevor Sie einen Befehl wie in Ihrem shSkript ausführen .

Sie müssen dieses Skript jedoch nicht in eine Datei schreiben, sondern können es einfach einbinden:

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

(vorausgesetzt, das Verzeichnis ist nicht -). Hinzufügen CDPATH=(falls es eine in der Umgebung gibt) und -Pdamit es sich eher wie eine Straße verhält chdir().

Alternativ können Sie verwenden , perlderen chdir()tut eine gerade chdir()aus dem Kasten heraus .

perl -e 'chdir(shift@ARGV) or die "chdir: $!"; exec @ARGV or die "exec: $!"
         ' /some/dir cmd args

Oh ja. Dies ist eine sehr praktische Variante des Skripts, das ich in meine Frage aufgenommen habe. Ich hatte Angst, dass das von mir gesuchte Dienstprogramm nicht existiert, da seine Funktionalität bereits mit einem relativ kurzen sh (1) -Oneliner verfügbar ist.
Mateusz Piotrowski

8
Wenn Sie bereits laufen sh, können Sie dies auch tun (cd /wherever && exec /my/command). Das ()Programm öffnet implizit eine Subshell, um die umschlossenen Befehle auszuführen, und löscht execden zusätzlichen Shell-Prozess natürlich so schnell wie möglich /my/command.
Jpaugh

2
Das wurde in einer jetzt gelöschten Antwort vorgeschlagen. Der Fragesteller erklärte, dass dies keine Antwort auf die Frage von xe sei.
JdeBP

15

Die Toolsets, die in der Welt von daemontools und anderswo verwendet werden, bieten dies und mehr. haben seit vielen Jahren gehabt; und sind weit verbreitet.

  • Wayne Marshalls Täter hat runtool:

    runtool -c / new / cwd myProgram
  • Laurent Bercots Execline hat cd:

    cd / new / cwd myProgram
  • Mein Nosh-Toolset enthält chdir:

    chdir / new / cwd myProgram

All dies sind Kettenladewerkzeuge, die für genau diese Arten von Ketten entwickelt wurden. Es gibt eine große Auswahl an Kettenladewerkzeugen in diesen Werkzeugsätzen für andere Zwecke.

Weitere Lektüre


11

Es gibt so ein beliebtes Programm. Es heißt ... Halt auf dem Stuhl ... Trommelwirbel ... env. Die GNU-Version, seit Version 8.28, nicht POSIX, hat die -COption, mit der Sie das Verzeichnis nach Ihren Wünschen einstellen können:

    NAME
           Führen Sie ein Programm in einer geänderten Umgebung aus

    ZUSAMMENFASSUNG
           env [OPTION] ... [-] [NAME = VALUE] ... [COMMAND [ARG] ...]

    BESCHREIBUNG
           Setzen Sie jeden NAME in der Umgebung auf VALUE und führen Sie COMMAND aus.

           Obligatorische Argumente für lange Optionen sind auch für kurze Optionen obligatorisch.

           -i , --ignore-Umgebung
                  Beginnen Sie mit einer leeren Umgebung

           -0 , --null
                  Beenden Sie jede Ausgabezeile mit NUL, nicht mit Newline

           -u , --unset = NAME
                  Variable aus der Umgebung entfernen

           -C , --chdir = DIR
                   Arbeitsverzeichnis in DIR ändern

           --help Diese Hilfe anzeigen und beenden

           --Ausführung
                  Versionsinformationen ausgeben und beenden

           Ein bloßes - impliziert -i . Wenn kein BEFEHL angezeigt wird, drucken Sie die resultierende Umgebung.


Cool, obwohl es unter macOS und FreeBSD nicht sofort verfügbar ist.
Mateusz Piotrowski

1

Bestimmte Programme haben eine Option dafür, wie Git:

-C <path>

Führen Sie das Programm so aus, als wäre gites in <path>dem aktuellen Arbeitsverzeichnis gestartet worden .

und mache:

-C dir, --directory=dir

Wechseln Sie in das Verzeichnis, dirbevor Sie die Makefiles lesen oder etwas anderes tun.

und Teer:

-C, --directory=DIR

Wechseln Sie zu, DIRbevor Sie Vorgänge ausführen. Diese Option ist auftragssensitiv, dh sie wirkt sich auf alle folgenden Optionen aus.


Ja. Obwohl meine Frage ist, was ist, wenn myProgramnicht eine solche Option bietet ... Vielen Dank für Ihren Beitrag, aber ich fürchte, es beantwortet meine Frage überhaupt nicht.
Mateusz Piotrowski
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.