it-swarm-eu.dev

Jak správně přidat cestu k PATH?

Zajímalo by mě, kde je třeba do proměnné prostředí PATH přidat novou cestu. Vím, že toho lze dosáhnout úpravou .bashrc (například), ale není jasné, jak to provést.

Tudy:

export PATH=~/opt/bin:$PATH

nebo toto?

export PATH=$PATH:~/opt/bin
994
Paolo

Jednoduché věci

PATH=$PATH:~/opt/bin

nebo

PATH=~/opt/bin:$PATH

v závislosti na tom, zda chcete přidat ~/opt/bin na konci (prohledávat všechny ostatní adresáře, v případě, že existuje program se stejným názvem ve více adresářích) nebo na začátku (prohledávat před všemi ostatními adresáři).

Můžete přidat více záznamů najednou. PATH=$PATH:~/opt/bin:~/opt/node/bin nebo variace v objednávce fungují dobře. Nedávejte export na začátek řádku, protože to má další komplikace (viz níže pod „Poznámky k granátům jiným než bash“).

Pokud váš PATH bude sestaven z mnoha různých komponent, můžete skončit duplicitními položkami. Viz Jak přidat cestu domovského adresáře, kterou má Unix zjistit, který příkaz? a Odstranit duplicitní položky $ PATH pomocí příkazu awk , abyste se vyhnuli přidávání duplikátů nebo jejich odstraňování.

Některé distribuce automaticky vloží ~/bin Ve vaší PATH, pokud existuje, mimochodem.

Kam to dát

Vložte řádek a upravte PATH v ~/.profile, nebo v ~/.bash_profile pokud to máte.

Všimněte si, že ~/.bash_rc není čten žádným programem a ~/.bashrc je konfigurační soubor interaktivních instancí bash. Neměli byste definovat proměnné prostředí v ~/.bashrc. Správné místo pro definování proměnných prostředí, jako je PATH, je ~/.profile (nebo ~/.bash_profile pokud vám záleží na granátech jiných než bash). Viz Jaký je rozdíl mezi nimi a který z nich bych měl použít?

Nedávejte to do /etc/environment nebo ~/.pam_environment: nejedná se o soubory Shell, nemůžete použít substituce jako $PATH tam. V těchto souborech můžete přepsat pouze proměnnou a nepřidávat ji.

Potenciální komplikace v některých systémových skriptech

Nepotřebujete export, pokud je proměnná již v prostředí: jakákoli změna hodnoty proměnné se projeví v prostředí.¹ PATH je v prostředí téměř vždy; všechny unixové systémy to nastavily velmi brzy (obvykle v prvním procesu, ve skutečnosti).

V době přihlášení se můžete spolehnout na to, že PATH je již v prostředí a již obsahuje některé systémové adresáře. Pokud píšete skript, který může být spuštěn brzy při nastavování jakéhokoli virtuálního prostředí, možná budete muset zajistit, aby PATH není prázdné a exportováno: pokud PATH je stále nastaveno , pak něco jako PATH=$PATH:/some/directory nastaví PATH na :/some/directory a prázdná komponenta na začátku znamená aktuální adresář (jako .:/some/directory).

if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi

Poznámky k granátům jiným než bash

V bash, ksh a zsh je export speciální syntaxe a obojí PATH=~/opt/bin:$PATH a export PATH=~/opt/bin:$PATH udělej správnou věc. V jiných lasturách typu Bourne/POSIX, jako je pomlčka (což je /bin/sh na mnoha systémech), export je analyzováno jako obyčejný příkaz, což znamená dva rozdíly:

Takže ve skořápce jako pomlčka, export PATH=~/opt/bin:$PATH nastaví PATH na doslovný řetězec ~/opt/bin/: následované hodnotou PATH až do prvního místa. PATH=~/opt/bin:$PATH (holé přiřazení) nevyžaduje uvozovky a dělá správnou věc. Pokud chcete v přenosném skriptu použít export, musíte napsat export PATH="$HOME/opt/bin:$PATH" nebo PATH=~/opt/bin:$PATH; export PATH (nebo PATH=$HOME/opt/bin:$PATH; export PATH za přenositelnost i do Bourne Shell, která nepřijala export var=value a nedělali tildovou expanzi).

¹ To neplatilo v Bourne shellech (jako ve skutečném Bourne Shell, ne v moderních skořápkách ve stylu POSIX), ale je velmi nepravděpodobné, že byste se dnes setkali s takovými starými skořápkami.

Každopádně to funguje, ale nedělají to samé: prvky PATH jsou zkontrolovány zleva doprava. V prvním příkladu spustitelné soubory v ~/opt/bin bude mít přednost před těmi nainstalovanými, například v /usr/bin, což může, ale nemusí být to, co chcete.

