2011-10-19 6 views
7

#! yerine $! ile bir bash komut dosyasını yanlışlıkla başlattım ve çok tuhaf davranışlar elde ettim. Ne olduğunu anlamaya çalışıyorum. aşağıdaki davranışla alacak

$!/bin/bash 
echo Hello world! 

: Bu komut dosyasını denerseniz

  1. yeni bash kabuk olurken:

    $ chmod +x hello 
    $ ./hello 
    [nothing happens, get prompt back] 
    $ exit 
    exit 
    Hello world! 
    $ 
    

    Yani bu oldu gibi görünüyor.

  2. Çıkışta, komut dosyasının geri kalanı yürütüldü.

N'aber? Her şey nasıl oluyor? #! olmadan, kabuk betiği yorumlamak için bash'u nasıl kullanır?

Açıkçası bu, "sorunumu çöz" sorusu yerine "merakımı tatmin eder". Googling fazla vermez, muhtemelen sorgulardaki #! ve $! Google bot'unu mutlu etmemektedir.

cevap

9

$ şey bir parametre ("değişken") genişleme, ancak belirli getiri komut dosyanızda ayarlanmamış bir değer içinde $!, bu yüzden sıfır uzunluklu bir dize olarak genişler.

/bin/bash 
echo Hello world! 

shebang magic number Unix eski özelliğidir, ancak kabuk bile eskidir:

nedenle senaryonuz eşdeğer, doğru olmaları. Yürütme biti ile birlikte bir metin dosyası, çekirdeğin çalıştırılamayacağını (aslında derlenmediği için) bir alt kabuk tarafından yürütülür. Yani, kabuk kasıtlı olarak başka bir kabuk çalıştırır ve yol adını parametre olarak geçirir. Kabuk betikleri olarak yazılan komutlar, shebang'in icat edilmeden önce nasıl yürütüldüğü ve kodda hala var.

3

@ DigitalRoss'un yanıtını biraz genişletme:. ilk satırda hiçbir #! ile

bir çalıştırılabilir komut /bin/sh tarafından yürütülür - Eğer bash (veya tcsh) onu çalıştırmak bile. Bu kabuk işlevi değil, çekirdekte.

Komut dosyanızı yürüttüğünüzde, /bin/sh (çoğu sistemde, bash'a özgü özellikleri kullanamayacağı anlamına gelir), $! hiçbir şey için genişletilemedi. herhangi bir arka plan işlemini başlattı) ve ilk satır bir etkileşimli/bin/bash kabuğunu çağırır. Ardından, o etkileşimli kabuktan çıkın ve komut dosyanız echo Hello world! satırını çalıştırıp sonlandırın ve sizi özgün kabuğunuza geri koyun.Eğer echo Hello world!echo $BASH_VERSION geçtiğinizdeyse

Örneğin, bunu şey yazmaz olduğunu göreceksiniz - ve çağrılan interaktif bash kabuğundan history yazarsanız, hiçbir şey göstermez.