Nasıl doğru yol PATH ekleyebilirim?


922

PATHOrtam değişkenine yeni bir yolun nereye ekleneceğini merak ediyorum . Bunun düzenleme .bashrc(örneğin) ile yapılabileceğini biliyorum , ancak bunun nasıl yapılacağı belli değil.

Bu yoldan:

export PATH=~/opt/bin:$PATH

veya bu?

export PATH=$PATH:~/opt/bin

printf '\ nPATH = $ PATH: "ekleme yolu" \ nexport PATH \ n' >> ~ / .bashrc
Sudoer


Halihazırda eklenmiş bazı yollar varsa, örneğin PATH=$PATH:$HOME/.local/bin:$HOME/bin, bir: a ile ayrılarak bir başka eklenebilir PATH=$PATH:$HOME/.local/bin:$HOME/bin:/home/ec2-user/pear/bin.
Sandeepan Nath

2
Bu cevaplar linux'un tüm lezzetleri için işe yarıyor mu?
Ungeheuer,

Yanıtlar:


1033

Basit şeyler

PATH=$PATH:~/opt/bin

veya

PATH=~/opt/bin:$PATH

~/opt/binsonunda eklemek isteyip istemediğinize bağlı olarak (birden fazla klasörde aynı adda bir program olması durumunda diğer tüm dizinlerden sonra aranacak) veya başlangıçta (diğer tüm dizinlerden önce aranacak).

Aynı anda birden fazla giriş ekleyebilirsiniz. PATH=$PATH:~/opt/bin:~/opt/node/binya da sipariş çalışmasındaki değişiklikler gayet iyi. Koymayın exportek komplikasyonlar olduğu gibi satır başında ( “bash dışındaki kabukları üzerinde Notlar” başlığı altında aşağıya bakınız).

Sizin PATHbirçok farklı bileşen tarafından oluşturuluyorsa, yinelenen girişlerle sonuçlanabilir. Bkz ev dizin yolu komut Unix tarafından keşfedilmeyi nasıl eklenir? ve yinelenen $ PATH girişlerini yinelenenleri eklemek veya kaldırmaktan kaçınmak için awk komutuyla kaldırın.

Bazı dağıtımlar ~/bin, eğer varsa, PATH’nize otomatik olarak konur .

Nereye koymak

Değiştirmek için çizgi koyun PATHiçinde ~/.profile, ya da ~/.bash_profilebu da sahip buysa.

Not ~/.bash_rcherhangi bir program tarafından okunan ve olmayan ~/.bashrcBash interaktif örneklerinin yapılandırma dosyasıdır. İçindeki ortam değişkenlerini tanımlamamalısınız ~/.bashrc. Doğru yer gibi ortam değişkenleri tanımlamak PATHolduğu ~/.profile(ya ~/.bash_profilesen bash dışındaki kabukları umurumda değil ise). Bkz. Aralarındaki fark nedir ve hangisini kullanmalıyım?

İçine koymayın /etc/environmentveya ~/.pam_environment: bunlar kabuk dosyaları değildir $PATH, orada olduğu gibi değiştirmeleri kullanamazsınız . Bu dosyalarda, bir değişkeni geçersiz kılabilirsiniz, buna ekleyemezsiniz.

Bazı sistem komut dosyalarındaki potansiyel komplikasyonlar

exportDeğişkenin zaten çevrede olup olmadığına ihtiyacınız yok : değişkenin değerindeki herhangi bir değişiklik çevreye yansır PATH. tüm unix sistemleri onu çok erken başlattı (aslında ilk süreçte, aslında).

Giriş zamanında, PATHzaten ortamda bulunduğunuza ve zaten bazı sistem dizinlerini içerdiğinize güvenebilirsiniz . Eğer sanal ortamda çeşit kurarken erken infaz edilebilir bir senaryo yazıyoruz, o emin olmanız gerekebilir PATHeğer: Boş olmayan ve ihraç olduğu PATHhala ayarlanmazsa, daha sonra böyle bir şey PATH=$PATH:/some/directorykuracak PATHkadar :/some/directoryve boş komponent başında geçerli dizin (benzeri .:/some/directory) anlamına gelir .

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

Bash dışındaki kabukları üzerine notlar

Bash, ksh ve zsh olarak, exportözel sözdizimi ve her iki PATH=~/opt/bin:$PATHve export PATH=~/opt/bin:$PATHhatta doğru olanı yap. Diğer Bourne / POSIX tarzı çizgi gibi kabuklar ( /bin/shbirçok sistemde bulunur), exportiki farklılığı ifade eden sıradan bir komut olarak ayrıştırılır:

