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, nichtexit
– sie sind wie Shell-Funktionen undexit
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.
.
undsource
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`
odereval $(./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
oderglobstar
) 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
oderglobstar
) 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