staging.inyokaproject.org

Verzeichniswechsel aus Subshell heraus

Status: Gelöst | Ubuntu-Version: Ubuntu MATE 24.04 (Noble Numbat)
Antworten |

CarstenHa

Avatar von CarstenHa

Anmeldungsdatum:
1. Mai 2020

Beiträge: 154

Hallo,

mal eine Frage. Angenommen ich habe ein Bash-Skript, das ich aus dem Ordner /home/user/dir2 aufrufe:

1
2
3
4
#!/bin/bash
cd /home/user/dir
pwd
...

Kann ich aus der Subshell (z.B. am Ende des Skriptes) eigentlich auch gleichzeitig das Verzeichnis im Elternprozess von /home/user/dir2 nach /home/user/dir wechseln? Ich weiss, man könnte ja auch einfach das Skript sourcen, also . ./skriptname.sh Aber kann ich das auch anders lösen wenn ich das Skript "normal" aufrufe ./skriptname.sh

Gruß

Carsten

micneu

Avatar von micneu

Anmeldungsdatum:
19. Januar 2021

Beiträge: 845

Moin, ich verstehe dein Ziel noch nicht. Bitte deinen code in codeblöcke, dann können wir darauf aufbauen

CarstenHa

(Themenstarter)
Avatar von CarstenHa

Anmeldungsdatum:
1. Mai 2020

Beiträge: 154

Oh sorry, das kommt davon wenn man schnell Copy & Paste macht und sich das nicht mehr anschaut.

CarstenHa

(Themenstarter)
Avatar von CarstenHa

Anmeldungsdatum:
1. Mai 2020

Beiträge: 154

micneu schrieb:

Moin, ich verstehe dein Ziel noch nicht. Bitte deinen code in codeblöcke, dann können wir darauf aufbauen

Ich möchte in der Shell, in der ich das Skript aufrufe, in das gleiche Verzeichnis wechseln wie im Skript. Und das soll vom Skript ausgehen.

TK87

Anmeldungsdatum:
8. Juli 2019

Beiträge: 266

Moin,

wenn das Skript ansonsten keine Ausgaben in stdout erzeugt, könntest du am Ende des Skripts den Pfad Ausgeben und am Ende des Skripts den per echo ausgeben...

1
echo cd /home/user/dir

und es in der Elternshell ausführen...

1
$(/home/user/dir2/myscript.sh)

Gruß Thomas

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

CarstenHa schrieb:

Ich möchte in der Shell, in der ich das Skript aufrufe, in das gleiche Verzeichnis wechseln wie im Skript. Und das soll vom Skript ausgehen.

So eine Möglichkeit gibt es generell nicht: Kontrolle und Vererbung gehen immer vom Elternprozess zum Kindprozess.

TK87 schrieb:

wenn das Skript ansonsten keine Ausgaben in stdout erzeugt, könntest du am Ende des Skripts den Pfad Ausgeben und am Ende des Skripts den per echo ausgeben... [...]

Was ein übler Hack ist. Und es funktioniert auch nur, wenn die aufrufende Shell daran "denkt", den Aufruf genau so zu machen. Wenn das aufgerufene Skript noch weitere Ausgaben nach Stdout erzeugen soll, die man womöglich noch sehen will, dann geht es schon nicht mehr.

Eine andere Möglichkeit wäre, das neue Verzeichnis an einen bekannten Ort (sprich: Datei) zu schreiben und die dann von der Elternshell auslesen zu lassen. Aber auch da braucht es die Kooperation der Elternshell, die z.B. das Skript mit einer Shell-Funktion klammern muss:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
foo() {
  ~/bin/foo
  x=$?

  if [ -r /tmp/newdir ]; then
    cd $(read -r /tmp/newdir)
    rm /tmp/newdir
  fi

  return $x
}

TK87

Anmeldungsdatum:
8. Juli 2019

Beiträge: 266

rklm schrieb:

Wenn das aufgerufene Skript noch weitere Ausgaben nach Stdout erzeugen soll, die man womöglich noch sehen will, dann geht es schon nicht mehr.

Genau das habe ich doch auch so geschrieben.

Ausgaben die man noch sehen will kann man aber nach stderr leiten. So funktioniert es auch damit.

CarstenHa

(Themenstarter)
Avatar von CarstenHa

Anmeldungsdatum:
1. Mai 2020

Beiträge: 154

TK87 schrieb:

Moin,

wenn das Skript ansonsten keine Ausgaben in stdout erzeugt, könntest du am Ende des Skripts den Pfad Ausgeben ...

Das hat mich auf eine Idee gebracht. Ich habe das jetzt wie folgt gelöst. Ich habe mir folgende Funktion (die den gleichen Namen wie mein Skript hat) in der Datei ~/.bashrc erstellt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
skriptname() {
tfile="$(mktemp)"
/path/to/script $@ &> >(tee -a "$tfile")
# Der eigentliche Pfad befindet sich in der Gruppierung: \(.*\)
gotopath="$(cat "$tfile" | sed -n 's%.*MUSTER\(.*\)%\1%p')"
if [ -d "$gotopath" ]; then
 echo "Gehe ins Verzeichnis ..."
 cd "$gotopath"
fi
}

Kurze Erklärung:
- mktemp erzeugt eine temporäre datei in Ordner /tmp/
- Das Skript wird aufgerufen mit allen Argumenten ($@) und die Ausgabe zusätzlich in die temporäre Datei geschrieben.
- Dann wird der Pfad mit sed aus der temporären Datei gefiltert.
- Bei Fund wird in das Verzeichnis gesprungen.

Danke Euch allen. Manchmal braucht es nur einen kleinen Stupser 😉

Viele Grüße

Carsten

Antworten |