Skript zum Ändern des aktuellen Verzeichnisses (cd, pwd)

Ich möchte ein Skript ausführen, um einfach das aktuelle Arbeitsverzeichnis zu ändern:

#!/bin/bash cd web/www/project 

Aber nachdem ich es ausgeführt habe, bleibt das aktuelle pwd unverändert! Wie kann ich das tun?

Antwort

Es handelt sich um ein erwartetes Verhalten. Das Skript wird in einer Subshell ausgeführt und kann das übergeordnete Shell-Arbeitsverzeichnis nicht ändern. Seine Effekte gehen verloren, wenn es beendet ist.

Um das Verzeichnis der aktuellen Shell dauerhaft zu ändern, sollten Sie den Befehl source verwenden, der auch einfach als ., das ein Skript in der aktuellen Shell-Umgebung anstelle einer Sub-Shell ausführt.

Die folgenden Befehle sind identisch:

. script 

oder

source script 

Kommentare

  • @Sony: Beachten Sie, dass Sie verwenden sollten return, um einem auf diese Weise bezogenen Skript zu entkommen, nicht exit – sie sind wie Shell-Funktionen und exit beendet die Shell, aus der das Skript stammt.
  • @CharlesStewart Tatsächlich bin ich ‚ mit Skripts nicht vertraut. Vielen Dank!
  • ist source ./script dasselbe?
  • @amyassin: Ja, es ist
  • 1. . und source sind in Bash gleich. 2. Wir geben muss vor dem Dateinamen nicht ./ verwenden, wenn sich ‚ im selben Verzeichnis befindet. Es ist in Ordnung, nur Folgendes auszuführen: . script

Antwort

Erstellen Sie für kleine Aufgaben wie diese anstelle eines Skripts einen Alias wie diesen:

$ alias cdproj="cd /dir/web/www/proj" 

Sie sollten diesen zu Ihrer -Datei, wenn Sie möchten, dass sie für jede interaktive Shell festgelegt wird.

Jetzt können Sie diese als $ cdproj ausführen.

Kommentare

  • Sie können das Skript auch die auszuführenden Befehle wiederholen lassen und dann eval `./script` oder eval $(./script), um diese Befehle auszuführen. Dies ist ein gängiger Ansatz für Befehle, die die Umgebung der aufrufenden Shell ‚ aktualisieren müssen.
  • Seien Sie nur sehr vorsichtig, was Sie ausgeben, wenn Sie gehen möchten der Ansatz eval.

Antwort

Verwenden Sie exec bash am Ende

Ein Bash-Skript arbeitet mit seiner aktuellen Umgebung oder der seiner Kinder, aber niemals mit seiner übergeordnete Umgebung.

Diese Frage wird jedoch häufig gestellt, weil bei der Bash belassen werden soll Eingabeaufforderung in einem bestimmten Verzeichnis nach der Ausführung eines Bash-Skripts aus einem anderen Verzeichnis.

Wenn dies der Fall ist, führen Sie am Ende einfach eine untergeordnete Bash-Instanz aus des Skripts:

#!/usr/bin/env bash cd desired/directory exec bash 

Dadurch wird eine neue Unterschale erstellt. Geben Sie Strg + D oder exit ein, um zur ersten Shell zurückzukehren, in der das Skript ursprünglich gestartet wurde.

Update

Zumindest bei neueren Versionen von bash ist die exec in der letzten Zeile nicht mehr erforderlich. Darüber hinaus kann das Skript mithilfe der Umgebungsvariablen $SHELL so gestaltet werden, dass es mit jeder bevorzugten Shell funktioniert. Dies ergibt dann:

#!/usr/bin/env bash cd desired/directory $SHELL 

Kommentare

  • Es ist besser, das Skript einfach als Quelle zu verwenden, wie in der akzeptierten Antwort : Die Verwendung von exec wird normalerweise als letzter Ausweg eines Schurken angesehen. 🙂
  • Dieser Trick führt ‚ t nicht aus Arbeit in Debian 9 Stretch.
  • Dies ist der falsche Weg, um dies zu tun!
  • Da niemand die Probleme damit detailliert hat (ich sehe dich an, @Dennis): (1) Jedes Mal, wenn Sie dies ausführen, wird ein neuer, dauerhafter Bash-Prozess erstellt. Wenn Sie dies zehn- oder zwanzigmal in einer Sitzung tun, stapeln sich 11 bis 21 Bash-Prozesse. Dies kann die Leistung beeinträchtigen. Wenn Sie versuchen, die Sitzung sauber zu beenden, indem Sie exit (oder Strg + D) eingeben, müssen Sie dies 11 bis 21 Mal tun. (2) Ein weiterer Nachteil der Verwendung eines ausführbaren Skripts besteht darin, dass Sie in Ihrer Shell Shell-Optionen festlegen (z. B. dotglob oder globstar) Bei einer interaktiven Shell-Sitzung verlieren Sie sie, weil Sie eine neue Shell starten.
  • Sehr schöne Lösung! Ich ‚ habe meinen Alias in bash_profile umgeschrieben, sodass es sich jetzt um ein Skript handelt, das in einer separaten Datei gespeichert ist. Ich benutze das Skript, um zu einem neu erstellten temporären Ordner zu wechseln. Und jetzt ist es noch einfacher, eine temporäre Bash-Sitzung abzuhalten. SRP in Aktion! Vielen Dank!

Antwort

Während es Antworten gibt, die genau die gewünschte Aktion ausführen, ist dies eine Standardmethode Zweck ist es, eine symbolische Verknüpfung zu erstellen:

