Takma ad ve işlevler


17

Bash kılavuzundan

Takma adların tanımı ve kullanımı ile ilgili kurallar biraz kafa karıştırıcıdır. Bash, o satırdaki komutlardan herhangi birini yürütmeden önce her zaman en az bir tam satır okur. Takma adlar, bir komut yürütüldüğünde değil, okunduğunda genişletilir. Bu nedenle, başka bir komutla aynı satırda görünen bir diğer ad tanımı, bir sonraki girdi satırı okunana kadar etkili olmaz. Bu satırdaki diğer ad tanımını izleyen komutlar yeni diğer addan etkilenmez. Bu davranış, işlevler yürütüldüğünde de bir sorundur. Diğer ad, işlev yürütüldüğünde değil, işlev tanımı okunduğunda genişletilir , çünkü işlev tanımının kendisi bileşik bir komuttur. Sonuç olarak, Bir işlevde tanımlanan takma adlar, bu işlev yürütülene kadar kullanılamaz . Güvende olmak için, her zaman diğer ad tanımlarını ayrı bir satıra yerleştirin ve bileşik komutlarında diğer ad kullanmayın.

İki cümle, "İşlev yürütüldüğünde değil, işlev tanımı okunduğunda diğer adlar genişletilir" ve "işlevde tanımlanmış diğer adlar, bu işlev yürütülene kadar kullanılamaz" ifadelerinin birbirine aykırı olduğu görülmektedir.

Sırasıyla ne anlama geldiğini açıklayabilir misiniz?


İyi soru! Bugün yeni bir şey eğdim. Aslında 2 şey öğrendim: 1) işlev def okunurken diğer ad genişletme hakkında bu bilgi ve 2) gerçekten bash kılavuzunu dikkatlice okumalıyım (ki zaten yaptım sandım, ama görünüşe göre ^ ^) )
Olivier Dulac

4
Ana soru, etkileşimsiz modda takma ad kullanmalı mıdır? Bu işlevler içindir ve takma adlar komut dosyasını daha hataya açık hale getirir. Asla yukarıdaki bilgilere hiç ihtiyacım olmadı, çünkü sadece en .bashrcüstteki dosyalarda takma adlarla karşılaştım .
orion

Yanıtlar:


29
  1. Diğer ad, işlev yürütüldüğünde değil, işlev tanımı okunduğunda genişletilir…

    $ echo "Hızlı kahverengi tilki tembel köpeğin üstünden atlar." > dosyam
     
    $ takma ad myalias = kedi
     
    $ myfunc () {
    > myalias myfile
    >}
     
    $ myfunc
    Hızlı kahverengi tilki tembel köpeğin üstünden atlar.
     
    $ alias myalias = "ls -l"
     
    $ myalias myfile
    -rw-r - r-- 1 myusername mygroup 45 Ara 13 07:07 myfile
     
    $ myfunc
    Hızlı kahverengi tilki tembel köpeğin üstünden atlar.

    myfuncAramak için tanımlanmış olmasına rağmen myaliasve yeniden tanımladım myalias, myfunchala orijinal tanımını yürütür myalias. Çünkü fonksiyon tanımlandığında takma ad genişletildi . Aslında, kabuk artık bu myfuncçağrıları hatırlamıyor myalias; sadece bu myfuncçağrıları bilir cat:

    $ tip myfunc
    myfunc bir işlevdir
    myfunc ()
    {
    kedi dosyam
    }
  2. … Bir işlevde tanımlanan takma adlar, bu işlev yürütülene kadar kullanılamaz.

    $ echo "Hızlı kahverengi tilki tembel köpeğin üstünden atlar." > dosyam
     
    $ myfunc () {
    > takma ad myalias = kedi
    >}
     
    $ myalias myfile
    -bash: myalias: komut bulunamadı
     
    $ myfunc
     
    $ myalias myfile
    Hızlı kahverengi tilki tembel köpeğin üstünden atlar.

    Diğer myaliasad, myfuncişlev yürütülene kadar kullanılamaz . (Takma adı tanımlayan işlevi tanımlamanın takma adın tanımlanmasına neden olması için yeterli olmasının oldukça garip olacağını düşünüyorum.)


4
+1, iyi cevap. Bunun için önemli bir "sonuç", eğer bir komut dosyasındaki işlevleri ve diğer adları tanımlamak istiyorsa, diğer ad tanımını işlev tanımlarından önce daha iyi koymaktır! (açık, şimdi, cevap verildi, ama bunu bilmiyordum).
Olivier Dulac

Teşekkürler. Bence altta yatan bir sorun, bir fonksiyonun tanımını çalıştırmak ve bir fonksiyonu çağırmak arasındaki farktır. Özellikle, bir işlevin tanımını çalıştırırken ve sırasıyla işlevi çağırırken hangi kabuk işlemleri yapılır? Hem bir işlevin tanımını çalıştırma hem de işlevi çağıran herhangi bir kabuk işlemi var mı ya da bir işlevin tanımını çalıştırıp işlevi çağıran kabuk işlemleri örtüşmeyen bir küme işlemi gerçekleştiriyor mu?
Tim

Biraz araba inşa etmek ve araba kullanmak arasındaki farka benziyor. Ya da bir sandviç almak ve bir sandviç yemek. Diğer sorunuza daha ayrıntılı bir cevap verdim .
G-Man 'Monica'yı Eski durumuna Getir'

Teşekkürler. Alıntıyı bash kılavuzundan ve cevabınızı tekrar okuduktan sonra, bir işlevi yürütmenin anlamı hakkında kafam karıştı. Bir işlevin tanımını yürütmek veya bir işlevi çağırmak anlamına mı geliyor? Bkz. Unix.stackexchange.com/q/384209/674
Tim

1

Parçamın altında denediğimde ilk cümlenin verdiği cevaba ihtiyacım var.bashrc .

alias ls='\ls -F --color=auto --show-control-chars'
alias ll='ls -ahl'
function lf_macro() {
    local CMD=${1:-ls} DIR=${2:-.};
    $CMD $(find $DIR -maxdepth 1 -type f);
}
function lf() { lf_macro ll "$1"; }
function lsf() { lf_macro ls "$1"; }     # list all file, no directories

sonra unalias -a; source ~/.bashrcidam etmeye çalışıyorum lfve lsf,

$ lf
-bash: ll: command not found

$ lsf
./file1 ./file2 ./script.sh ...     # no color, no control-chars

$ ls $(find -maxdepth 1 -type f)
./file1 ./file2 ./script.sh* ...

takma adların işlev yürütmede değil, işlev tanımında genişletildiği açıkça görülmektedir, çünkü :

  • yürüttüğümde lfhata -bash: ll: command not foundve
  • çalıştırdığımda lsf, /usr/bin/lstakma ad formu değil, renk vurgulaması ve yürütülebilir dosyadan sonra kontrol karakterleri kullanılmadığında kullanılı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.