Finden Sie heraus, welche Skripte beim Start von Bash ausgeführt werden

14

Nach dem Starten eines Bash-Terminals habe ich festgestellt, dass die Variable PATH doppelte Einträge enthält. Mein Terminal startet eine Anmelde-Shell , wird also ~/.bash_profilevon ~/.profileund gefolgt ~/.bashrc. Nur in ~/.profileerstelle ich die Pfade Einträge, die dupliziert werden.

Um pedantisch zu sein, ist dies die Reihenfolge, in der die zu beschaffenden Dateien beschafft werden:

Sourced /etc/profile
Sourced /etc/bash.bashrc
Sourced .bash_profile
Sourced .profile
Sourced .bashrc

Bevor jemand dies als Duplikat von "PATH-Variable enthält Duplikate" markiert, lesen Sie weiter.

Zuerst dachte ich, das hätte damit zu tun ~/.profile, dass ich zweimal beschafft wurde, also musste ich die Datei jedes Mal, wenn sie beschafft wurde, in eine Protokolldatei schreiben, und überraschenderweise protokollierte sie nur einen Eintrag, was mir sagt, dass sie nur einmal beschafft wurde. Noch überraschender ist die Tatsache, dass, wenn ich die Einträge auskommentiere, die in waren ~/.profile, die Einträge immer noch in der PATHVariablen angezeigt werden. Dies hat mich zu drei Schlussfolgerungen geführt, von denen eine schnell ausgeschlossen wurde:

  1. Bash ignoriert gültige Bash-Kommentare und führt den kommentierten Code weiterhin aus
  2. Es gibt ein Skript, das den ~/.profileCode liest und ignoriert, der eine Ausgabe druckt (z. B. die Protokolldatei).
  3. Es gibt noch eine Kopie von mir ~/.profile, die woanders bezogen wird

Das erste habe ich schnell festgestellt, dass es aufgrund einiger schneller Tests nicht der Fall ist. Bei der zweiten und dritten Option brauche ich Hilfe.

Wie sammle ich ein Protokoll von Skripten, die beim Start meines Terminals ausgeführt werden? Ich habe echoin den von mir überprüften Dateien nachgeschlagen, ob sie von Bash stammen, aber ich muss eine schlüssige Methode finden, die die Ausführung bis zu dem Zeitpunkt nachzeichnet, an dem das Terminal für mich zum Eingeben bereit ist.

Wenn dies nicht möglich ist, kann jemand vorschlagen, wo ich sonst nachsehen kann, welche Skripte ausgeführt werden .


Zukunftsbezug

Dies ist das Skript, das ich jetzt verwende, um es meinem Pfad hinzuzufügen:

function add_to_path() {
    for path in ${2//:/ }; do
        if ! [[ "${!1}" =~ "${path%/}" ]]; then # ignore last /
            new_path="$path:${!1#:}"
            export "$1"="${new_path%:}" # remove trailing :
        fi
    done
}

Ich benutze es so:

add_to_path 'PATH' "/some/path/bin"

Das Skript prüft, ob der Pfad in der Variablen bereits vorhanden ist, bevor er vorangestellt wird.

Für zsh-Benutzer können Sie dieses Äquivalent verwenden:

function add_to_path() {
    for p in ${(s.:.)2}; do
        if [[ ! "${(P)1}" =~ "${p%/}" ]]; then
            new_path="$p:${(P)1#:}"
            export "$1"="${new_path%:}"
        fi
    done
}

Bearbeiten 28/8/2018

Eine weitere Sache, die ich mit diesem Skript machen konnte, war, den Pfad zu korrigieren. Also .bashrcmache ich am Anfang meiner Datei so etwas:

_temp_path="$PATH"
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin'
add_to_path 'PATH' "$_temp_path"
unset _temp_path

Es liegt an Ihnen, mit was das PATHbeginnen soll. Untersuche PATHzuerst, um zu entscheiden.

smac89
quelle
Bash liest nur aus, ~/.profile wenn ~/.bash_profilenicht vorhanden ist ...
Jasonwryan
@Jasonwryan, ich Quelle ~/.profileund ~/.bashrcvon~/.bash_profile
smac89

Antworten:

29

Wenn Ihr System über Folgendes verfügt strace, können Sie die von der Shell geöffneten Dateien auflisten, z. B. mit

echo exit | strace bash -li |& grep '^open'

( -liBedeutet interaktive Anmeldeshell; nur -ifür eine interaktive Shell ohne Anmeldung verwenden.)

Daraufhin wird eine Liste der Dateien angezeigt, die die Shell geöffnet hat oder zu öffnen versucht hat. Auf meinem System lauten sie wie folgt:

  1. /etc/profile
  2. /etc/profile.d/*(verschiedene Skripte in /etc/profile.d/)
  3. /home/<username>/.bash_profile (dies schlägt fehl, ich habe keine solche Datei)
  4. /home/<username>/.bash_login (dies schlägt fehl, ich habe keine solche Datei)
  5. /home/<username>/.profile
  6. /home/<username>/.bashrc
  7. /home/<username>/.bash_history (Befehlszeilenverlauf; dies ist kein Skript)
  8. /usr/share/bash-completion/bash_completion
  9. /etc/bash_completion.d/* (verschiedene Skripte mit Autovervollständigungsfunktionen)
  10. /etc/inputrc (definiert Tastenkombinationen; dies ist kein Skript)

Verwenden Sie man stracefür weitere Informationen.

AlexP
quelle
Vielen Dank für Ihre Eingabe, aber ich denke, mit meiner Bash stimmt etwas nicht. Laufen echo $0im Terminal gibt -basheher als das zu erwarten bash. Haben Sie noch weitere Vorschläge dazu?
smac89
3
@ smac89: Das ist normal für eine Login-Shell. Bash verhält sich als Anmeldeshell, wenn das erste Zeichen von $0ein Bindestrich -ist oder mit der Option aufgerufen wird -l.
AlexP
OK, das ist eine Erleichterung. Ich habe den Befehl ausgeführt, den Sie gegeben haben, und die Ausgabe sieht sehr kompliziert aus, aber dennoch enthalten alle angezeigten Dateien nicht die doppelten Einträge. Dies führt mich zu der Annahme, dass die doppelten Einträge auftreten, wenn ich mich zum ersten Mal in meinem Konto anmelde. Das heißt, dass die Einträge in dieser Datei anfänglich von einer Quelle stammen und dass dies erneut erfolgt, wenn ich das Terminal öffne. Eigentlich denke ich das könnte es sein. Wenn ich mich in meinem Konto anmelde, werden die Einträge übernommen, und wenn ich das Terminal wieder öffne, wird der Vorgang wiederholt. Klingt das möglich
smac89
Warum debuggen Sie nicht auf die altmodische Art und Weise, indem Sie echo PATH=\""$PATH"\"am Anfang und Ende von .profileund setzen .bashrc? Und warum tun Sie nicht das, was jeder tut, und setzen den PATH entweder vollständig oder, wenn Sie ein Verzeichnis hinzufügen, geschützt auf echo ":$PATH:" | grep -q ":/path/to/dir:" || export PATH="$PATH:/path/to/dir":?
AlexP
3
Verwenden Sie sudo bash -c "echo exit|dtruss bash -li|& less|grep '^open'"auf MacOS. (ersetzen Sie einfach stracemit dtruss)
Max Coplan