Bir link aracılığıyla çalıştırıldığında mevcut betiğin yolunu alın


58

Bazı bash betiği olan birkaç dizinden ve muhtemelen her makinede farklı bir dizinde bulunan birkaç makineye dağıtılacak destek dosyalarından oluşan bir yardımcı programım var. Komut dosyalarının kendilerine göre yollara referans verebilmeleri gerekir, bu nedenle yürütülmekte olan dosyanın yolunu bulabilmeliyim.

dirname $0Senaryomu doğrudan çağırdığınızda mükemmel çalışan deyimin farkındayım . Ne yazık ki, tamamen farklı bir dizinden bu komut dosyalarına sembolik bağlantılar oluşturabilmek ve göreceli yamalama mantığı çalışmasına sahip olmak arzusu var.

Genel kurutma yapısı örneği aşağıdaki gibidir:

/
 |-usr/local/lib
 |  |-foo
 |  |  |-bin
 |  |  |  |-script.sh
 |  |  |-res
 |  |  |  |-resource_file.txt
 |-home/mike/bin
 |  |-link_to_script (symlink to /usr/local/lib/foo/bin/script.sh)

Nasıl güvenilir bir referans verebilir /usr/local/lib/foo/res/resource_file.txtdan script.sho tarafından çağrıldığında /usr/local/lib/foo/bin/script.shya ~mike/bin/link_to_script?

Yanıtlar:


79

Bunu genel amaçlı bir çözüm olarak deneyin:

DIR="$(cd "$(dirname "$0")" && pwd)"

Aşağıdaki sembolik bağların özel durumunda, bunu da yapabilirsiniz:

DIR="$(dirname "$(readlink -f "$0")")"

Mükemmel çalışıyor ve çalıştığımdan çok daha basit. Teşekkürler!
Mike Deck,

@MikeDeck Keyfini çıkarın. İlk gönderimden bu yana bazı alıntı sorunlarını çözdüğümü unutmayın ... yolunuzda boşluklar veya başka tuhaf karakterler olması durumunda en son düzenlemeden bir seçenek kullanabilirsiniz. Bu proje için önemli olmasa bile, kodu yoldaki kendi komut dosyalarınızdan kopyalayabilir ve en iyi seçeneğe sahip olmalısınız!
Caleb,

1
Aydınlatmalıyım, ikincisi mükemmel çalışıyor. Verdiğiniz ilk çözüm sistemimdeki sembolik bağlantılar için işe yaramıyor.
Mike Deck,

4
@MikeDeck: İlk çözüm, yolun bir parçası olarak birbirine bağlanmış çeşitli dizinlere sahip olmanın tipik durumu için işe yarar, ancak son ikili bir işaret ise, yardımcı olmaz. İkincisinin halletmesi gereken şey bu.
Caleb,

1
Komut dosyası sourced ise (örneğin $ source ./sript.sh) çalışmaz Bu her iki durumda da işe DIR="$(cd "$(dirname "$BASH_SOURCE")" && pwd)"
yarar

7

Tek çizgi:

cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))

2
Bir satırlık cevaplar tipik olarak en yararlı değildir. Lütfen önerilen çözümünüzü daha fazla destekleyecek açıklamalar, bağlantılar veya belgeler eklemek için cevabınızı genişletmeyi düşünün.
HalosGhost

1
Aslında, bunu yapmanıza gerek yok, orijinal cevabın
okuma

3

readlink -f benim için çalışmıyor, ben bu hatayı:

readlink: illegal option -- f
usage: readlink [-n] [file ...]

Ancak bu iyi çalışıyor:

DIR="$(dirname "$(readlink "$0")")"
echo $DIR

3
O zaman bir Mac üzerindesiniz ve bu sorunuza cevap vermeli .
Isaac

Evet, MacO'lar @isaac'tayım, ancak herhangi bir sorum yok. Yanımda çalışan emri gönderdim.
Kevin Campion

0

Yukarıdaki betiğe küçük bir ekleme. Pwd için -P seçeneği sembolik izleri takip eder.

DIR="$(cd "$(dirname "$0")" && pwd -P)"

7
Bu yalnızca sembolik link dizin yapısının bir parçası olduğunda çalışır. Dosyanın kendisi bağlı olduğunda çalışmaz.
Oliver Gondza
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.