Aktualisieren Sie `.bashrc` und laden Sie neu

Aktualisieren Sie `.bashrc` und laden Sie neu

Ich habe ein Skript, das am Ende meiner Seite einige Zeilen einfügt .bashrc. Gibt es eine Möglichkeit, die .bashrcaus dem Skript heraus zu beziehen, sodass diese Änderungen erhalten bleiben, wenn das Skript beendet ist? Hier ist ein MWE eines ähnlichen Skripts:

#!/bin/bash

echo "export MyDir='MyAnalysis'" >> ~/.bashrc
echo "alias llA='ll MyAnalysis'" >> ~/.bashrc

source ~/.bashrc

Wenn das Skript ausgeführt wurde, sind weder MyDirnoch llAverfügbar, es sei denn, die .bashrcDatei wird manuell bezogen.

Antwort1

Nicht direkt.

Ihr Skript wird in einem separaten Prozess von Ihrer interaktiven Shell ausgeführt. Alle Änderungen, die die Shell des Skripts an der Umgebung vornimmt, verschwinden, wenn diese Shell beendet wird.Ein untergeordneter Prozess darf die Umgebung des übergeordneten Prozesses nicht ändern.

Dinge die du tun kannst:

  • das Skript aktualisiert Ihre .bashrc und tut sonst nichts: Sie beziehen Ihre bashrc als Quelle, wenn das Skript erfolgreich abgeschlossen wird

    bash yourScript.bash && source .bashrc
    
  • das Skript aktualisiert .bashrc unddrucktder Quellbefehl: Stellen Sie sicher, dass nichts anderes gedruckt wird. Dann evalführen Sie das Skript aus.

    eval "$(bash yourScript.bash)"
    
  • das Skript aktualisiert die .bashrc undAuchdruckt aus, was es tut. Sie werten es aus: Dies ist das Skript

    #!/bin/bash
    exec > >(tee -a "$HOME/.bashrc")
    
    echo "export MyDir='MyAnalysis'"
    echo "alias llA='ll MyAnalysis'"
    

    und du führst es aus wie

    eval "$(bash yourScript.bash)"
    
  • aktualisieren Sie nicht dieElternteilShell, sondern starten Sie eine neue interaktive Shell, die die bashrc liest

    #!/bin/bash
    {
        echo "export MyDir='MyAnalysis'"
        echo "alias llA='ll MyAnalysis'"
    } >> ~/.bashrc
    exec bash -i
    

    Die übergeordnete Shell wird nicht aktualisiert.


Wenn Sie den .bashrc-updating Code zu einemFunktion, es wird wie erwartet funktionieren, da die Funktionen in der aktuellen Shell ausgeführt werden (standardmäßig):

addMyAnalysis() {
    echo "export MyDir='MyAnalysis'" >> ~/.bashrc
    echo "alias llA='ll MyAnalysis'" >> ~/.bashrc
    source ~/.bashrc
}

Eine alternative Technik: Erstellen Sie ein Verzeichnis „conf“ $HOME/.bash.d. Schreiben Sie dort die Bash-Datei hinein.

# this is "~/.bash.d/some_file.bash"
export MyDir='MyAnalysis'
alias llA='ll MyAnalysis'

Und Ihre .bashrc-Quelle ist jede Bash-Datei in diesem Verzeichnis:

if [[ -d ~/.bash.d ]]; then
    shopt -s nullglob
    for f in ~/.bash.d/*.bash; do
        source "$f"
    done
    shopt -u nullglob
fi

Antwort2

Wie @glenn-jackman anmerkt, erfolgt Ihr Sourcing in einer Untershell, in der Ihr Skript ausgeführt wird, und am Ende Ihres Skripts kehren Sie zur übergeordneten Shell zurück, in der kein Sourcing stattgefunden hat und auch .bashrc nicht erneut ausgeführt wird – diese Trennung von übergeordneter und Untershell ergibt sich aus allgemeinen Sicherheitsüberlegungen.

Was Sie suchen, ist exec bash, aber nicht innerhalb Ihres Skripts, sondern damit gruppiert, d. h.

bash your-script.sh && exec bash

Das verhält sichals obSie würden eine Quelle finden und dann in der Hülle bleiben, in der Sie eine Quelle gefunden haben.ersetztdie aktuelle Shell durch eine neue Shell, und diese neue Shell startet, wie jede (interaktive) Shell, mit der Ausführung Ihrer .bashrc, jetzt mit Ihren Änderungen, und das Gleiche gilt für jede neue Shell/jedes neue Terminal, das Sie starten.

Beachten Sie, dass wenn Sie in Ihrem Skript „exec bash“ ausführen, dies die Subshell, in der Ihr Skript ausgeführt wird, ersetzen würde, es aber weiterhin eine Subshell wäre.

Wenn Ihr Ziel eine dynamische und temporäre Manipulation von .bashrc ist, sollten Sie die Vorschläge von @glenn-jackman berücksichtigen, Ihre Änderungen in separaten Dateien vorzunehmen, die Sie jederzeit problemlos löschen können. Dafür könnten Sie auch einfach eine permanente Zeile haben

[ -f ~/.bashrc-temporary-addons ] && source ~/.bashrc-temporary-addons

am Ende Ihrer .bashrc und dann tun (! nureins">" in der ersten Zeile, um eine neue Datei zu haben)

echo "" > ~/.bashrc-temporary-addons
echo "export MyDir='MyAnalysis'" >> ~/.bashrc-temporary-addons
echo "alias llA='ll MyAnalysis'" >> ~/.bashrc-temporary-addons

und an einem Punkt Ihrer Wahl einfach

rm ~/.bashrc-temporary-addons

(Aufgrund des „-f“-Tests tritt kein Fehler auf, wenn „~/.bashrc-temporary-addons“ nicht existiert.)

Wenn Ihre .bashrc-Manipulationen so lange wie Ihre Sitzung bestehen bleiben sollen, also bis zur Abmeldung (aber nicht bei der nächsten Anmeldung wieder erscheinen), dann könnten Sie eine .bash_logoutDatei erstellen, um temporäre Dateien in „bash.d/“ oder den gesamten Inhalt von „bash.d/“ oder „~/.bashrc-temporary-addons“ zu löschen.

verwandte Informationen