Ändern des Arbeitsverzeichnisses des übergeordneten Skripts von einem "ausgehobenen" Skript

2131
Sebi

Ich möchte das Arbeitsverzeichnis meines Skripts durch ein anderes Skript ändern, das hinzugefügt wurde.

Erstes Skript:

#!/bin/bash pwd source script2 pwd 

Sedond-Skript:

cd .. pwd 

Das Ergebnis ist folgendes:

> ./script1 /home/sebi/testdir1/testdir2 # 1st script /home/sebi/testdir1 # 2nd script /home/sebi/testdir1 # 1st script 

Ich habe die Frage bearbeitet, als ich dieses Skript getestet habe, und es funktionierte, wie ich wollte. Das folgende Skript funktioniert jedoch anders, da die Ausführung des Indexes beendet ist. Parent befindet sich in demselben Verzeichnis wie vor dem Aufruf des Indexes.

#!/bin/bash while : do sleep 5   cat /home/.../shelldata.txt >> /home/.../gmodshell #logging  ((source /home/..../shelldata.txt) 2>&1) | \ sed -e "s/..shellRunner.sh..line../SH/" > \ /home/..../shellFeedback.txt  echo > /home/..../shelldata.txt  done 

Ziel ist es, mit Dateien auf Bash zuzugreifen, damit ich den Befehl in eine Datei schreiben kann und nach einer Weile bekomme ich die Ausgabe in einer anderen Datei.

2
Es funktioniert gut für mich, wenn ich dasselbe tue. Sebastian Paaske Tørholm vor 13 Jahren 1

5 Antworten auf die Frage

5
Cam Jackson

Wenn sich die Skripts 1 und 2 im selben Verzeichnis befinden, versuchen Sie, das Skript 1 zu erstellen:

#!/bin/bash pwd . ./script2 pwd 

Wenn Sie den Punkt vor dem Aufruf des Skripts platzieren (ich spreche vom ersten Punkt, nicht vom Punkt, der zum Dateipfad des Skripts gehört, das Sie aufrufen möchten), sagt die Shell: "Führen Sie das folgende Skript in diesem Prozess aus, anstatt zu spawnen ein neuer Prozess dafür. "

Aktionen, die im zweiten Skript ausgeführt werden (wie cd-ing oder Einstellungsvariablen), bleiben auch nach dem Ende des zweiten Skripts bestehen.

2
Rajish

Aus der bashDokumentation:

Befehlsersetzung, Befehle, die in Klammern gruppiert sind, und asynchrone Befehle werden in einer Subshell-Umgebung aufgerufen, die ein Duplikat der Shell-Umgebung ist, mit der Ausnahme, dass von der Shell abgefangene Traps auf die Werte zurückgesetzt werden, die die Shell beim Aufruf von ihrer Shell geerbt hat. Integrierte Befehle, die als Teil einer Pipeline aufgerufen werden, werden auch in einer Subshell-Umgebung ausgeführt. Änderungen an der Subshell-Umgebung haben keinen Einfluss auf die Ausführungsumgebung der Shell.

Sie sollten also vermeiden, Klammern zu setzen, wenn Sie eine Datei mit dem .Befehl (Punkt) beschaffen (wie in dieser Antwort erwähnt ).

1
ℝaphink

Dies gilt nicht für die Beschaffung eines Skripts. Sie würden mit einem einzigen Skript genau das gleiche Ergebnis erzielen. Versuchen:

#!/bin/bash pwd cd .. pwd 

Der Grund dafür ist, dass ein gestartetes Skript in einer Subshell ausgeführt wird. Wenn das Skript zurückkehrt, wird die Subshell geschlossen und Sie gelangen zurück zu Ihrer ursprünglichen Shell, unabhängig davon, wo Sie sich im Skript befanden.

Wenn Sie möchten, dass ein Befehl Sie in einem anderen Verzeichnis ablegt, sollten Sie stattdessen einen Aliasnamen oder eine Bash-Funktion verwenden:

function script1 () { cd ..; } 
Das zweite Skript ist dynamisch und empfängt Befehle von der entfernten Quelle. Gibt es eine Möglichkeit anstelle von "source", andere Dateien einzuschließen, da sie von derselben Datei ausgeführt werden, Art von Inline-Include? Sebi vor 13 Jahren 0
@Sebi: Kannst du deine Bedürfnisse / Architektur erklären? ℝaphink vor 13 Jahren 0
Ich habe genau das gleiche Skript getestet, das ich anfangs in der Frage gepostet hatte, und es funktionierte, wie ich es wollte. Das von mir hinzugefügte Skript funktioniert jedoch nicht richtig. Ich bin auf Fedora 14. Was ich erreichen möchte, ist die Ausführung von Remote-Befehlen (in eine Datei geschrieben) und Ausgabe in eine andere Datei, damit ich mit Dateifunktionen auf Bash zugreifen kann. Ich weiß, wie unwirksam es ist Ich kann aber nur kommunizieren, indem ich Dateifunktionen benutze. Sebi vor 13 Jahren 0
1
jlliagre

Es macht keinen Sinn, den Befehl source zu verwenden, wenn Sie dies in einer Subshell wie in Ihrem zweiten Skript tun:

((source /home/..../shelldata.txt) 2>&1) | \ 

Darüber hinaus ist shelldata.txt wirklich ein Shell-Skript, daher ist es verwirrend, wenn Sie ihm eine .txt-Erweiterung geben, obwohl dies nicht verboten ist.

Schließlich wäre es hilfreich, wenn Sie wissen, was shelldata.txt enthält, um herauszufinden, wie Sie Ihre Frage beantworten können.

0
uSlackr

Könnten Sie das Quelle-Skript verwenden, um eine Variable festzulegen, und die ursprüngliche Variable die Änderung basierend auf dem Inhalt der Variablen vornehmen lässt, anstatt die Änderung direkt im Quelle-Skript vorzunehmen?

Die Variable würde jedoch nach dem Beenden des zweiten Skripts nicht existieren, was bedeutet, dass sie im aktuellen Prozess mit dem Befehl dot ausgeführt werden muss. Und wenn Sie es auf diese Weise tun möchten (führen Sie es im aktuellen Prozess aus), können Sie auch einfach die CD machen, anstatt eine Variable zu setzen und dann eine CD einzubringen. Cam Jackson vor 13 Jahren 0