2011-10-19 9 views
7

私は誤って#!の代わりに$!のbashスクリプトを開始し、非常に奇妙な動作をしました。私は何が起こったのか把握しようとしています。あなたは、次の動作を取得します

$!/bin/bash 
echo Hello world! 

:あなたはこのスクリプトをしようとした場合

  1. 新しいbashシェルが起動され:

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

    は、だから、これが起こったように見えます。

  2. 終了時に、残りのスクリプトが実行されました。

どうしましたか?何が起こっているのですか? #!がなければ、シェルはbashを使ってスクリプトをどのように解釈するのですか?

明らかに、これは「自分の問題を解決する」問題ではなく、「自分の好奇心を満たす」ことです。グーグルではあまり効果がありません。クエリの中で#!$!がGoogle-botを幸せにしないからです。

答えて

9

$何かは、パラメータ( "変数")そう拡張が、特にリターンの$!スクリプトに設定されていない値であり、長さゼロの文字列として展開されます。

したがって、あなたのスクリプトは、あなたが正しい、と同等です:

/bin/bash 
echo Hello world! 

shebang magic numberは、Unixの古い機能ですが、シェルはさらに古いです。カーネルが実行することができない(実際にはコンパイルされていない)実行ビットがセットされたテキストファイルは、サブシェルによって実行されます。つまり、シェルは意図的に別のシェルを実行し、パラメータとしてパス名を渡します。これは、シェルスクリプトとして書かれたコマンドが、シバンが発明される前にどのように実行されたかを示しています。

3

@ DigitalRossの回答を少し拡大しています。

最初の行に#!がない実行可能スクリプトは、bash(またはtcsh)から実行しても、/bin/shによって実行されます。これはシェル機能ではなく、カーネル内にあります。

したがって、スクリプトを実行すると/bin/sh(ほとんどのシステムではbash固有の機能を使用できないことを意味します)、$!は何も展開されていませんバックグラウンドプロセスを開始しました)、最初の行は対話型/bin/bashシェルを呼び出します。その対話型シェルを終了すると、スクリプトはecho Hello world!行を実行して終了し、元のシェルに戻ります。例えば

あなたはecho $BASH_VERSIONecho Hello world!を変更した場合、あなたはそれが何も印刷されないことがわかります - あなたが呼び出された対話型のbashシェルからhistoryを入力した場合、それは何も表示されません。

関連する問題