Frage Irgendwas stimmt nicht mit meinem `.profile`


Ich habe vor kurzem ein paar Software installiert und musste ihre hinzufügen bin/ Verzeichnisse zu meinem PATH. Bisher nichts Außergewöhnliches. Aber ich beschloss, es schlau zu machen und schrieb einen Teil von mir neu .profile also musste ich die paar Zeilen nicht immer wieder kopieren / einfügen. Hier war meine Idee:

# Create an array with directories to be added to PATH
declare -a addpath=("$HOME/bin" "$HOME/.cabal/bin" "/opt/vert.x/current/bin")

# Add directories recursively
for dir in "${addpath[@]}"; do
if [ -d "$dir" ]; then
    PATH="$dir:$PATH"
fi
done

Ich dachte, das hätte gut geklappt ... bis ich meinen PC neu gestartet und mich aus der Sitzung ausgesperrt habe, als ich mich anzumelden versuchte. Es hat eine Weile gedauert, bis ich herausgefunden hatte, dass es tatsächlich wegen meiner .profile; Sobald ich diese Zeilen kommentiert habe, konnte ich mich in meine Sitzung einloggen, ohne zurückgeworfen zu werden.

Meine Frage ist; Was habe ich mit diesen Zeilen falsch gemacht? Gibt es einen Syntaxfehler? Gibt es einen anderen / besseren Weg, das zu tun? Was ist passiert?


4
2017-08-19 23:55


Ursprung




Antworten:


In dem Standard-Setup auf Ubuntu 12.04, das .profile Datei wird geladen von /usr/sbin/lightdm-session. Dies ist ein Shell-Skript, ausgeführt von /bin/sh.

Auf Ubuntu, /bin/sh ist Strich. Sie haben Funktionen von verwendet bash Dieser Strich unterstützt nicht. Dash und Bash haben beide die gleichen Kernfunktionen, aber Dash bleibt bei diesen Kernfunktionen, um schnell und klein zu sein, während Bash viele Funktionen auf Kosten von mehr Ressourcen hinzufügt. Es ist üblich, Dash für Skripts zu verwenden, die keine zusätzlichen Funktionen und Bash für die interaktive Verwendung benötigen (though zsh  hat eine Menge schöner Eigenschaften).

Dash hat keine Arrays und auch keinen declare eingebaut, also bombardiert es auf dieser Linie. Sie können die Liste der Pfade inline einfügen:

for dir in "$HOME/bin" "$HOME/.cabal/bin" "/opt/vert.x/current/bin"; do
  if [ -d "$dir" ]; then
    PATH="$dir:$PATH"
  fi
done

Sehen Behalte Duplikate aus $ PATH auf der Quelle wenn Sie sicherstellen möchten, dass Sie nicht mit doppelten Einträgen enden.


Anstatt für jedes von Ihnen installierte Programm neue Verzeichnisse zu PATH hinzuzufügen, sollten Sie stattdessen symbolische Verknüpfungen in einem vorhandenen Verzeichnis einrichten. Zum ~/.cabal/binDu wirst es auf deinem Weg haben wollen, weil ausführbare Dateien dort kommen und gehen werden; Ich würde es jedoch am Ende des PATH setzen, um mögliche Konflikte mit bestehenden Programmen auf Ihrem System zu vermeiden. ~/bin ist bereits in Ihrem PATH auf Ubuntu. Für Programme, die Sie manuell installieren, z. B. vert.x, verstauen oder xstow ist gut für die Verwaltung von symbolischen Links. Sehen Verfolgen von Programmen für eine Einführung in Stow.


6
2017-08-20 07:40



Entschuldigung für die Zeit, die ich brauchte, um zu dir zurück zu kommen. Vielen Dank damit viel für deine ausführliche Antwort, ich habe definitiv etwas hier gelernt! - Sheljohn


Ich denke, dass in Ihrem Fall die beste Vorgehensweise, um Ihre Binärdateien als Befehle zur Verfügung zu stellen, ist, das, was Sie benötigen, mit dem / usr / bin zu verknüpfen. Versehen mit $ PATH ist nicht immer eine gute Sache zu tun.

Sie können "cp" verwenden, um symbolische Links rekursiv wie folgt zu erstellen:

cp -rs $HOME/bin/* /usr/bin #This will link all non hidden files
cp -rs $HOME/bin/.[^.]* /usr/bin # This will link all the hidden files

Passen Sie dies einfach Ihrem Szenario an und verwenden Sie dabei die gleiche Logik Ihres aktuellen Codes.

BEARBEITEN: Sie können nur die erste Zeile des obigen Codes verwenden, wenn Sie dotglob setzen wahr auf Bash. So was:

shopt -s dotglob #This will make Bash include filenames beginning with a '.' in the results of filename expansion
cp -rs $HOME/bin/* /usr/bin #Now, this will link ALL files in that directory to the destination

EDIT 2: Wie Sie in den Kommentaren lesen können, ist es besser, dass Sie / usr / local / bin anstelle von / usr / bin verwenden. Lesen Sie die Kommentare, um zu verstehen, warum.


-2
2017-08-20 00:59



Es ist genau das Gegenteil. Du solltest dich nie damit anfreunden /usr/binLassen Sie den Paketmanager es verwalten. Sie könnten Programme hinzufügen /usr/local/bin, aber als symbolische Links, nicht als Kopien. - Gilles
Wenn Sie meinen Code lesen, werden Sie sehen, dass ich keine Kopien verwende. 'cp' kann symbolische Links schreiben anstatt zu kopieren. Dies ist einfacher, wenn Sie alle symbolischen Links mit 'ln' erstellen. Was du über / usr / bin sagst, kann hier auf Ubuntu halb wahr sein (das benutzt tatsächlich einen Paket-Manager), aber ist kein globales Wahr, erinnere dich daran. PS .: NIEMALS ist ein komisches Wort auf der Linux-Welt. Sie können das natürlich tun (und alles wird in den meisten Fällen funktionieren). Der Unterschied besteht darin, dass / usr / bin die von der Verteilung verwaltete Software hostet und / usr / local / bin die andere Software hostet. Aber das ist eine Konvention, kein technisches Problem. - Alexandre Teles
Oh, richtig, ich hatte das verpasst -s. Aber der Hauptteil meines Einwands steht immer noch: nicht durcheinander bringen /usr/bin. Es ist wahr unter Ubuntu und so ziemlich jedem anderen Unix. Sicher, es ist kein Gesetz der Physik. Es ist eine Konvention, als würde man auf einer bestimmten Straßenseite fahren. Einige Konventionen sind wichtig. - Gilles
@AlexandreTeles Vielen Dank für Ihre Antwort. Ich weiß, dass das Downvoting sehr frustrierend sein kann. Sie wollten helfen, und Sie wurden dafür bestraft. Es tut mir wirklich leid (ich habe mich nicht selbst herabgesetzt, auch wenn ich es tun sollte). Die Wahrheit ist, du liegst eigentlich falsch, aber ich ermutige dich, die folgenden zwei Artikel zu lesen, um herauszufinden, warum: wiki.debian.org/FilesystemHierarchyStandard und dann unix.stackexchange.com/questions/11544/ .... Mit freundlichen Grüßen :) - Sheljohn