aşağıda belirtilen çağrı fonksiyonu


15

Aşağıda bash olarak bildirilen bir işlevi çağırmak mümkün müdür?

Misal

if [ "$input" = "yes" ]; then
    YES_FUNCTION
elif [ "$input" = "no" ]; then
    NO_FUNCTION
else
    exit 0;
fi

YES_FUNCTION()
{
  .....
  .....
}

NO_FUNCTION()
{
  .....
  .....
}

Yanıtlar:


37

Diğerlerinin söylediği gibi, bunu yapamazsın.

Ancak kodu, ana program dosyanın üstünde olacak ve diğer işlevler aşağıda tanımlanacak şekilde bir dosyaya yerleştirmek istiyorsanız, ayrı bir mainişleve sahip olarak yapabilirsiniz .

Örneğin

#!/bin/sh

main() {
    if [ "$1" = yes ]; then
        do_task_this
    else
        do_task_that
    fi
}

do_task_this() {
    ...
} 
do_task_that() {
    ...
} 

main "$@"; exit

mainDosya sonunda aradığımızda , tüm fonksiyonlar zaten tanımlanmıştır. Açıkça geçen "$@"için mainişlev görebilir komut komut satırı değişkenleri yapmak için gereklidir.

exitMain çağrısı ile aynı satırdaki açık zorunlu değildir, ancak komut dosyası değiştirilirse çalışan bir komut dosyasının dağılmasını önlemek için kullanılabilir. Bu olmadan, kabuk, maindönüşten sonra komut dosyası dosyasındaki komutları okumaya devam etmeye çalışır . (bkz . Tüm kabuk betiğini çalıştırmadan önce nasıl okunur? )


@ikkachu işe yaradığını düşünüyorum .. kontrol edeyim.
msp9011

8
Bash betikleri ile genellikle [[ ${BASH_SOURCE[0]} = "$0" ]] && Main "$@"ana işlevi çağırmak için kullanırım , böylece başka bir komut dosyasında Mainyürütülmeden kaynak yapabilirim . Sonra fonksiyonları tekrar kullanabilir veya kontrol etmek için testler yazabilirim.
BlackJack

11
Ayrıca main "$@"; exit(ile exitaynı satırda main), yorumlanırken değiştirilen dosyaya karşı bir koruma olarak da yararlıdır.
Stéphane Chazelas

2
@JoL, okunanlar tekrar okunmaz ve kabuğun çalıştırmaya başlamadan önce bir döngünün tüm metnini okuması ve ayrıştırması gerekir, ancak daha sonra döngü döndükten sonra dosyanın geri kalanından okumaya devam eder. geçerli konum (ve dosya değiştirilmişse işleri bozar). Her şey fonksiyonları ise, kabuk ihtiyaçları biz koyarsanız, (bu işlevleri tanımlayan hariç) bir şey yapmak için başlamadan önce her şeyi okumaya exitaynı satırda mainPeşinde dosyadan tekrar emin kabuk okumazlar şey yapmak maingetiri.
Stéphane Chazelas

1
@MontyHarder, bunu kullandığınız takdirde önemli değil main; exit, main; exit $?ya main <EOF>her durumda, çıkış kodu mainkomut çıkış kodu olarak kullanılır. Bu exitsadece birisi çalışırken senaryoyu düzenlerse, işlerin dağılmasını önlemek olacaktır.
ilkkachu

14

Hayır, fonksiyonlar onları çağırırken kabuklar ortamında bulunmalıdır.

Google'ın "Kabuk Stili Kılavuzu" bunun için bir düzeltmeye sahiptir:

mainEn az bir başka işlev içerecek kadar uzun komut dosyaları için çağrılan bir işlev gereklidir.

Komut dosyasının en sonunda, tüm işlevlerden sonra, bir işlevde olmayan tek ifade olarak,

main "$@"

Bu main, komut dosyasına verilen parametrelerle işlevi çağırır . mainFonksiyon komut dosyasının en üstünde yer alabilir (stil kılavuzu altındaki koymak için söylüyor, ama sonra tekrar, birçok şeyler söylüyor).

Kabuk mainçağrıyı aldığında , komut dosyasındaki tüm işlevler ayrıştırılır ve bu nedenle mainişlevin içinden çağrılabilir .


9

Hayır, işlevler kullanılmadan önce bildirilmelidir. Kabuk komut dosyaları satır satır okunur ve satır satır hareket edilir; bu nedenle bir işlev, bildirimi yürütülene kadar mevcut değildir.


Haklısın. sorun ben bir senaryoda 30 + fonksiyonları var. kodu okurken oldukça zor. In Crahat.
msp9011

3
İşlev bildirimlerinizi başka bir dosyaya koyabilir ve kaynak ( . yourfile) yapabilirsiniz.
Stephen Kitt

Evet, bunu denedim, ancak gereklilik tek bir komut dosyasına sahip olmak.
msp9011

@SivaPrasath Sorun tam olarak nedir? Sadece tüm fonksiyonları tanımlayın, hatta ana kodu bir fonksiyona koyun ve son satır hangi fonksiyonun çağrıldığını gösterir ve kodun ana kısmını içerir.
BlackJack

@SivaPrasath C'de ifbir işlevin dışında çıplak ifadeleriniz yoktur. İşlevi ne zaman tanımlanmalıdır zorunda değildir beyanif sadece zaman ihtiva eden işlevini çağırır onu.
chepner

4

Kabuk declaringbir işlev kavramına sahip değildir . Dolayısıyla ileri bir beyanınız olamaz.

Sonuç olarak, çağrılmadan önce işlev uygulamasının kabuk tarafından okunması gerekir.


4
Teknik olarak, bazı kabuklar (ksh, zsh), bir tür bildirim olarak görülebilen bir işlev otomatik yükleme özelliğine sahiptir (burada işlevi bildirir, ancak gövdesi yalnızca ilk çağırma üzerine yüklenir ). Bu OP için geçerli değildir . autoload fbash
Stéphane Chazelas
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.