Bir bash betiği yazarken, geçerli dosyanın konumunun mutlak yolunu nasıl edinebilirim?


16

Diyelim ki bir bash dosyam var myBash.bash. İçinde bulunur:

/myDirect/myFolder/myBash.bash

Şimdi betiğin içindeki dizgiyi /myDirect/myFolder(konumunu myBash.bash) kullanmak istiyorum . Bu konumu bulmak için kullanabileceğim bir komut var mı?

Düzenleme: Fikir o zip dosyası içinde bir bash komut dosyası tarafından başlatılabilir kodlu bir zip klasörü ayarlamak istiyorum. Bu zip dosyasının içindeki kodun göreceli dosya yollarını biliyorum, ama mutlak yollar değil ve bunlara ihtiyacım var. Bunun bir yolu, yolu sabit kodlamak veya dosyanın yolunun bir değişken olarak verilmesini istemektir. Ancak bash dosyasının kendi nerede olduğunu anlaması ve daha sonra zip dosyasının yapısı hakkındaki bilgisinden diğer dosyaya ilgili yollar oluşturması mümkün olsaydı daha kolay olurdu.


3
Bu yığın akışı için daha uygun olabilir. Şu soruları kontrol edin: stackoverflow.com/questions/4774054/… stackoverflow.com/questions/59895/… .
Sethos II

1
nasıl kullanılır.? lütfen açıklayın
Sergiy Kolodyazhnyy

1
@SethosII bu soru tamamen burada konu ile ilgili
Zanna

1
Soruya daha fazla bağlam ekledim. Yürütülen dosyanın dosya yolunu almak için kolay / açık bir komut olabileceğini düşündüm, ancak cevap en azından açık değil gibi görünüyor.
dimpol

3
@Zanna Ben offtopic demiyorum, sadece daha uygun olduğunu düşünüyorum ve bağlantılar zaten gösterildiği gibi orada defalarca sordu ve cevapladı.
Sethos II

Yanıtlar:


25

Tam yolu aşağıdaki gibi alabilirsiniz:

realpath "$0"

Ve Serg tarafından işaret kullanabileceğiniz dirnameböyle dosya adı şerit

dirname "$(realpath $0)"

veya zor dosya adlarıyla garip alıntıları ve kelime bölünmelerini önlemek için daha da iyidir:

temp=$( realpath "$0"  ) && dirname "$temp"

Ayrıştıracak olan önceki fikrimden çok daha iyi (daha iyi bir yol olacağını biliyordum!)

realpath "$0" | sed 's|\(.*\)/.*|\1|'

notlar

  • realpath bir dosyanın gerçek yolunu döndürür
  • $0 bu dosya (betik)
  • s|old|new|yerine oldsahipnew
  • \(.*\)//daha önce kullanmak üzere herhangi bir karakteri kaydet
  • \1 kaydedilen kısım

2
+1 kullanımı $0ve sedbüyü için. Ancak, söz konusu sedbüyü gerçekten gibi araçlar dirnamemevcut olduğunda gereksizdir
Sergiy Kolodyazhnyy

2
zaten cevabınız var, kullanın realpath: realpath "$( dirname $0 )"Şahsen kullanırım readlinkama bu benim:readlink -e $(dirname $0)
Sergiy Kolodyazhnyy

@Serg: Daha dirname "$(realpath "$0")"iyi olmaz mıydı ? Genellikle kişi, söz konusu dosyaya atıfta bulunan sembolik bağlantının üst dizini yerine başvurulan dosyanın üst dizinini bilmek ister.
David Foerster

4
@Serg "$(dirname "$(realpath "$0")")"en açık yoldur. İçerideki alıntılar $()normaldir.
DepressedDaniel

@DepressedDaniel Çevrimiçi biraz araştırma yaptınız, haklısınız: subshell $()olmak dışarıdan alıntı yapılmasına izin verecektir. Biri $()tüm alt kabukları olmadıkça, bunun kadar basit olduğunu söyleyemem
Sergiy Kolodyazhnyy

5

komut dosyası yolunuzdaysa, aşağıdaki gibi bir şey kullanabilirsiniz

$ myloc=$(dirname "$(which foo.sh)")
$ echo "$myloc"
/path/to/foo.sh

EDIT: Serg yorumlarını okuduktan sonra, bu komut dosyası yolunda olsun ya da olmasın çalışan genel bir çözüm olabilir.

myloc==$(dirname "$(realpath $0)")
dirname "$myloc"

whichbetiğin PATHdeğişkenin bir parçası olan dizinlerden birinde bulunması durumunda daha uygundur . $0Bir komut dosyasından, tıpkı Zanna'nın gösterdiği gibi kullanın . Ancak, dirnamebunun için uğraşmak yerine kullandığınız için cevabınız doğru sed, bu nedenle +1
Sergiy Kolodyazhnyy

5

Kabul edilen cevap mükemmel görünüyor. İşte bunu yapmanın başka bir yolu:

cd "$(dirname "$0")"
/bin/pwd

/bin/pwdpwdyerleşik komutun aksine dizinin gerçek yolunu yazdırır .


0
wdir="$PWD"; [ "$PWD" = "/" ] && wdir=""
case "$0" in
  /*) scriptdir="${0}";;
  *) scriptdir="$wdir/${0#./}";;
esac
scriptdir="${scriptdir%/*}"
echo "$scriptdir"

Bu gelen referans olarak alınır kenorb ve andro
Hayır dirname, readlink, realpath, BASH_SOURCE
Bütün builtins vardır

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.