Jeg undrer mig over, hvor en ny sti skal tilføjes til miljøvariablen PATH
. Jeg ved, at dette kan gøres ved at redigere .bashrc
(for eksempel), men det er ikke klart, hvordan man gør det.
På denne måde:
export PATH=~/opt/bin:$PATH
eller dette?
export PATH=$PATH:~/opt/bin
PATH=$PATH:~/opt/bin
eller
PATH=~/opt/bin:$PATH
afhængigt af, om du vil tilføje ~/opt/bin
i slutningen (der skal søges efter alle andre mapper, hvis der er et program med samme navn i flere mapper) eller i begyndelsen (der skal søges før alle andre mapper).
Du kan tilføje flere poster på samme tid. PATH=$PATH:~/opt/bin:~/opt/node/bin
eller variationer af denne rækkefølge fungerer fint. Lad være med at sætte export
i begyndelsen af linjen, da det medfører yderligere komplikationer (se nedenfor under "Bemærkninger om andre skaller end bash").
Hvis din PATH
bliver bygget af mange forskellige komponenter, kan du ende med at få dobbelte poster. Se https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-to-be-discovered-by-unix-which-command og https://unix.stackexchange.com/questions/40749/remove-duplicate-path-entries-with-awk-command for at undgå at tilføje dubletter eller for at fjerne dem.
Nogle distributioner sætter forresten automatisk ~/bin
ind i din PATH, hvis den findes.
Sæt linjen til at ændre PATH
i ~/.profile
, eller i ~/.bash_profile
, hvis det er det du har.
Bemærk at ~/.bash_rc
ikke læses af noget program, og at ~/.bashrc
er konfigurationsfilen for interaktive instanser af bash. Du bør ikke definere miljøvariabler i ~/.bashrc
. Det rigtige sted at definere miljøvariabler som PATH
er ~/.profile
(eller ~/.bash_profile
, hvis du er ligeglad med andre skaller end bash). Se [Hvad er forskellen på dem, og hvilken skal jeg bruge?] (https://superuser.com/questions/183870/difference-between-bashrc-and-bash-profile/183980#183980)
Lad være med at lægge den i /etc/environment
eller ~/.pam_environment
: det er ikke shell-filer, du kan ikke bruge substitutioner som $PATH
derinde. I disse filer kan du kun tilsidesætte en variabel, ikke tilføje til den.
Du behøver ikke export
hvis variablen allerede er i miljøet: enhver ændring af variablens værdi afspejles i miljøet. ¹ PATH
er stort set altid i miljøet; alle unix-systemer sætter den meget tidligt (som regel i den allerførste proces, faktisk).
Ved login kan du stole på, at PATH
allerede er i miljøet og allerede indeholder nogle systemmapper. Hvis du skriver et script, der kan blive udført tidligt, mens du opretter en slags virtuelt miljø, kan det være nødvendigt at sikre, at PATH
ikke er tomt og eksporteret: hvis PATH
stadig ikke er indstillet, så vil noget som PATH=$PATH:/some/directory
sætte PATH
til :/some/directory
, og den tomme komponent i begyndelsen betyder den aktuelle mappe (som .:/some/directory
).
if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi
I bash, ksh og zsh er export
en speciel syntaks, og både PATH=~/opt/bin:$PATH
og export PATH=~/opt/bin:$PATH
gør endda det rigtige. I andre Bourne/POSIX-lignende shells såsom dash (som er /bin/sh
på mange systemer), bliver export
analyseret som en almindelig kommando, hvilket indebærer to forskelle:
~
bliver kun analyseret i begyndelsen af et ord, undtagen i opgaver (se https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-to-be-discovered-by-unix-which-command/25704#25704 for detaljer);$PATH
uden for dobbelte anførselstegn [brydes, hvis PATH
indeholder whitespace eller \[*?
] (https://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters).Så i skaller som dash, sætter export PATH=~/opt/bin:$PATH
PATH
til den bogstavelige streng ~/opt/bin/:
efterfulgt af værdien af PATH
op til det første mellemrum.
PATH=~/opt/bin:$PATH
(en simpel tildeling) [doesn't require quotes] (https://unix.stackexchange.com/questions/68694/when-is-double-quoting-necessary/68748#68748) og gør det rigtige. Hvis du vil bruge export
i et portabelt script, skal du skrive export PATH="$HOME/opt/bin:$PATH"
, eller PATH=~/opt/bin:$PATH; export PATH
(eller PATH=$HOME/opt/bin:$PATH; export PATH
for portabilitet til selv Bourne-shellen, der ikke accepterede export var=value
og ikke gjorde tildeudvidelse).
¹ Dette var ikke sandt i Bourne-shells (som i den egentlige Bourne-shell, ikke moderne POSIX-stil-shells), men det er meget usandsynligt, at du støder på sådanne gamle shells i dag.
Begge måder virker, men de gør ikke det samme: elementerne i PATH
kontrolleres fra venstre til højre. I dit første eksempel vil eksekverbare programmer i ~/opt/bin
have forrang frem for dem, der f.eks. er installeret i /usr/bin
, hvilket måske eller måske ikke er det, du ønsker.
Især ud fra et sikkerhedsmæssigt synspunkt er det farligt at tilføje stier forrest, for hvis nogen kan få skriveadgang til din ~/opt/bin
, kan de f.eks. lægge en anden ls
deri, som du så sandsynligvis vil bruge i stedet for /bin/ls
uden at bemærke det. Forestil dig nu det samme for ssh
eller din browser eller andet... (Det samme gælder tredobbelt for at sætte . i din sti).
Jeg er forvirret over spørgsmål 2 (som siden er fjernet fra spørgsmålet, da det skyldtes et uvedkommende spørgsmål):
Hvad'er en brugbar måde at tilføje flere stier på forskellige linjer? I første omgang troede jeg, at dette kunne gøre tricket:
export PATH=$PATH:~/opt/bin export PATH=$PATH:~/opt/node/bin
men det gør det ikke, fordi den anden tildeling ikke kun tilføjer
~/opt/node/bin
, men også hele den tidligere tildeltePATH
.Dette er en mulig løsning:
< <!--language: lang-bash --&>
export PATH=$PATH:~/opt/bin:~/opt/node/bin
men af hensyn til læsbarheden ville jeg foretrække at have én tildeling for én sti.
Hvis du siger
PATH=~/opt/bin
er det alt det, der vil være i din PATH. PATH er bare en miljøvariabel, og hvis du vil tilføje noget til PATH, skal du genopbygge variablen med præcis det indhold, du ønsker. Dvs. det du giver som eksempel til spørgsmål 2 er præcis det du vil gøre, med mindre jeg helt misser pointen med spørgsmålet.
Jeg bruger begge former i min kode. Jeg har en generisk profil, som jeg installerer på alle de maskiner, jeg arbejder på, og som ser sådan ud, for at tage højde for potentielt manglende mapper:
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