Böylece çizgi gibi kabukları , ilk boşluğa kadar değeri takiben değişmez dizeye export PATH=~/opt/bin:$PATHayarlar . (çıplak bir atama) tırnak gerektirmez ve doğru olanı yapar. Taşınabilir bir komut dosyasında kullanmak istiyorsanız , yazmanız veya (ya da tilde genişleme yapmayan ve kabul etmeyen Bourne kabuğunun bile taşınabilmesi için) yazmanız gerekir .PATH~/opt/bin/:PATHPATH=~/opt/bin:$PATHexportexport PATH="$HOME/opt/bin:$PATH"PATH=~/opt/bin:$PATH; export PATHPATH=$HOME/opt/bin:$PATH; export PATHexport var=value

Ne Bourne mermilerinde bu doğru değildi (asıl Bourne mermisinde olduğu gibi, modern POSIX tarzı mermilerde değil), ancak bugünlerde böyle eski mermilerle karşılaşmanız pek mümkün değil.


Yine de ihracatla ilgili komplikasyonları anlayamadım. basitleştirebilir misiniz lütfen?
priojeet priyom

@priojeetpriyom Basit bir açıklama: İhtiyacınız yok export.
Gilles

Mükemmel cevap veren bu cevap için teşekkür ederim. " Ortam değişkenlerini ~ / .bashrc biçiminde tanımlamamalısınız " diyorsunuz , ancak ne yazık ki, sistemime kurduğum programların% 100'ünde yolu değiştiren (FZF ve Rust'in Kargoları) yolu değiştiriyor .bashrc. FZF'nin Rust dilinde yazıldığından, Rust modelinin peşinden olduğunu varsayıyorum.
icc97

83

Her iki şekilde de çalışır, ancak aynı şeyi yapmazlar: elemanları PATHsoldan sağa kontrol edilir. İlk örneğinizde, çalıştırılabilir dosyalar ~/opt/bin, örneğin, /usr/binistediğiniz veya olabileceği veya yüklenmemiş olanlardan öncelikli olacaktır .

Özellikle, emniyet açısından bakıldığında, cepheye yollar eklemek tehlikelidir, çünkü eğer biri size yazma erişimini ~/opt/binsağlayabilirse, örneğin, lso zaman muhtemelen yerine kullanacağınız başka bir yere koyabilirler. arasında /bin/lsfark etmeden. Şimdi aynısını sshya da tarayıcınızı ya da seçiminizi hayal edin ...


6
Ancak, kendi özelleştirilmiş sürümünüzün olmasını lsistiyorsanız, onu bir dizine koymanız gerekir /bin.
Barmar

16
veya diğer adı ls = myl
waltinator

36

Soru 2 ile karıştığım (ilgisiz bir sorundan dolayı sorudan çıkarıldığından beri):

Farklı satırlara daha fazla yol eklemenin uygulanabilir bir yolu nedir? Başlangıçta bunun hile yapabileceğini düşündüm:

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

ancak bu, ikinci ödev sadece eklenmediği için değil ~/opt/node/bin, aynı zamanda PATHönceden atananların tümü değildir .

Bu olası bir geçici çözümdür:

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

ancak okunabilirlik için bir yol için bir ödev yapmayı tercih ederim.

Eğer öyle diyorsan

PATH=~/opt/bin

işte bütün PATH içinde olacak. PATH yalnızca bir ortam değişkenidir ve PATH'e eklemek istiyorsanız, değişkeni istediğiniz içerikle yeniden oluşturmanız gerekir. Yani, 2. soruya örnek olarak verdiğiniz şey, tam olarak ne yapmak istediğinizi, soruyu tam olarak anlamadığım sürece.

Her iki formu da kodumda kullanıyorum. Potansiyel olarak eksik olan dizinleri barındırmak için üzerinde çalıştığım ve üzerinde çalıştığım her makineye yüklediğim genel bir profilim var:

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

2
Soru 2 örneği hakkında haklısın, işe yarıyor. PATH ile ilgili başka bir konu sistemimde kafamı karıştırdı. Bunun için özür dilerim.
Paolo,

26

Ekleme / Hazırlamanın kurşun geçirmez yolu

Hazırlamaya karşı hazır olma seçiminde yer alan birçok husus vardır. Birçoğu başka cevaplarla kaplıdır, bu yüzden onları burada tekrar etmeyeceğim.

Önemli bir nokta, sistem komut dosyaları bunu kullanmasa da (nedenini merak ediyorum) * 1 , $HOME/binPATH ortam değişkenine yol (örneğin ) eklemek için kurşun geçirmez yolun olmasıdır.

PATH="${PATH:+${PATH}:}$HOME/bin"

eklemek için (yerine PATH="$PATH:$HOME/bin") ve

PATH="$HOME/bin${PATH:+:${PATH}}"

