Mi sto chiedendo dove deve essere aggiunto un nuovo percorso alla variabile d'ambiente PATH
. So che questo può essere realizzato modificando .bashrc
(per esempio), ma non è chiaro come farlo.
In questo modo:
-- lingua: bash -->
export PATH=~/opt/bin:$PATH
o questo?
export PATH=$PATH:~/opt/bin
PATH=$PATH:~/opt/bin
o
PATH=~/opt/bin:$PATH
a seconda che tu voglia aggiungere ~/opt/bin
alla fine (da cercare dopo tutte le altre directory, nel caso ci sia un programma con lo stesso nome in più directory) o all'inizio (da cercare prima di tutte le altre directory).
Puoi aggiungere più voci allo stesso tempo. PATH=$PATH:~/opt/bin:~/opt/node/bin
o variazioni sull'ordine funzionano bene. Non mettere export
all'inizio della linea perché ha ulteriori complicazioni (vedi sotto "Note sulle shell diverse da bash").
Se il tuo PATH
viene costruito da molti componenti diversi, potresti ritrovarti con voci duplicate. Vedere https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-to-be-discovered-by-unix-which-command e https://unix.stackexchange.com/questions/40749/remove-duplicate-path-entries-with-awk-command per evitare di aggiungere duplicati o rimuoverli.
Alcune distribuzioni mettono automaticamente ~/bin
nel tuo PATH se esiste, comunque.
Metti la linea per modificare il PATH
in ~/.profile
, o in ~/.bash_profile
se è quello che hai.
Nota che ~/.bash_rc
non è letto da nessun programma, e ~/.bashrc
è il file di configurazione delle istanze interattive di bash. Non dovresti definire variabili d'ambiente in ~/.bashrc
. Il posto giusto per definire variabili d'ambiente come PATH
è ~/.profile
(o ~/.bash_profile
se non ti interessa la shell diversa da bash). Vedi Qual è la differenza tra loro e quale dovrei usare?
Non metterlo in /etc/environment
o ~/.pam_environment
: questi non sono file di shell, non puoi usare sostituzioni come $PATH
lì dentro. In questi file puoi solo sovrascrivere una variabile, non aggiungerla.
Non hai bisogno di export
se la variabile è già nell'ambiente: ogni cambiamento del valore della variabile si riflette nell'ambiente.¹ PATH
è praticamente sempre nell'ambiente; tutti i sistemi unix lo impostano molto presto (di solito nel primo processo, infatti).
Al momento del login, si può contare sul fatto che PATH
sia già nell'ambiente, e che contenga già alcune directory di sistema. Se stai scrivendo uno script che può essere eseguito all'inizio mentre imposti un qualche tipo di ambiente virtuale, potresti aver bisogno di assicurarti che PATH
non sia vuoto ed esportato: se PATH
non è ancora impostato, allora qualcosa come PATH=$PATH:/some/directory
imposterà PATH
su :/some/directory
, e il componente vuoto all'inizio significa la directory corrente (come .:/some/directory
).
if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi
In bash, ksh e zsh, export
è una sintassi speciale, e sia PATH=~/opt/bin:$PATH
che export PATH=~/opt/bin:$PATH
fanno la cosa giusta. In altre shell in stile Bourne/POSIX come dash (che è /bin/sh
su molti sistemi), export
viene analizzato come un comando ordinario, il che implica due differenze:
~
viene analizzato solo all'inizio di una parola, tranne che nelle assegnazioni (vedi https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-to-be-discovered-by-unix-which-command/25704#25704 per i dettagli);$PATH
fuori dai doppi apici [si interrompe se PATH
contiene spazi bianchi o \[*?
](https://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters).Così in shell come dash, imposta export PATH=~/opt/bin:$PATH
PATH
alla stringa letterale ~/opt/bin/:
seguita dal valore di PATH
fino al primo spazio.
PATH=~/opt/bin:$PATH
(un'assegnazione nuda) non richiede virgolette e fa la cosa giusta. Se vuoi usare export
in uno script portatile, devi scrivere export PATH="$HOME/opt/bin:$PATH"
, o PATH=~/opt/bin:$PATH; export PATH
(o PATH=$HOME/opt/bin:$PATH; export PATH
per la portabilità anche alla shell Bourne che non accettava export var=value
e non faceva l'espansione tilde).
¹ Questo non era vero nelle shell Bourne (come nella vera shell Bourne, non nelle moderne shell in stile POSIX), ma è altamente improbabile incontrare tali vecchie shell in questi giorni;
Entrambi i modi funzionano, ma non fanno la stessa cosa: gli elementi di PATH
sono controllati da sinistra a destra. Nel tuo primo esempio, gli eseguibili in ~/opt/bin
avranno la precedenza su quelli installati, per esempio, in /usr/bin
, che può essere o meno quello che vuoi.
In particolare, da un punto di vista della sicurezza, è pericoloso aggiungere percorsi all'inizio, perché se qualcuno può ottenere l'accesso in scrittura al tuo ~/opt/bin
, può metterci, per esempio, un diverso ls
, che probabilmente useresti al posto di /bin/ls
senza accorgertene. Ora immaginate lo stesso per ssh
o il vostro browser o la vostra scelta... (Lo stesso vale triplicato per mettere . nel vostro percorso).
Sono confuso dalla domanda 2 (da quando è stata rimossa dalla domanda poiché era dovuta a una questione non correlata):
Qual'è un modo fattibile per aggiungere più percorsi su linee diverse? Inizialmente ho pensato che questo potrebbe fare il trucco:
esporta PATH=$PATH:~/opt/bin esporta PATH=$PATH:~/opt/node/bin
ma non lo fa'perché il secondo assegnamento non aggiunge solo
~/opt/node/bin
, ma anche tutto ilPATH
precedentemente assegnato.Questo è un possibile workaround:
esporta PATH=$PATH:~/opt/bin:~/opt/node/bin
ma per la leggibilità preferirei avere una sola assegnazione per un solo percorso.
Se dite
PATH=~/opt/bin
questo è tutto quello che sarà nel vostro PATH. PATH è solo una variabile d'ambiente, e se vuoi aggiungere al PATH, devi ricostruire la variabile con esattamente il contenuto che vuoi. Cioè, quello che dai come esempio alla domanda 2 è esattamente quello che vuoi fare, a meno che non mi sfugga completamente il punto della domanda.
Io uso entrambe le forme nel mio codice. Ho un profilo generico che installo su ogni macchina su cui lavoro che assomiglia a questo, per adattarsi alle directory potenzialmente mancanti:
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