0 $ ile BASH_SOURCE arasında seçim yapmak


119

"$0"Ve arasında nasıl seçim yapılır"${BASH_SOURCE[0]}"

GNU'nun bu açıklaması bana pek yardımcı olmadı.

    BASH_SOURCE

 An array variable whose members are the source filenames where the
 corresponding shell function names in the FUNCNAME array variable are
 defined. The shell function ${FUNCNAME[$i]} is defined in the file
 ${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}

BASH_SOURCEbash-3.0-alpha'da eklendi. Test rejiminize bağlı olarak buna sahip olmayabilirsiniz. Hem erken Solaris hem de OS X'te eksik buldum. Ayrıca dönüşe bakın : U & L.SE'de yalnızca bir işlevden veya kaynaklı komut dosyasından `` geri dönebilir '' .
jww

Yanıtlar:


174

Not: POSIX uyumlu bir çözüm için bu yanıta bakın .

${BASH_SOURCE[0]}(veya, daha basit olarak, $BASH_SOURCE[1] ), tüm çağrı senaryolarında, özellikle de komut dosyası kaynaklandığında içeren komut dosyasının (potansiyel olarak göreceli) yolunu içerir , ki bu doğru değildir $0.

Ayrıca, Charles Duffy'nin de işaret ettiği gibi, arayan tarafından keyfi bir değere $0ayarlanabilir . Kapak tarafında, isimlendirilmiş dosya yoksa boş olabilir ; Örneğin:
$BASH_SOURCE
echo 'echo "[$BASH_SOURCE]"' | bash

Aşağıdaki örnek bunu göstermektedir:

Senaryo foo:

#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"

$ bash ./foo
[./foo] vs. [./foo]

$ ./foo
[./foo] vs. [./foo]

$ . ./foo
[bash] vs. [./foo]

$0POSIX kabuk belirtiminin bir parçasıdır, oysa BASH_SOURCEadından da anlaşılacağı gibi Bash'e özgüdür.


[1] İsteğe bağlı okuma: ${BASH_SOURCE[0]}ile$BASH_SOURCE :

Bash, skaler gösterimi kullanarak 0bir dizi değişkeninin öğesine başvurmanıza izin verir : yazmak yerine yazabilirsiniz ; başka bir deyişle: değişkene bir skaler gibi başvurursanız , indekste öğeyi alırsınız . ${arr[0]}$arr0

Bu özelliği kullanmak $arr, bir dizi olduğu gerçeğini gizler , bu nedenle popüler kabuk kodu linter shellcheck.net aşağıdaki uyarıyı verir (bu yazı itibariyle):

SC2128: Bir diziyi indeks olmadan genişletmek yalnızca ilk öğeyi verir.

Bir yan not: Bu uyarı yararlı olsa da, daha kesin olabilir, çünkü ilk öğeyi almanız gerekmeyecektir : Özellikle 0döndürülen, dizindeki öğedir , bu nedenle ilk öğenin daha yüksek bir dizini varsa - ki Bash'de mümkündür - boş dizgeyi alırsınız; deneyin 'a[1]='hi'; echo "$a"'.
(Buna karşılık, zshher zamankinden dönek gerçekten yapar , indeksinin bakılmaksızın, ilk elemanını döndürür).

Pragmatik anlamda, nedeniyle karanlığa için bu özelliği eschew tercih edebilir, ancak tahmin edilebileceği çalışır ve, nadiren, eğer hiç, erişim ihtiyacı endeksleri edeceğiz diğer daha 0dizi değişkenin ${BASH_SOURCE[@]}.


yani $ BASH_SOURCE daha genel ve daha fazla durumda işe yarıyor mu?
Alexander Mills

2
@AlexanderMills Evet, Bash kullanıyorsanız $BASH_SOURCEdaha iyi bir seçimdir.
mklement0

18

Bu komut dosyaları açıklamaya yardımcı olabilir. Dıştaki komut dosyası, içteki komut dosyasını çağıran ortadaki komut dosyasını çağırır:

$ cat outer.sh
#!/usr/bin/env bash
./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "\$0 = '$0'"
echo "\${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "\${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "\${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
$ ./outer.sh
$0 = './inner.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = ''
$BASH_SOURCE[2] = ''

Bununla birlikte, komut dosyası çağrılarını sourceifadelere değiştirirsek:

$ cat outer.sh
#!/usr/bin/env bash
source ./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
source ./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "\$0 = '$0'"
echo "\${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "\${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "\${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
$ ./outer.sh
$0 = './outer.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = './middle.sh'
$BASH_SOURCE[2] = './outer.sh'

1

Taşınabilirlik ${BASH_SOURCE[0]}için, tanımlandığında veya $0başka şekilde kullanın. Bu verir

${BASH_SOURCE[0]:-$0}

Özellikle, zsh diyelim, $ 0, komut dosyası sourced olsa bile doğru dosya yolunu içerir .

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.