hazırlamak için (yerine PATH="$HOME/bin:$PATH")

Bu $PATH, başlangıçta boşken istenmeyen yan etkilere neden olabilecek ve bulması zor olan kabus haline gelebilecek sahte ön / arka kolondan kaçınır ( bu cevap kısa süre içinde ele alınır awk).

Açıklama ( Kabuk Parametre Genişletmesinden ):

${parameter:+word}

Eğer parameterboş veya ayarlanmadan, hiçbir şey aksi takdirde genişleme, ikame edilir wordikame edilir.

Bu nedenle, ${PATH:+${PATH}:}şu şekilde genişletilir: 1) eğer boşsa PATHveya sıfırsa hiçbir şey , 2) ${PATH}:, eğer PATHayarlanmamışsa.

Not : Bu bash içindir.


* 1 Ben sadece bu gibi komut dosyalarının devtoolset-6/enablebunu kullandığını öğrendim ,

$ cat /opt/rh/devtoolset-6/enable
# General environment variables
export PATH=/opt/rh/devtoolset-6/root/usr/bin${PATH:+:${PATH}}
...

24

Linux, çalıştırılabilir arama yolunu $PATHortam değişkeniyle belirler. Dizin / data / myscripts'i $PATHortam değişkeninin başlangıcına eklemek için aşağıdakileri kullanın:

PATH=/data/myscripts:$PATH

Bu dizini yolun sonuna eklemek için aşağıdaki komutu kullanın:

PATH=$PATH:/data/myscripts

Ancak, önceki komutlar yeterli değildir, çünkü komut dosyası içinde bir ortam değişkeni ayarladığınızda, bu değişiklik yalnızca komut dosyası içinde etkili olur. Bu sınırlamanın etrafında sadece iki yol var:

  • Komut dosyasındaysa, ortam değişkenini dışa aktarırsanız, komut dosyası tarafından adlandırılan tüm programlarda etkili olur. Komut dosyasını çağıran program içinde etkili olmadığını unutmayın.
  • Komut dosyasını çağıran program bunu çağırmak yerine dahil ederek yaparsa, komut dosyasındaki herhangi bir ortam değişikliği arama programı içinde etkili olur. Bu ekleme, dot komutu veya source komutu ile yapılabilir.

Örnekler:

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

Dahil etme, temel olarak "calling" betiğine "called" komut dosyasını içerir. Bu, C'ye bir #include gibi. Bu nedenle, "arama" senaryosunda veya programında etkilidir. Ancak elbette, çağıran program tarafından adlandırılan hiçbir programda veya komut dosyasında etkili değildir. Çağrı zincirinin sonuna kadar etkili hale getirmek için, ortam değişkeninin ayarını bir export komutuyla izlemelisiniz.

Bir örnek olarak, bash shell programı, .bash_profile dosyasının içeriğini dahil ederek içerir. .Bash_profile dosyasına şu 2 satırı yerleştirin:

PATH=$PATH:/data/myscripts
export PATH

bash programına bu 2 satır kodunu etkili bir şekilde yerleştirir. Yani bash içinde $ PATH değişkeni içerir $HOME/myscript.shve export ifadesi nedeniyle bash tarafından adlandırılan programlar değiştirilmiş $PATHdeğişkene sahiptir. Ve bir bash komut isteminden çalıştırdığınız tüm programlar bash tarafından çağrıldığından, yeni yol, bash komut isteminden çalıştırdığınız her şey için yürürlüktedir.

Alt satırda, yola yeni bir dizin eklemek için, dizini kabuğa dahil edilen bir komut dosyasındaki $ PATH ortam değişkenine eklemeniz veya hazırlamanız ve $PATHortam değişkenini dışa aktarmanız gerekir .

Daha fazla bilgi burada


19

Bir süredir benimle birlikte iki işlevi tuttum pathaddve pathrmbu da kopyalar için endişelenmenize gerek kalmadan yola eleman eklemenize yardımcı oldu.

pathaddtek bir yol argümanı ve aftereğer verilirse PATHaksi takdirde hazırlayacağı bir opsiyon argümanı alır .

Neredeyse her durumda yola ekliyorsanız, muhtemelen zaten yoldaki herhangi bir şeyi geçersiz kılmak isteyeceksinizdir, bu yüzden varsayılan olarak hazırlanmayı tercih ediyorum.

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')"
}

Bunları PATH ortamını değiştirmek istediğiniz herhangi bir komut dosyasına koyun ve şimdi yapabilirsiniz.

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

Zaten oradaysa yola ekleme yapmama garantilidir. Şimdi sağlamak istiyorsanız /baz/batbaşlangıçta.

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

Şimdi, halihazırda iki katına çıkmadan yolun içindeyse herhangi bir yol öne taşınabilir.



