2009-04-24 3 views
240

Wie starte ich mit einer Linux-Shell ein Programm mit einem anderen Arbeitsverzeichnis als das aktuelle Arbeitsverzeichnis? Zum Beispiel habe ich eine Binärdatei helloworld, die die Datei hello-world.txt im aktuellen Verzeichnis erstellt. Diese Datei befindet sich im Verzeichnis /a. Momentan bin ich im Verzeichnis /b. Ich möchte mein Programm starten ../a/helloworld starten und die hello-world.txt irgendwo in einem dritten Verzeichnis /c.Wie führe ich ein Programm mit einem anderen Arbeitsverzeichnis als das aktuelle von der Linux-Shell aus?

+4

ich auf die harte Art und Weise entdeckt auszuführen, dass ' su 'setzt das Arbeitsverzeichnis auf das Ausgangsverzeichnis des angegebenen Benutzers zurück, bevor Befehle '-c' ausgeführt werden. Das war sehr hilfreich für mich. –

Antwort

406

Rufen Sie das Programm wie folgt:

(cd /c; /a/helloworld) 

Die Klammern verursachen eine Unterschale hervorgebracht werden. Diese Untershell ändert dann ihr Arbeitsverzeichnis in /c und führt dann helloworld von /a aus. Nachdem das Programm beendet wurde, wird die Subshell beendet und Sie werden an die Eingabeaufforderung der übergeordneten Shell in dem Verzeichnis zurückgeleitet, von dem aus Sie gestartet wurden.

Fehlerbehandlung: Um zu vermeiden, das Programm auszuführen, ohne das Verzeichnis geändert zu haben, z. wenn /c falsch geschrieben haben, machen die Ausführung von helloworld bedingten:

(cd /c && /a/helloworld) 

Speichernutzung Reduzierung: die Subshell Abfallspeicher Um zu vermeiden, während hallo Welt führt, helloworld über exec aufrufen:

(cd /c && exec /a/helloworld) 

[ Danke an Josh and Juliano für Tipps zur Verbesserung dieser Antwort!]

+1

Eine Möglichkeit, Argumente an diese Shell zu übergeben? Wie in $ 1 und $ 2? – finiteloop

+1

@segfault: Die Subshell hat vollständigen Zugriff auf den umgebenden Bereich. –

+0

Scheint so, als wäre es in diesem Verzeichnis sowieso, nicht wahr? – dhein

1

Wenn Sie immer möchten, dass es an/C geht, verwenden Sie beim Schreiben der Datei einen absoluten Pfad.

3

Eine Möglichkeit ist das Erstellen eines Wrapper Shell-Skripts.

Das Shell-Skript würde das aktuelle Verzeichnis in/c ändern und dann/a/helloworld ausführen. Sobald das Shell-Skript beendet wird, wird das aktuelle Verzeichnis wieder in/b zurückgesetzt.

Hier ist ein Bash-Shell-Skript Beispiel:

#!/bin/bash 
cd /c 
/a/helloworld 
14
sh -c 'cd /c && ../a/helloworld' 
+1

Wird für FreeBSDs jexec verwendet, um einen Befehl im angegebenen Arbeitsverzeichnis auszuführen. –

+0

wow Ihr Glück, dass Sie sogar einen Computer im Gefängnis benutzen können –

+0

@MattWilde https://www.freebsd.org/cgi/man.cgi?jail – mihi

77

ähnlich David Schmitt ‚s Antwort, und Joshs Vorschlag, aber hinterlässt keine Shell-Prozess läuft:

(cd /c && exec /a/helloworld) 

Auf diese Weise ist ähnlich, wie Sie in der Regel Befehle auf der Shell ausgeführt. Um den praktischen Unterschied zu sehen, müssen Sie ps ef von einer anderen Shell mit jeder Lösung ausführen.

+0

[Bash Handbuch Builtins ** Exec **] (https: // www .gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html # Bourne-Shell-Builtins) –

1

Wenn Sie dies in Ihrem Programm ausführen wollen, dann würde ich so etwas wie:

#include <unistd.h> 
int main() 
{ 
    if(chdir("/c") < 0) 
    { 
    printf("Failed\n"); 
    return -1 ; 
    } 

    // rest of your program... 

} 
+0

Er will das in einem Shell-Skript, und nicht in einem C. Das wäre es auch eine schreckliche Idee, die Binärdatei zu verarbeiten. –

9

Ich denke immer UNIX-Tools wie Filter geschrieben werden sollen, eine Eingabe von stdin lesen und Ausgabe auf stdout schreiben. Wenn möglich, könnten Sie Ihre Helloworld-Binärdatei ändern, um den Inhalt der Textdatei in stdout statt in eine bestimmte Datei zu schreiben. Auf diese Weise können Sie die Shell verwenden, um Ihre Datei überall zu schreiben.

$ cd ~/b

$ ~/a/helloworld> ~/c/helloworld.txt

+5

+1 für richtig, obwohl die Antwort nur peripher eine Antwort ist. –

1

, warum es nicht einfach halten

cd SOME_PATH && run_some_command && cd -

der letzte ' Der cd 'Befehl bringt Sie zurück zum letzten pwd-Verzeichnis. Dies sollte auf allen * nix-Systemen funktionieren.

+0

Es bringt Sie nicht zurück, wenn run_some_command fehlschlägt. –

+0

Sie sind @mezhaka schreiben, sollte das gedacht haben :) – Sahil

7

Eine Option, die in

(pushd SOME_PATH && run_stuff; popd) 

Demo bash gebaut keine Subshell erfordern und ist:

$ pwd 
/home/abhijit 
$ pushd /tmp # directory changed 
$ pwd 
/tmp 
$ popd 
$ pwd 
/home/abhijit 
+0

Ein ähnlicher Vorschlag wurde von Sahil unten gemacht. Es funktioniert nicht, wenn der Befehl fehlschlägt. Betrachte 'pushed SOME_PATH && run_stuff && popd' - wenn run_stuff fehlschlägt, dann wird popd nicht ausgeführt. –

+0

Späte Antwort, das hängt von den Einstellungen der Bash-Datei ab. Bash kann die Ausführung von Befehlen auch nach einem fehlgeschlagenen Befehl fortsetzen (im Gegensatz zur Verwendung von &&), aber es kann so eingestellt werden, dass 'set -e'' in der Datei nicht verwendet wird und dann nicht" popd ". – Loren

+1

Noch, ich denke, pushed $ {SOME_PATH} "&& run_stuff; popd' ist besser als die aktuelle Antwort, da die Pushd/Popd-Semantik speziell für diese Situation entwickelt wurde, in ein Verzeichnis zu gehen und dann zu dem ursprünglichen zurückzukehren. –

4

Nur der letzte "& &" in ändern ";" und es wird cd zurück, egal, ob der Befehl fehlschlägt oder erfolgreich ist:

cd SOME_PATH && run_some_command ; cd - 
-1

aus dem aktuellen Verzeichnis den vollständigen Pfad zum Skript-Verzeichnis bietet den Befehl

/root/server/user/home/bin/script.sh 
+0

Das ändert das Arbeitsverzeichnis überhaupt nicht - ich denke, Sie beantworten eine andere Frage als die, die gestellt wurde. –

Verwandte Themen