$ PATH içindeki girişler yineleniyor mu?


45

Ben birkaç arkadaşımdan bashrc'ye kaynak veriyorum. Bu yüzden $ PATH değişkenime çift girişler yaptım. Başlamak için uzun süren komutların sorunu olup olmadığından emin değilim. $ PATH dahili olarak bash'ta nasıl çalışır? Daha fazla PATHS sahibi olmak başlangıç ​​zamanımı yavaşlatıyor mu?




İlgili: Eğer zaten mevcut değilse $ PATH dizinini ekleyin (Süper Kullanıcı üzerinde).
G-Man

Yanıtlar:


42

Daha fazla giriş yapmak $PATH, başlangıç ​​işleminizi doğrudan yavaşlatmaz, ancak belirli bir komutu bir kabuk oturumunda ilk çalıştırdığınızda yavaşlar (komutu her çalıştırdığınızda değil, çünkü bash bir önbellek tutar). Yavaşlama, özellikle yavaş bir dosya sistemine (örneğin, NFS, Samba veya diğer ağ dosya sistemine veya Cygwin'de) sahip olmadıkça nadiren algılanabilir.

Yinelenen girişler ayrıca $PATHgörsel olarak gözden geçirirken biraz can sıkıcıdır , daha fazla zalimce beklemeniz gerekir.

Çift girişler eklemekten kaçınmak yeterince kolaydır.

case ":$PATH:" in
  *":$new_entry:"*) :;; # already there
  *) PATH="$new_entry:$PATH";; # or PATH="$PATH:$new_entry"
esac

Not: başkasının kabuk betiğini almak, yazdığı kodu çalıştırmak anlamına gelir. Başka bir deyişle, arkadaşlarınıza istediğiniz zaman hesabınıza erişme izni veriyorsunuz.

Yan not: .bashrcayarlamak için doğru yer $PATHya da başka bir ortam değişkeni değil. Ortam değişkenleri ayarlanmalıdır ~/.profile. Bkz. Bash ile ortam değişkenlerini ayarlamak için hangi kurulum dosyaları kullanılmalıdır? , .Bashrc ve .bash_profile arasındaki fark .


8
+1: "arkadaşlarınıza hesabınıza erişme izni" nin vurgulandığını vurgulayamıyoruz. Size zarar verme girişiminde bulunmasanız bile senaryoları tam da ihtiyaç duydukları şey olabilir ve kaynağınız olduğunda öğlen yemeğinizi yiyebilirsiniz.
msw

Bu çözümle ilgili olası bir sorun, $ new_entry zaten PATH'deki ilk giriş ise, ": $ new_entry:" eşleşmeyecek. Bunu profilimdeki ilk ':' sütununu hariç tutarak düzelttim.
Jeff Bauer,

@JeffBauer Sorunu görmüyorum. Kullandığım case :$PATH:ve case $PATHbu yüzden giriş ilk veya son olsa bile eşleştiğini.
Gilles 'SO- kötü olmayı bırak'

31

İnsanların PATH değişkenindeki kopyaları ve bunun awkgibi bir şeyi temizlediklerini gördüm :

PATH=$(printf "%s" "$PATH" | awk -v RS=':' '!a[$1]++ { if (NR > 1) printf RS; printf $1 }')

Bunu kendi bashrc'nize eklemeyi deneyebilir ve çalıştırmadan önce diğer dosyaları bir yerden kaynakladığınızdan emin olabilirsiniz.

Alternatif bir kullanmak olacaktır yarar.pathmerge

Hız probleminize gelince, bu, kabuğun başlangıç ​​zamanını önemli bir şekilde etkilemeyecektir, ancak özellikle komut yolda bulunmazsa ve aynı aramaları tekrarladıktan sonra, komutlar için sekme tamamlama işlemi biraz zaman kazanabilir. klasörler onu arıyor.

Güvenlik Üzerine Bir Not: Sen gerektiğini gerçekten kulak Gilles' uyarılarını burada güvenlik konusunda. Başka bir kullanıcının sahip olduğu bir dosyayı alarak, bu kullanıcılara bir kabuk başlattığınızda kullanıcı olarak kendi kodlarını yürütmeleri için ücretsiz bir geçiş hakkı veriyorsunuzdur. Bu kullanıcılara şifrenizle güvenmiyorsanız, kabuk dosyalarına kaynak bulmamanız gerekir.


6
Awk one-liner'ı beğendim, ancak takip eden bir ORS ':' yazdıracak. Bu yüzden okumak için modifiyePATH=$(echo "$PATH" | awk -v RS=':' -v ORS=":" '!a[$1]++{if (NR > 1) printf ORS; printf $a[$1]}')
gkb0986

İz :sadece kozmetik bir mesele değil. .Potansiyel olarak tehlikeli olan yolunuza eklemekle aynı şeydir.
wisbucky

Cevabı, gkb0986'daki düzeltmeyi içerecek şekilde düzenledim.
Tim Lesher

Nedenle @TimLesher Cevabın benim için işe değil yapmasıdır tarafından içine daha düzenlenmiş asla .... ve o (iş dahil etmez olmadan orijinal değil bir eğik ayırıcı bırakarak. Ben farkın ne olduğunu bilmiyorum .
Caleb

1
@ gkb0986 Bu yol, PATH = / bin: / foo \ bar: / usr / bin gibi bir çıkış alanı içeriyorsa, yine de başarısız olur. Bunu engelleyen bir değişken buldum unix.stackexchange.com/a/124517/106102
maharvey67

13

@Gilles yanıtına dayanarak yazmayı en aza indirgeyen bir fonksiyonla sarabilirsiniz:

function addToPATH {
  case ":$PATH:" in
    *":$1:"*) :;; # already there
    *) PATH="$1:$PATH";; # or PATH="$PATH:$1"
  esac
}

addToPATH /Applications/AIRSDK_Compiler/bin
addToPATH ~/.local/lib/npm/bin

1
Pratik olarak en kullanışlı (belki de yüksek seviye) cevap.
ijoseph

3

Yalnızca ilk eşleşme $PATHgerçekleştirilir, bu nedenle sonraki girişler bundan sonra işlenmez. Bu nedenle $PATH, ortamınızın beklendiği gibi davranmasını sağlamak için girdilerinizin sırasını bazen gözden geçirmelisiniz .

Sorunuzu cevaplamak için: bu yavaş başlangıç ​​nedeni olmamalıdır.


1
Ancak var olmayan bir komut yazdığımda daha uzun sürüyor. Aynı klasörü komut için iki kez arayacaktır.
balki

@balki Bir komutu tamamlamanı TABmı istiyorsun? Bu durumda tanımlamayı tamamlayıp tamamlamadığınızı kontrol etmelisiniz complete -c which -a. -aParametreyi silmelisiniz . Sen komutu vererek kontrol edebilirsiniz: complete | grep which.
Rajish

Bulmadan önce birden çok kez bulunmayan aynı dizini ararsa, yine de bir sorun olabilir.
Random832

-1

PATH’imdeki yinelenen girişleri önlemek için aşağıdakileri BOTH ~ / .bash_profile ve ~ / .bashrc dizinine koymak zorunda kaldım:

PATH=$(echo $(sed 's/:/\n/g' <<< $PATH | sort | uniq) | sed -e 's/\s/':'/g')

En büyük dezavantajı PATH girişlerini sıralaması, ancak bununla yaşayabileceğimi düşünüyorum.


PATH aramasının sırası oldukça önemlidir.
Steven Shaw
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.