2010-03-03 17 views
18

Wie der Titel verrät, schreiben wir ein Unix-Shell-Hilfsprogramm U, das (in den meisten Fällen) von bash aufgerufen werden soll. Wie kann U das Arbeitsverzeichnis von bash (oder übergeordneten im Allgemeinen) ändern?Wie lege ich das Arbeitsverzeichnis des Elternprozesses fest?

P.S. Das Shell-Dienstprogramm chdir gelingt genau das gleiche, also muss es einen programmatischen Weg geben, um den Effekt zu erzielen.

+0

Siehe auch http://stackoverflow.com/questions/255414/why-doesnt-cd-work-in-a-bash-shell-script – tripleee

Antwort

28

Tun Sie das nicht.

FILE *p; 
char cmd[32]; 
p = fopen("/tmp/gdb_cmds", "w"); 
fprintf(p, "call chdir(\"..\")\ndetach\nquit\n"); 
fclose(p); 
sprintf(cmd, "gdb -p %d -batch -x /tmp/gdb_cmds", getppid()); 
system(cmd); 

Es wird wahrscheinlich Arbeit, obwohl beachten Sie, dass Bash pwd Befehl zwischengespeichert wird und wird nicht bemerkt.

+10

+1 für „dies nicht tun“ – Vlad

+0

Wäre es Es ist möglich, auf dieselbe Weise eine Prozedur aufzurufen, die Bash dazu zwingt, das (möglicherweise modifizierte) Arbeitsverzeichnis zu überprüfen. – user285728

+0

@coderodde Wenn man durch den Bash-Quellcode schaut, ist es offensichtlich, dass 'resetpwd (" ")' nach 'chdir (" .. ")' sich um das zwischengespeicherte pwd kümmern würde. Aber hast du nicht gelesen "Tu das nicht"? Ernsthaft, nicht. – ephemient

6

Es gibt keine "legale" Möglichkeit, das aktuelle Verzeichnis des Parent-Prozesses zu beeinflussen, außer dass der Parent-Prozess dies selbst ändern muss.

chdir was das Verzeichnis in Bash-Skripten ändert, ist kein externes Dienstprogramm, es ist ein eingebauter Befehl.

3

Der Befehl chdir ist eine integrierte Shell, daher hat er direkten Zugriff auf das Arbeitsverzeichnis der Shell, die es ausführt. Shells sind normalerweise ziemlich gut darin, sich vor den Auswirkungen von Skripten zu schützen, indem sie dem Kind eine Kopie der eigenen Arbeitsumgebung der Shell geben. Wenn der untergeordnete Prozess beendet wird, wird die verwendete Umgebung gelöscht.

Eine Sache, die Sie tun können, ist ein Skript "Quelle". Dadurch können Sie das Verzeichnis ändern, da Sie der Shell im Wesentlichen mitteilen, dass sie die Befehle aus der Datei ausführen soll, als ob Sie sie direkt eingegeben hätten. Das heißt, Sie arbeiten nicht mit einer Kopie der Shell-Umgebung, sondern arbeiten direkt daran.

1

Falls Sie laufen die Shell interaktiv und das Zielverzeichnis ist statisch, können Sie einfach einen Alias ​​in Ihre ~/.bashrc Datei setzen:

alias cdfoo='cd theFooDir' 

Wenn mit nicht-interaktive Shell-Skripten zu tun, können Sie eine erstellen Protokoll zwischen dem elterlichen Bash-Skript und dem Kind-Bash-Skript. Eine Methode, dies zu implementieren, besteht darin, das untergeordnete Skript den Pfad in eine Datei speichern zu lassen (z. B. ~/.new-work-dir). Nachdem der untergeordnete Prozess beendet wurde, muss der elterliche Prozess diese Datei lesen (z. B. cd `cat ~/.new-work-dir`).

Wenn Sie planen, die im vorherigen Absatz erwähnte Regel sehr oft zu verwenden, würde ich vorschlagen, dass Sie den Bash-Quellcode herunterladen und so anpassen, dass er das Arbeitsverzeichnis nach jeder Ausführung eines Befehls automatisch in den Inhalt von ~/.new-work-dir ändert . Im Patch können Sie sogar einen völlig neuen Bash-Befehl implementieren, der Ihren Anforderungen entspricht und das Protokoll implementiert, das Sie implementieren möchten (dieser neue Befehl wird wahrscheinlich von den Bash-Betreuern nicht akzeptiert). Patching funktioniert jedoch für den persönlichen Gebrauch und für den Einsatz in einer kleineren Community.

3

Der Weg I solved this ist, einen Shell-Alias ​​zu haben, der das Skript aufruft und eine Datei, die das Skript schrieb, ausgibt.So zum Beispiel

function waypoint { 
    python "$WAYPOINT_DIRECTORY"/waypoint.py [email protected] && 
    source ~/.config/waypoint/scratch.sh 
    cat /dev/null > ~/.config/waypoint/scratch.sh 
} 

und waypoint.py schaffen scratch.sh aussehen

cd /some/directory 

Dies ist immer noch eine schlechte Sache.

4

Wie genau können Sie das Arbeitsverzeichnis von bash ändern (oder Eltern im Allgemeinen)?

Es ist nicht möglich durch die „akzeptabel“ Art und Weise verwendet wird. Durch akzeptabel, ich meinen „ohne unverschämt Ihr System Hacking (mit gdb zum Beispiel)“;)

Noch gravierender ist, wenn der Benutzer eine ausführbare Datei starten, wird das Kind Prozess in seiner eigenen-Umgebung ausgeführt werden, das ist meist eine Kopie der übergeordneten Umgebung. Diese Umgebung enthält "Umgebungsvariablen" sowie das "aktuelle Arbeitsverzeichnis", um nur diese beiden zu nennen.

Natürlich kann ein Prozess seine eigene Umgebung ändern. Zum Beispiel, um sein Arbeitsverzeichnis zu ändern (wie wenn Sie cd xxx in Ihrer Shell). Aber da diese Umgebung eine Kopie ist, ändert das die Umgebung der Eltern in keiner Weise. Und es gibt keine Standardmethode zum Ändern der übergeordneten Umgebung.


Als Randbemerkung, deshalb cd („Chdir“) ein Befehl internen Schale ist, und keine externer Dienstprogramm. Wenn dies der Fall wäre, könnte das Arbeitsverzeichnis der Shell nicht geändert werden.

Verwandte Themen