Farklı komut dosyaları tarafından kullanılabilen bir Bash işlevi nasıl tanımlanır


13

Dosyamda bir bashişlev tanımladım ~/.bashrc. Bu onu kabuk terminallerinde kullanmama izin veriyor. Ancak, bir komut dosyasından çağırdığımda görünmüyor.

bashKomut dosyaları tarafından da kullanılacak bir işlevi nasıl tanımlayabilirim ?


Ama benim .bash_profile temelde .basrc dosyasını okur, bu yüzden giriş veya giriş olmayan kabuk kullandığım dikkate alınmadan sonucun aynı olmasını beklerim.
Onturenio

/bin/shMesele hattında mı kullanıyorsun ?
Kevin

Yanıtlar:


9

~/.bash_profileve ~/.bashrckomut dosyaları tarafından okunmaz ve işlevler varsayılan olarak dışa aktarılmaz. Bunu yapmak için şu şekilde kullanabilirsiniz export -f:

$ cat > script << 'EOF'
#!/bin/bash
foo
EOF
$ chmod a+x script
$ ./script
./script: line 2: foo: command not found
$ foo() { echo "works" ; } 
$ export -f foo
$ ./script
works

export -f foo~/.bash_profilebu işlevi giriş yaptıktan sonra komut dosyaları için kullanılabilir hale getirmek için de çağrılabilir . export -fTaşınabilir olmayan uyarıda bulunun.

Daha iyi bir çözüm kullanarak fonksiyonu içeren dosyayı kaynaklamak olacaktır . file. Bu çok daha portatiftir ve ortamınızın belirli bir şekilde kurulmasına bağlı değildir.


neden olmasın gibi bir işlevi bildirmek function myFunction { ... }içinde ~/.bash_profileve sen iyi gitmeye?
amphibient

Cevabınızı düzgün bir şekilde anladıysam (işlevle bir dosyayı kaynaklamakla ilgili), bu dosyayı her komut dosyasında açıkça kaynaklamak zorunda olduğum anlamına geliyor, ki bu oldukça can sıkıcı. Bu, her komut dosyasına işlevin kendisini kopyalayıp yapıştırmaktan çok daha az karmaşık değildir. Elbette bazı çizgiler kaydederdim, ama hepsi bu. Ancak, exportçözüm düzgün çalışıyor gibi görünüyor. Teşekkürler.
Onturenio

@foampile, bu tam olarak yaptığım şeydir ve bir komut dosyasından işlevi çağırırken çalışmaz.
Onturenio

1
@Onturenio: Birisi senaryoyu okuduğumda 1), onlar da bazı ihtiyaçları olduğunun farkındayız: Chris aşağı önerilen @ ikinci yöntem gerçekten iyidir foobazılarından işlevini fileEn iyisi içeriğini kontrol edebilirsiniz) 2 fileçağıran kabuğun emin daha marka foobetiğinizi çalıştırmadan önce değişmedi . fileÖrneğin, denetlenmemiş olduğundan emin olmak için güvenlik denetimleri ekleyebilirsiniz . (kolay değil, ancak mümkün). (Eh, tanımlanmış foo işlevi üzerinde bu kontrolleri de yapabilirsiniz ... ama benim sapma olsun ^ ^ Yöntem 2 daha temiz olduğunu düşünüyorum.) 3) filesadece gerekli olanı içerir, daha fazla değil.
Olivier Dulac

8

.bashrcyalnızca etkileşimli kabuklar tarafından okunur. Bash okumaz Bash bu açıdan ilginç. (Aslında o bir oversimplification .bashrcinteraktif, bir giriş kabuğu eğer ya da değil Ve bir istisna bile istisna var:. Bash ebeveyni süreci ise rshdveya sshddaha sonra bash okuyacak .bashrc, etkileşimli olsun veya olmasın.)

İşlev tanımlarınızı bilinen bir yere bir dosyaya koyun ve .(aynı zamanda yazıldığını source) yerleşik dosyayı kullanarak bir dosyayı betiğe ekleyin.

$ cat ~/lib/bash/my_functions.bash
foo () {

$ cat ~/bin/myscript
#!/bin/bash
. ~/lib/bash/my_functions.bash
foo bar

İsterseniz, ksh'ın otomatik yükleme özelliğini takip edebilirsiniz. Her işlev tanımını işlevle aynı ada sahip bir dosyaya yerleştirin. FPATHDeğişkende işlev tanımlarını içeren dizinleri (iki nokta üst üste işaretli dizin listesi) listeleyin. İşte autoload, isteğe bağlı olarak hemen işlevi yükleyen ksh'ların kaba bir yaklaşımı :

autoload () {
  set -- "$(set +f; IFS=:;
            for d in $FPATH; do
              if [ -r "$d/$1" ]; then echo -E "$d/$1"; break; fi;
            done)"
  [[ -n $1 ]] && . "$1"
}

Bash ile gelenleri kullanmanızı öneririm, ancak otomatik yükleme için +1. En sonuncusu tembel yükü destekler.
Denizyıldızı

0

Eğer Do gerek bir işlevi? Değilse, mantığı ayrı bir bağımsız Bash betiğine çekmeyi düşünün $PATH. Örneğin, bu benim vardı ~/.bashrc:

# echo public IP address
alias wanip='dig +short myip.opendns.com @resolver1.opendns.com'

~/binbenim $PATH, bu yüzden ~/bin/wanipaşağıdaki içeriklerle oluşturdum :

#!/bin/bash

# echo public IP address
dig +short myip.opendns.com @resolver1.opendns.com

Ve çalıştırılabilir chmod 0755 ~/bin/wanipyapmak için koştu . Şimdi wanipdiğer komut dosyalarından da çalıştırabilirim .

wanipTek başına bir Bash senaryosuna sahip olmayı seviyorum . Bu mantığın genel olarak kullanılabilir olmasını istediğimi hatırlatıyor (sadece şu anki etkileşimli Bash oturumumun yanı sıra). Komut dosyası, mantığı ve belgeleri güzel bir şekilde içine alı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.