Z bezpečnostního hlediska je obzvláště nebezpečné přidat do popředí cesty, protože pokud někdo může získat přístup pro zápis k vašemu ~/opt/bin, tam mohou například vložit jiný ls, který byste pak pravděpodobně použili místo /bin/ls bez vědomí. Teď si představte totéž pro ssh nebo váš prohlížeč nebo volbu ... (Totéž platí i pro vložení. Do vaší cesty.)

88
Ulrich Schwarz

Jsem zmaten otázkou 2 (protože byl odstraněn z otázky, protože to bylo způsobeno nesouvisejícím problémem):

Jaký je proveditelný způsob, jak připojit více cest na různých řádcích? Zpočátku jsem si myslel, že to může udělat trik:

export PATH=$PATH:~/opt/bin
export PATH=$PATH:~/opt/node/bin

ale není tomu tak proto, že druhé přiřazení nepřipojí pouze ~/opt/node/bin, ale také celý dříve přiřazený PATH.

Toto je možné řešení:

export PATH=$PATH:~/opt/bin:~/opt/node/bin

ale kvůli čitelnosti bych měl raději jedno zadání pro jednu cestu.

Pokud řeknete

PATH=~/opt/bin

to je vše, které bude ve vaší cestě. PATH je pouze proměnná prostředí, a pokud chcete přidat do PATH, musíte proměnnou znovu vytvořit přesně podle požadovaného obsahu. To znamená, že to, co uvedete jako příklad k otázce 2, je přesně to, co chcete dělat, pokud mi úplně chybí otázka.

V kódu používám oba formuláře. Mám obecný profil, který instaluji na každém počítači, na kterém pracuji, který vypadá takto, abych vyhověl potenciálně chybějícím adresářům:

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
39
Carl Cravens

Linux určuje spustitelnou vyhledávací cestu pomocí $PATH proměnná prostředí. Přidání adresáře/dat/myscriptů na začátek $PATH proměnná prostředí, použijte následující:

PATH=/data/myscripts:$PATH

Chcete-li přidat tento adresář na konec cesty, použijte následující příkaz:

PATH=$PATH:/data/myscripts

Předchozí však nestačí, protože když nastavíte proměnnou prostředí uvnitř skriptu, tato změna je účinná pouze v rámci skriptu. Toto omezení lze obejít pouze dvěma způsoby:

  • Pokud ve skriptu exportujete proměnnou prostředí, je účinná v rámci všech programů, které skript volá. Všimněte si, že to není účinné v programu, který volal skript.
  • Pokud to program, který volá skript, provede zahrnutím namísto volání, jsou všechny změny prostředí ve skriptu účinné v rámci volajícího programu. Takové zařazení lze provést pomocí příkazu dot nebo source.

Příklady:

$HOME/myscript.sh
source $HOME/myscript.sh

Zahrnutí v zásadě zahrnuje skript „volal“ do skriptu „volání“. Je to jako #include in C. Takže je to efektivní uvnitř "volajícího" skriptu nebo programu. Ale samozřejmě to není efektivní v žádných programech nebo skriptech, které volající program volá. Chcete-li, aby byl účinný po celou dobu hovoru, musíte postupovat podle nastavení proměnné prostředí pomocí příkazu export.

Například program bash Shell obsahuje obsah souboru .bash_profile zahrnutím. Umístěte následující 2 řádky do .bash_profile:

PATH=$PATH:/data/myscripts
export PATH

efektivně vloží tyto 2 řádky kódu do bash programu. Takže v rámci bash obsahuje proměnná $ PATH $HOME/myscript.sh a kvůli exportnímu příkazu mají všechny programy, které volá bash, změněné $PATH proměnná. A protože všechny programy, které spouštíte z bash Prompt, se nazývají bash, nová cesta platí pro vše, co spouštíte z bash Prompt.

Spodní řádek je, že k přidání nového adresáře na cestu musíte připojit nebo připojit adresář do proměnné prostředí $ PATH ve skriptu zahrnutém ve skořepině a musíte exportovat $PATH proměnná prostředí.

Více informací zde

25
Steve Brown

Po nějakou dobu jsem si u sebe nechal dvě funkce pathadd a pathrm, které pomáhají při přidávání prvků na cestu, aniž by bylo třeba se obávat duplicit.

pathadd vezme argument jediné cesty a volitelný argument after, který, pokud je zadán, připojí _ PATH, jinak jej připojí.

Téměř v každé situaci, pokud přidáváte cestu, pravděpodobně budete chtít přepsat cokoli, co již na cestě existuje, a proto se ve výchozím nastavení rozhodnu předběžně připojit.

pathadd() {
    newelement=${1%/}
    if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then
        if [ "$2" = "after" ] ; then
            PATH="$PATH:$newelement"
        else
            PATH="$newelement:$PATH"
        fi
    fi
}

