Ik'ben benieuwd waar een nieuw pad moet worden toegevoegd aan de PATH
omgevingsvariabele. Ik weet dat dit kan door (bijvoorbeeld) .bashrc
te bewerken, maar het'is niet duidelijk hoe je dit moet doen.
Op deze manier:
export PATH=~/opt/bin:$PATH
of dit?
export PATH=$PATH:~/opt/bin
PATH=$PATH:~/opt/bin
of
PATH=~/opt/bin:$PATH
afhankelijk van of u ~/opt/bin
aan het eind wilt toevoegen (om te doorzoeken na alle andere directories, in het geval er een programma met dezelfde naam in meerdere directories staat) of aan het begin (om te doorzoeken vóór alle andere directories).
U kunt meerdere regels tegelijk toevoegen. PATH=$PATH:~/opt/bin:~/opt/node/bin
of variaties op deze volgorde werken prima. Zet export
niet aan het begin van de regel, want dat heeft extra complicaties (zie hieronder onder "Opmerkingen over shells anders dan bash").
Als uw PATH
door veel verschillende componenten wordt gebouwd, kunt u dubbele regels krijgen. Zie https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-to-be-discovered-by-unix-which-command en https://unix.stackexchange.com/questions/40749/remove-duplicate-path-entries-with-awk-command om te voorkomen dat duplicaten worden toegevoegd of om ze te verwijderen.
Sommige distributies zetten trouwens automatisch ~/bin
in je PATH als het bestaat.
Zet de regel om PATH
aan te passen in ~/.profile
, of in ~/.bash_profile
als dat is wat u heeft.
Merk op dat ~/.bash_rc
door geen enkel programma wordt gelezen, en ~/.bashrc
is het configuratiebestand van interactieve instanties van bash. U moet geen omgevingsvariabelen definiëren in ~/.bashrc
. De juiste plaats om omgevingsvariabelen zoals PATH
te definiëren is ~/.profile
(of ~/.bash_profile
als u niets geeft om andere shells dan bash). Zie Wat's het verschil tussen hen en welke moet ik gebruiken?
Zet het niet in /etc/environment
of ~/.pam_environment
: dit zijn geen shell-bestanden, je kunt er geen substituties in gebruiken zoals $PATH
. In deze bestanden kunt u alleen een variabele overschrijven, niet toevoegen.
Je hebt export
niet nodig als de variabele al in de omgeving zit: elke verandering van de waarde van de variabele wordt in de omgeving gereflecteerd.¹ PATH
zit vrijwel altijd in de omgeving; alle unix-systemen stellen het al heel vroeg in (meestal in het allereerste proces, in feite).
Als je inlogt, kun je erop vertrouwen dat PATH
al in de omgeving zit, en al een aantal systeemmappen bevat. Als je een script schrijft dat vroeg kan worden uitgevoerd tijdens het opzetten van een soort virtuele omgeving, moet je er misschien voor zorgen dat PATH
niet leeg is en geëxporteerd wordt: als PATH
nog niet is ingesteld, dan zou iets als PATH=$PATH:/some/directory
PATH
instellen op :/some/directory
, en de lege component aan het begin betekent de huidige directory (zoals .:/some/directory
).
if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi
In bash, ksh en zsh is export
een speciale syntaxis, en zowel PATH=~/opt/bin:$PATH
als export PATH=~/opt/bin:$PATH
doen zelfs het juiste. In andere Bourne/POSIX-stijl shells zoals dash (die op veel systemen /bin/sh
is), wordt export
geparsed als een gewoon commando, wat twee verschillen met zich meebrengt:
~
wordt alleen aan het begin van een woord geparseerd, behalve in opdrachten (zie https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-to-be-discovered-by-unix-which-command/25704#25704 voor details);$PATH
buiten dubbele aanhalingstekens [breekt als PATH
spaties bevat of [*?
](https://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters).Dus in shells zoals dash, stelt export PATH=~/opt/bin:$PATH
PATH
in op de letterlijke string ~/opt/bin/:
gevolgd door de waarde van PATH
tot aan de eerste spatie.
PATH=~/opt/bin:$PATH
(een kale toewijzing) heeft geen aanhalingstekens nodig en doet het juiste. Als je export
in een portable script wilt gebruiken, moet je export PATH="$HOME/opt/bin:$PATH"
schrijven, of PATH=~/opt/bin:$PATH; export PATH
(of PATH=$HOME/opt/bin:$PATH; export PATH
voor portabiliteit naar zelfs de Bourne shell die geen export var=value
accepteerde en geen tilde-expansie deed).
¹ Dit was niet waar in Bourne shells (zoals in de echte Bourne shell, niet moderne POSIX-stijl shells), maar het is hoogst onwaarschijnlijk dat je zulke oude shells tegenwoordig nog tegenkomt.
Beide manieren werken, maar ze doen niet hetzelfde: de elementen van PATH
worden van links naar rechts gecontroleerd. In uw eerste voorbeeld zullen uitvoerbare bestanden in ~/opt/bin
voorrang hebben boven die geïnstalleerd in bijvoorbeeld /usr/bin
, wat al dan niet is wat u wilt.
In het bijzonder, vanuit een veiligheidsperspectief, is het gevaarlijk om paden aan de voorkant toe te voegen, want als iemand schrijftoegang kan krijgen tot uw ~/opt/bin
, kan hij, bijvoorbeeld, een ander ls
daar in zetten, dat u'dan waarschijnlijk zou gebruiken in plaats van /bin/ls
zonder het te merken. Stel je nu hetzelfde voor voor ssh
of je browser of keuze... (Hetzelfde geldt drievoudig voor het plaatsen van . in je pad).
Ik ben in de war door vraag 2 (die inmiddels uit de vraag is verwijderd omdat er een kwestie speelde die er niets mee te maken had):
What's a workable way to append more paths on different lines? Aanvankelijk dacht ik dat dit de truc zou kunnen doen:
export PATH=$PATH:~/opt/bin export PATH=$PATH:~/opt/node/bin
maar dat doet het niet omdat de tweede opdracht niet alleen append
~/opt/node/bin
, maar ook het helePATH
dat eerder is toegewezen.Dit is een mogelijke workaround:
export PATH=$PATH:~/opt/bin:~/opt/node/bin
maar voor de leesbaarheid zou ik'liever één toewijzing voor één pad hebben.
Als je zegt
PATH=~/opt/bin
dat is alles wat in je PATH zal staan. PATH is gewoon een omgevingsvariabele, en als je iets aan het PATH wilt toevoegen, moet je de variabele opnieuw opbouwen met precies de inhoud die je wilt. Dat wil zeggen, wat je als voorbeeld geeft bij vraag 2 is precies wat je wilt doen, tenzij ik'm totally missing the point of the question.
Ik gebruik beide vormen in mijn code. Ik heb een generiek profiel dat ik installeer op elke machine waar ik op werk dat er zo uitziet, om tegemoet te komen aan mogelijk ontbrekende mappen:
export PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11
# add optional items to the path
for bindir in $HOME/local/bin $HOME/bin; do
if [ -d $bindir ]; then
PATH=$PATH:${bindir}
fi
done