PATH değişkeninden yinelenen girişleri budama


9

Benim .bashrc sık sık değiştirmek ve sonra kaynak. Ancak, dosyamda olduğu gibi bir şey olduğunda, export PATH="~/bin:~/perl5/bin:$PATH"dosyayı PATHher kaynakladığımda ortam değişkeni büyür.

Örneğin, ilk kez .bashrc kaynaklanırken, PATHdeğişken oluşur ~/bin:~/perl5/bin:/usr/bin:/bin.

İkinci kez oluşur ~/bin:~/perl5/bin:~/bin:~/perl5/bin:/usr/bin:/bin.

Üçüncü kez oluşur ~/bin:~/perl5/bin:~/bin:~/perl5/bin:~/bin:~/perl5/bin:/usr/bin:/bin.

Sadece PATH'de olmayan bir şey eklemenin basit bir yolu var mı?

Yanıtlar:


12

Çoğu dağıtımda bulunan pathmunge () işlevini kullanın /etc/profile:

pathmunge () {
if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
   if [ "$2" = "after" ] ; then
      PATH=$PATH:$1
   else
      PATH=$1:$PATH
   fi
fi
}

edit : zshKullanıcılar için, typeset -U <variable_name>yol girişleri tekilleştirecek.


Teşekkürler! Bu burada değil /etc/profileDebian Lenny üzerinde, bu yüzden benim, dahil .bashrc.
Christopher Bottoms

Kullanımı: pathmunge /some/pathkoyacaktır /some/pathbaşında $PATHve pathmunge /some/path afteryerleştirecektir /some/pathsonunda$PATH
Christopher Bottoms

Yontmak dizini Modern bash kabuklarda, akım yolunda varsa çek yapmanın Temizleyici şekilde görmek: if ! [[ $PATH =~ (^|:)$1($|:) ]] ; then.
Christopher Cashell

Bunu kullanmam. Eğer saf versiyonum PATH = / foo: $ PATH demişse, / foo'nun kazanmasını istiyorum demektir. pathmunge /foo beforebunu başaramaz. Daha iyi bir yol başlangıçta / foo eklemek ve daha sonra yinelenenleri kaldırmak olacaktır.
Don Hatch

3