9

Diğer dağıtımlar için konuşamıyorum, ancak Ubuntu'da tüm kullanıcılar için varsayılan arama yolu olan / etc / environment adlı bir dosya var. Bilgisayarım yalnızca benim tarafımdan kullanıldığından, bir komut dosyasına koyduğum geçici bir ek olmadığı sürece, yolumda istediğim dizinleri koydum.


6

PATH=/a/b:$PATHBir yol eklemek için kullanmanın "yanlış" yol olarak kabul edilebileceği bazı durumlar vardır PATH:

  1. Aslında bir dizin olmayan bir yol eklemek.
  2. Zaten PATHaynı biçimde olan bir yol ekleme .
  3. Göreceli bir yol ekleme (aranan asıl dizin, geçerli çalışma dizinini değiştirdikçe değişeceğinden).
  4. Zaten PATHfarklı bir biçimde olan bir yol ekleme (yani, sembolik bağlantılar kullanmaya bağlı bir takma ad veya ..).
  5. 4'ü yapmaktan kaçınırsanız, PATHgirişi diğer girişleri geçersiz kılmak istediğiniz zaman önüne götürmeyin PATH.

Bu (yalnızca Bash) işlevi, yukarıdaki durumlarda "doğru olanı" yapar (istisna dışında, aşağıya bakın), hata kodlarını döndürür ve insanlar için hoş mesajlar yazdırır. Hata kodları ve mesajlar istenmediğinde devre dışı bırakılabilir.

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"
}

Bunun istisnası, bu fonksiyonun, PATHbaşka yollarla eklenen yolları kanonize etmemesidir; bu nedenle, yol için kanonik olmayan bir takma ad varsa PATH, bu bir kopya ekleyecektir. Halihazırda bulunan yolları kurallılaştırmaya çalışmak PATHzorlu bir öneridir, çünkü göreceli bir yolun geçtiğinde belirgin bir anlamı vardır, prepathancak zaten yoldayken mevcut çalışma dizininin eklendiğinde ne olduğunu bilmiyorsunuzdur.


göreceli yollarla ilgili olarak: peki ilk önce mutlak yapmadan yolu ekleyen ve eklemeden önce de mutlak olarak görünen bir '-r' anahtarına sahip olmak? Bu senaryo olsaydı, biri diğer mermilerde kullanabilirdi. Bir işlev olarak sahip olmanın faydası var mı? güzel kod!
hoijui

1
@hoijui Geçerli çevreyi değiştirdiği için bir işlev olması gerekir. Bir komut dosyası olsaydı, komut dosyasını çalıştıran alt işlemin ortamını değiştirirdi ve komut dosyası çıktığında önceden kullandığınızla aynı olurdu $PATH. Gelince -r, hayır, içinde göreli yollar düşünüyorum $PATH(Yolunuz her zaman değiştirir sadece çok güvenilmez ve garip cdbir genel aracında böyle bir şeyi desteklemek istiyorum!).
Curt J. Sampson

5

Benim için (Mac OS X 10.9.5'te), dosyaya yol adını (örn. /mypathname) Eklemek /etc/pathsçok iyi çalıştı.

Düzenlemeden önce echo $PATHdöner:

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

/etc/pathsKabuğu düzenleyip yeniden başlattıktan sonra , $ PATH değişkeni ile eklenir /pathname. Nitekim, echo $PATHdöner:

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

Olan /mypathname, $PATHdeğişkene eklenen şeydi .


3
/ Etc / paths.d dizinine bir dosya eklemek, / etc / paths dosyasının kendisini düzenlemekten daha iyidir.
rewewer

4

PATHOrtam değişkenine yeni bir yol eklemek için :

export PATH=$PATH:/new-path/

Bu değişikliğin açtığınız her kabuğa uygulanabilmesi için , çağrıldığında kabuğun kaynağı olacağı dosyaya ekleyin . Farklı mermilerde bu olabilir:

  • Bash Shell: ~ / .bash_profile, ~ / .bashrc veya profil
  • Korn Shell: ~ / .kshrc veya .profile
  • Z Kabuğu: ~ / .zshrc veya .zprofile

Örneğin

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

Sağlanan yolu yukarıdaki çıktıda görebilirsiniz.


4

İşte benim çözümüm:

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

İz bırakmayan güzel, kolay bir astar :


1
-bash: awk: Böyle bir dosya veya dizin yok -bash: sed: Böyle bir dosya veya dizin yok
davidcondrey 21:16

1
@davidcondrey - awk ve sed çok yaygın harici komutlardır. Bu cevap aynı şeyi elde etmenin saf bir yolunu sunar, bu nedenle awk ve / veya
sed'nin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.