Henüz kimseden bahsetmediğine biraz şaşırdım, ancak readlink -f
göreceli yolları mutlak yollara dönüştürmek ve bunları PATH'a eklemek için kullanabilirsiniz.
Örneğin, Guillaume Perrault-Archambault'un cevabını geliştirmek için,
pathappend() {
for ARG in "$@"
do
if [ -d "$ARG" ] && [[ ":$PATH:" != *":$ARG:"* ]]; then
PATH="${PATH:+"$PATH:"}$ARG"
fi
done
}
olur
pathappend() {
for ARG in "$@"
do
if [ -d "$ARG" ] && [[ ":$PATH:" != *":$ARG:"* ]]
then
if ARGA=$(readlink -f "$ARG") #notice me
then
if [ -d "$ARGA" ] && [[ ":$PATH:" != *":$ARGA:"* ]]
then
PATH="${PATH:+"$PATH:"}$ARGA"
fi
else
PATH="${PATH:+"$PATH:"}$ARG"
fi
fi
done
}
1. Temel Bilgiler - Bu Ne İşe Yarar?
readlink -f
Komutu (diğer şeyler arasında) mutlak bir yol göreli bir yol dönüştürecektir. Bu gibi bir şey yapmanıza olanak sağlar
$ cd / yol / to / my / bin / dir
$ pathappend .
$ echo "$ PATH"
<your_old_path> : / yol / to / my / bin / dir
2. Niçin PATH Twice İçinde Test Yapıyoruz?
Peki, yukarıdaki örneği düşünün. Kullanıcı diyorsa
gelen ikinci kez dizine,
olacaktır . Tabii ki, içinde olmayacak . Ama sonra ayarlanır
(mutlak yol eşdeğeri ), olduğu zaten . Bu yüzden eklemekten kaçının ihtiyaç için ikinci kez.pathappend .
/path/to/my/bin/dir
ARG
.
.
PATH
ARGA
/path/to/my/bin/dir
.
PATH
/path/to/my/bin/dir
PATH
Belki daha da önemlisi, asıl amacı readlink
, adından da anlaşılacağı gibi, sembolik bir bağlantıya bakmak ve içerdiği yol adını okumaktır (yani işaret eder). Örneğin:
$ ls -ld /usr/lib/perl/5.14
-rwxrwxrwx 1 root root Sep 3 2015 /usr/lib/perl/5.14 -> 5.14.2
$ readlink /usr/lib/perl/5.14
5.14.2
$ readlink -f /usr/lib/perl/5.14
/usr/lib/perl/5.14.2
Şimdi, eğer söylerseniz pathappend /usr/lib/perl/5.14
ve /usr/lib/perl/5.14
PATH'inizde zaten varsa , peki, sorun değil; sadece olduğu gibi bırakabiliriz. Ama, eğer /usr/lib/perl/5.14
PATH içinde zaten değil, biz diyoruz readlink
ve almak ARGA
= /usr/lib/perl/5.14.2
, ve sonra biz eklemek o kadar PATH
. Ama bir dakika - eğer zaten söyledi pathappend /usr/lib/perl/5.14
, o zaman zaten /usr/lib/perl/5.14.2
yine biz eklemeden önlemek için için kontrol edilmesi gereken PATH içinde ve PATH
ikinci kez.
3. Ne ile başa çıkmak if ARGA=$(readlink -f "$ARG")
?
Belirsiz olması durumunda, bu çizgi readlink
başarılı olup olmadığını test eder . Bu sadece iyi, savunma amaçlı programlama uygulamasıdır. Eğer m komutunun çıkışını n komutunun bir parçası
olarak kullanacaksak (burada m < n ), m komutunun başarısız olup olmadığını kontrol etmek ve bunu bir şekilde ele almak akıllıca olacaktır . Bunun başarısız olacağını düşünmüyorum - ancak, OS X'den
ve başka bir yerden keyfi bir dosyanın mutlak yolunun nasıl alınacağı , bir GNU icadıdır. POSIX’de belirtilmediğinden, Mac OS, Solaris ve diğer Linux olmayan Unix’lerde kullanılabilirliği sorgulanabilir. (Aslında, ben sadece şöyle yazan bir yorum okudum :readlink
readlink
readlink -f
Mac OS X 10.11.6'da çalışmıyor gibi görünüyor, ancak realpath
kutudan çıkıyor. ”Yani, sizde olmayan readlink
veya readlink -f
çalışmayan bir sistemde iseniz , bunu değiştirebileceksiniz. kullanılacak komut dosyası realpath
.) Bir güvenlik ağı kurarak kodumuzu biraz daha taşınabilir hale getiririz.
Tabii ki, readlink
(veya realpath
) olmayan bir sistemdeyseniz, yapmak istemeyeceksiniz .pathappend .
İkinci -d
test ( [ -d "$ARGA" ]
) gerçekten gereksizdir. $ARG
Bir dizin ve readlink
başarılı olan herhangi bir senaryo düşünemiyorum , ancak $ARGA
bir dizin değil. if
Üçüncü ifadeyi oluşturmak için ilk ifadeyi kopyalayıp yapıştırdım ve -d
testi orada tembelliğin dışında bıraktım .
4. Başka Yorumlarınız var mı?
Evet. Buradaki diğer cevapların birçoğu gibi, bu da her bir argümanın bir dizin olup olmadığını test eder, öyleyse onu işler ve değilse, onu yok sayar. Bu pathappend
sadece (“ ve .
benzeri ) dosyalarda ve diğer komut dosyalarında kullanıyorsanız (veya olmayabilir) yeterli olabilir . Ancak, bu cevabın (yukarıda) gösterdiği gibi, etkileşimli olarak kullanmak tamamen mümkün. Eğer yaparsan çok şaşırırsın.bash_profile
.bashrc
$ pathappend /usr/local/nysql/bin
$ mysql
-bash: mysql: command not found
Dediğim fark ettin nysql
içinde pathappend
yerine, komuta mysql
? Ve bu pathappend
hiçbir şey söylemedi; sadece sessizce yanlış argümanı görmezden geldi?
Yukarıda söylediğim gibi, hatalarla baş etmek iyi bir uygulamadır. İşte bir örnek:
pathappend() {
for ARG in "$@"
do
if [ -d "$ARG" ]
then
if [[ ":$PATH:" != *":$ARG:"* ]]
then
if ARGA=$(readlink -f "$ARG") #notice me
then
if [[ ":$PATH:" != *":$ARGA:"* ]]
then
PATH="${PATH:+"$PATH:"}$ARGA"
fi
else
PATH="${PATH:+"$PATH:"}$ARG"
fi
fi
else
printf "Error: %s is not a directory.\n" "$ARG" >&2
fi
done
}