ln -s ~/web/www/project proj #use full path to dir! 

Dann können Sie cd mit dem Namen :

cd proj 

Diese Methode ist flexibler, da Sie ohne :

ls proj/ #note the endslash! vim proj/file.x 

Antwort

Hängt davon ab, was Sie tun „Eine andere Lösung kann darin bestehen, eine Funktion anstelle eines Skripts zu erstellen.

Beispiel:

Erstellen Sie eine Funktion in einer Datei, sagen wir /home/aidin/my-cd-script:

function my-cd() { cd /to/my/path } 

Fügen Sie es dann in Ihre bashrc oder Datei:

# Somewhere in rc file source /home/aidin/my-cd-script 

Jetzt können Sie es wie einen Befehl verwenden:

$ my-cd 

Antwort

Wenn Sie zwischen weit entfernten Verzeichnissen im Dateisystem wechseln. Ich werde autojump empfehlen.

Antwort

Für mich war der bequemste und flexibelste Ansatz eine Mischung aus einem Alias und einem Skript:

Skript mit beliebiger Logik erstellen

Hier erstelle ich ein Skript, das in ein Verzeichnis wechselt und die entsprechende Python-Umgebung aktiviert. Der Speicherort der Skripte ist beispielhaft in /path/to/workon_myproj.sh.

#!/usr/bin/env bash cd $HOME/workspace/myproj source .venv/bin/activate 

Erstellen Sie einen Alias, der das Skript

alias workon_myproj="source /path/to/workon_myproj.sh" 

Fügen Sie die Aliasdefinition in Ihre entsprechende Shell-Startdatei ein, z .profile, .bashrc oder .zshrc.

Ergebnis

Sie können jetzt einfach workon_myproj in einer Shell ausführen, die den Inhalt Ihres Skripts im gewünschten Verzeichnis abruft.

Erweiterbarkeit

Sie können Ihr Skript verbessern, um ein Argument so zu verwenden, dass es mit mehreren Projekten in einem bestimmten Arbeitsverzeichnis funktioniert, oder es mit einer git pull kombinieren, um die neuesten Änderungen sofort zu erhalten on … alles, was Sie tun, wenn Sie an einem bestimmten Projekt weiterarbeiten.

Antwort

Warum nicht verwenden? exec „es scheint genau das zu tun, was ich wünsche.

#!/bin/bash cd someplace exec bash ~/someplace 

Kommentare

  • Vorsicht vor Dingen, die scheint das zu sein, was Sie wollen. (Ein riesiges Holzpferd! Genau das, was ich wollte!) Jedes Mal, wenn Sie dies ausführen, wird ein neuer, anhaltender Bash-Prozess erstellt. Wenn Sie dies zehn- oder zwanzigmal in einer Sitzung tun, sind 11 bis 21 Bash-Prozesse gestapelt. Dies kann die Leistung beeinträchtigen. Wenn Sie versuchen, die Sitzung sauber zu beenden, indem Sie exit (oder Strg + D) eingeben, müssen Sie dies 11 bis 21 Mal tun. Ich konnte definitiv sehen, wo das ein Problem sein würde. Für mich, obwohl ich ‚ es einmal benutze, die Arbeit mache, die ich brauche, und dann beende. Wenn ‚ der einzige Nachteil ist, den ich habe kann damit leben. Wenn es andererseits eine bessere Lösung gibt, bin ich ‚ bereit, sie mir anzusehen.
  • Aidins Antwort auf diese Frage mit einer Shell-Funktion und Sachin Divekars Antwort mit einem Alias sind (IMO) bessere Lösungen als mit einem Skript . P.S. Ein weiterer Nachteil der Verwendung eines Skripts besteht darin, dass Sie beim Festlegen von Shell-Optionen (z. B. dotglob oder globstar) diese verlieren. weil du eine neue Shell startest. … (Fortsetzung)
  • (Fortsetzung)… P.P.S. Mir ist gerade aufgefallen, dass Sie im Grunde die Antwort von Serge Stroobandt wiederholen und sagen: „Warum nicht?“ Bei Stack Exchange Wir erwarten, dass Antworten neue Ideen und / oder Informationen liefern und nicht nur andere Antworten diskutieren.

Antwort

Dies kombiniert die Antwort von Serge mit einer nicht verwandten Antwort von David . Es ändert das Verzeichnis und startet dann, anstatt eine Bash-Shell zu erzwingen, die Standard-Shell des Benutzers . Dies ist jedoch erforderlich sowohl getent als auch /etc/passwd, um die Standard-Shell zu erkennen.

 #!/usr/bin/env bash cd desired/directory USER_SHELL=$(getent passwd <USER> | cut -d : -f 7) $USER_SHELL  

Natürlich hat dies immer noch den gleichen Mangel beim Erstellen einer verschachtelten Shell.

Antwort

Sie können dies mit einer Funktion oder mit & & tun. Die folgenden Beispiele installieren Zabbix und erstellen eine Datei mit einer Zeile darin.

Beispiel:

#!/bin/bash # Create Function: installZabbix(){ cd /usr/src/zabbix-4.2.4; ./configure --enable-agent; make install; cd /usr/src/; >file; echo "Hi, this is a file." >>file; } # Call the function: installZabbix 

oder:

#!/bin/bash cd /usr/src/zabbix-4.2.4 && ./configure --enable-agent && make install && cd /usr/src && >file && echo "Hi, this is a file." >>file 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.