pathrm() {
    PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
}

Vložte je do jakéhokoli skriptu, který chcete změnit prostředí PATH, a nyní to můžete udělat.

pathadd "/foo/bar"
pathadd "/baz/bat" after
export PATH

Je zaručeno, že na cestu nepřidáte, pokud již existuje. Pokud nyní chcete zajistit /baz/bat je na začátku.

pathrm "/baz/bat"
pathadd "/baz/bat"
export PATH

Nyní lze libovolnou cestu přesunout dopředu, pokud je již v cestě bez zdvojnásobení.

20
Brett Ryan

Nemohu mluvit za jiné distribuce, ale Ubuntu má soubor/etc/environment, což je výchozí vyhledávací cesta pro všechny uživatele. Protože můj počítač používá pouze já, vložil jsem tam do své cesty všechny adresáře, které chci, pokud to není dočasný doplněk, který jsem vložil do skriptu.

10
Jim Bradley

Existují situace, kdy pomocí PATH=/a/b:$PATH lze považovat za „nesprávný“ způsob přidání cesty k PATH:

  1. Přidání cesty, která ve skutečnosti není adresářem.
  2. Přidání cesty, která je již v PATH, ve stejném tvaru.
  3. Přidání relativní cesty (protože skutečný prohledávaný adresář by se změnil při změně aktuálního pracovního adresáře).
  4. Přidání cesty, která je již v PATH, v jiné podobě (tj. Alias ​​způsobený používáním symbolických odkazů nebo ..).
  5. Pokud se vyhnete provádění 4, nepřesouvejte cestu dopředu PATH, pokud je to zamýšleno k přepsání ostatních položek v PATH.

Tato funkce (pouze Bash) provádí ve výše uvedených situacích „správnou věc“ (s výjimkou viz níže), vrací chybové kódy a tiskne pěkné zprávy pro lidi. Chybové kódy a zprávy lze zakázat, pokud nejsou požadovány.

prepath() {
    local usage="\
Usage: prepath [-f] [-n] [-q] DIR
  -f Force dir to front of path even if already in path
  -n Nonexistent dirs do not return error status
  -q Quiet mode"

    local tofront=false errcode=1 qecho=echo
    while true; do case "$1" in
        -f)     tofront=true;       shift;;
        -n)     errcode=0;          shift;;
        -q)     qecho=':';          shift;;
        *)      break;;
    esac; done
    # Bad params always produce message and error code
    [[ -z $1 ]] && { echo 1>&2 "$usage"; return 1; }

    [[ -d $1 ]] || { $qecho 1>&2 "$1 is not a directory."; return $errcode; }
    dir="$(command cd "$1"; pwd -P)"
    if [[ :$PATH: =~ :$dir: ]]; then
        $tofront || { $qecho 1>&2 "$dir already in path."; return 0; }
        PATH="${PATH#$dir:}"        # remove if at start
        PATH="${PATH%:$dir}"        # remove if at end
        PATH="${PATH//:$dir:/:}"    # remove if in middle
    fi
    PATH="$dir:$PATH"
}

Výjimkou je, že tato funkce nemůže kanonizovat cesty přidané k PATH jinými prostředky, takže pokud je nekanonický alias pro cestu v PATH, přidá se duplikát. Pokus o kanonizaci cest již v PATH je těžkopádný návrh, protože relativní cesta má zjevný význam, když je předána prepath, ale když už v cestě nevíte, jaký byl aktuální pracovní adresář když byl přidán.

7
cjs

Přidání nové cesty k proměnné prostředí PATH:

export PATH=$PATH:/new-path/

Aby tato změna byla aplikována na každé otevřené prostředí, přidejte ji do souboru, který prostředí při spuštění vyvolá zdroj. V různých skořápkách to může být:

  • Bash Shell: ~/.bash_profile, ~/.bashrc nebo profil
  • Korn Shell: ~/.kshrc nebo .profile
  • Z Shell: ~/.zshrc nebo .zprofile

např.

# export PATH=$PATH:/root/learning/bin/
# source ~/.bashrc
# echo $PATH

Ve výše uvedeném výstupu můžete vidět zadanou cestu.

7
Amit24x7

Pro mě (v systému Mac OS X 10.9.5) bylo přidání názvu cesty (např. /mypathname) Do souboru /etc/paths Velmi dobré.

Před úpravou se vrátí echo $PATH:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

Po úpravě /etc/paths A restartování prostředí je proměnná $ PATH připojena k /pathname. Opravdu se vrátí echo $PATH:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname

Stalo se, že /mypathname Byl připojen k proměnné $PATH.

6
faelx

Zde je moje řešení:

PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")

Pěkná jednoduchá vložka, která nezanechává koncové :

5
AJ.