StackOverflow soruda listelenen tekniklerin bir arada kullanılan bu sorunu yaşıyordum . Temel komut dosyasını değiştirmek istemediğim için, daha önce ayarlanmış olan gerçek PATH değişkenini çıkarmak için kullandığım şey aşağıdadır.

    tmppath=(${PATH// /@})
    array=(${tmppath//:/ })
    for i in "${array[@]//@/ }"
    do
        if ! [[ $PATH_NEW =~ "$i" ]]; then
            PATH_NEW="${PATH_NEW}$i:";
        fi
    done;
    PATH="${PATH_NEW%:}"
    export PATH
    unset PATH_NEW

Bunu her zaman biraz daha optimize edebilirsiniz, ancak orijinalimde değişkenleri doğru ayarladığından emin olmak için neler olduğunu göstermek için ekstra kod vardı. Dikkat edilmesi gereken diğer bir şey, aşağıdakileri yaptığımdır

  1. herhangi bir SPACE karakterini @ karakteriyle değiştirin
  2. diziyi böl
  3. dizi boyunca döngü
  4. öğe dizesindeki herhangi bir @ karakterini boşlukla değiştir

Bu, boşlukları olan dizinleri işleyebilmemi sağlamaktır (Active Directory kullanıcı adlarına sahip Samba ana dizinleri boşluklara sahip olabilir!)


UYARI: Bu uygulama büyük bir hata var !! iki giriş aynı olmasa da normal ifade eşleştiği /biniçin başka girişler varsa kaldırılır /usr/bin!
Sukima

İşte bu hatayı düzelten alternatif bir uygulama: github.com/sukima/dotfiles/blob/…
Sukima

1

Yolunuzu açıkça belirleyin.


Teşekkürler. Yolu açıkça ayarlamayı denedim, ancak birden çok ortamda kullandığım bir .bashrc dosyası var, bu yüzden tam varsayılan PATHher zaman aynı değil.
Christopher Bottoms

1

Yalnızca bir dize:

for i in $(echo $PATH|tr ":" "\n"|sort|uniq);do PATH_NEW="${PATH_NEW}$i:";done;PATH="${PATH_NEW%:}"

Teşekkürler. Bu benim için zor bir şey, içeriğinin alfabetik olarak (veya ASCIIbetically) yeniden sıralanmasıdır $PATH. Çalıştırılabilir kişisel kopyalarım yerleşik varsayılanlar yerine çalıştırılacak şekilde $PATH(gibi /home/username) başına belirli dizinler koymak istiyorum .
Christopher Bottoms

1

Bunu çözmenin iki farklı yolunu düşünebilirim. Birincisi, .bashrc'nizi taban PATH'inizi açıkça ayarlayan bir satırla başlatmaktır, böylece her kaynak yaptığınızda, ek dizinler eklemeden önce tabana sıfırlanır.

Örneğin, şunu ekleyin:

# Reset the PATH to prevent duplication and to make sure that we include
# everything we want.
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Alternatif olarak, bir öğeyi yola eklemeden önce kontrol edebilirsiniz. Bunu yapmak için şöyle bir şey kullanırsınız:

if ! [[ $PATH =~ '~/perl5/bin' ]]
then
    PATH="~/perl5/bin:$PATH"
fi

Ancak ikincisi, çok fazla giriş eklerseniz biraz tekrarlı olma eğilimindedir, bu yüzden ilkine sadık kalmaya eğilimliyim. Bunu kullanmak istiyor ve çok sayıda giriş eklemeyi planlıyorsanız, işlemek için bir bash işlevi yazmak akıllıca olacaktır.

Not: İkinci seçenek yalnızca modern sürümlerde yazılan şekilde çalışabilir. Normal ifade desteği Bourne Kabuğu (/ bin / sh) özelliği değildir ve diğer kabuklarda bulunmayabilir. Ayrıca, tırnak işaretlerinin kullanılması gerekli olmayabilir veya hatta bazı yeni bash sürümlerinde sorunlara neden olabilir.


Teşekkürler. Yolu açıkça ayarlamayı denedim, ancak birden çok ortamda kullandığım bir .bashrc dosyası var, bu yüzden tam varsayılan PATHher zaman aynı değil.
Christopher Bottoms

Yine de, yerel ana bilgisayar adınızın ne olduğunu görmek için komut dosyasını kontrol ederek ve ardından bu sunucu için mutlak yolunuzu uygun şekilde ayarlayarak işleyebilirsiniz.
Christopher Cashell

Sadece bir yazım hatası:! eksik if. Ayrıca, şaşırtıcı bir şekilde (bana göre) bunu boşlukla ayrılmış argümanlar üzerinde döngü yapan bir işleve dönüştürmek kolaydır, böylece şunu söyleyebilirsiniz: add_to_PATH ~/perl5/bin ~/.bin unix.stackexchange.com/a/4973/28760 (Sanırım casekullanılan ifade daha taşınabilir , ama sen ifbenim için daha net). Bu sorunun da perl5 eklediğini garip tesadüf EDIT !
13ren

@ 13ren: Not için teşekkürler. Ben de sadece olması gereken gibi çift tırnak yerine, PATH set satırında tek tırnak kullandığımı fark ettim. Yazıldığı gibi, mevcut yolunuzu değişken adıyla değiştirirdi. Hata! Görünüşe göre bu yazım hataları için benim için kötü bir girişti; her ikisi de şimdi düzeltildi.
Christopher Cashell

0

İşte benim çözümüm: PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")

Bir iz bırakmayan güzel, kolay bir astar:

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.