./file
またはsh file
を使用してファイルを実行することの違いは何ですか?インタプリタディレクティブを使用すると、スクリプトとデータファイルをコマンドとして使用でき、コマンドラインでインタプリタをスクリプトの前に付ける必要がなくなるため、実装の詳細をユーザーや他のプログラムから隠すことができます。
パスsome/path/to/fooで識別されるBourne Shellスクリプトには、最初の行があります。
#!/bin/sh -x
そして、以下のようにパラメーターbarおよびbazで実行されます。
some/path/to/foo bar baz
代わりに次のコマンドラインを実際に実行した場合と同様の結果が得られます。
/bin/sh -x some/path/to/foo bar baz
注:1980年にDennis Ritchieがインタプリタディレクティブのカーネルサポートを導入しました:
The system has been changed so that if a file being executed begins with the magic characters #! , the rest of the line is understood to be the name of an interpreter for the executed file. Previously (and in fact still) the Shell did much of this job; it automatically executed itself on a text file with executable mode when the text file's name was typed as a command. Putting the facility into the system gives the following benefits. 1) It makes Shell scripts more like real executable files, because they can be the subject of 'exec.' 2) If you do a 'ps' while such a command is running, its real name appears instead of 'sh'. Likewise, accounting is done on the basis of the real name. 3) Shell scripts can be set-user-ID.
注:Linuxは、解釈されたすべての実行可能ファイル(つまり、#!行で始まる実行可能ファイル)のsetuidビットを無視します
4) It is simpler to have alternate shells available; e.g. if you like the Berkeley csh there is no question about which Shell is to interpret a file. 5) It will allow other interpreters to fit in more smoothly.
より詳しい情報 :
ハッシュバンの機能は、ファイルが実行されたときにkernelスクリプトインタープリターとして実行するプログラムを指示することです。
./program
を実行すると、それが正確に行われ、ファイルに対する実行権限が必要になりますが、プログラムの種類に依存しません。これは、bashスクリプト、shスクリプト、Perl、Python、awk、expectスクリプト、または実際のバイナリ実行可能ファイルです。 sh program
を実行すると、他のものではなくsh
の下で強制的に実行されます。
sh
はbash
とは異なることに注意してください!後者には、標準のシェルでは認識されていない高度な機能がいくつかあります。システムによっては、sh
が別のプログラムであるか、互換モードのBashである可能性がありますが、結果は通常同じです。高度な機能にはアクセスできません。
Bash自体はhashbang行を理解していませんが、カーネルに依存して読み取っています。一方、Perlインタープリターは、開始方法に関係なく、hashbang行を単独で読み取ります。これは、hashbang行に設定されているコマンド行オプションを選択するために行われます。 Bashはこれを行いません。
たとえば、次のスクリプトは、./script
として開始された場合(exec
とhashbang行を使用)、またはbash script
を使用して開始された場合(bashインタープリターを手動で実行した場合)によって動作が異なります。
#!/bin/bash -u
echo $1
bash
自体はシバン行に意味を付けません。コメントとしてのみ表示します。シェルがコマンドラインを読み取り、コマンドが外部プログラム(cd
のような内部コマンドではない)である場合、シェルはexecve
システムコールを使用してコマンドを実行します。次に、カーネルは、ファイルの先頭にあるマジックナンバーをチェックして、execve
に渡されたファイルがどのような実行可能ファイルかを調べます。マジックナンバーが2バイト0x23 0x21(ASCII文字#!
)、カーネルは、スクリプトのインタプリタが絶対パスに続いていると想定します。次に、カーネルはインタプリタを起動し、スクリプトを渡します。
さて、100%正確に言うと、「bash Shebang」についてはあまりありません。シバンは様々な形でポップアップすることができます。それは単に通訳の表示です。したがって、たとえば#!/usr/bin/Perl
のシバンはf.exになります。 「Perl Shebang」であり、Perlインタープリターをそのようなスクリプトのインタープリターとして指定します。次に、シェルスクリプトのように、そのようなPerlスクリプトを直接呼び出すことができます。他のスクリプトインタープリタも同じです。これは、php、cshell、prolog、basic、またはテキストファイルを何らかの方法で解釈するその他のものです。そしてもちろん、その通訳はシバンを無視できるはずです。 bashの場合、これは単なるコメント行です。 PHPとPerlについても同様です。プロローグはその行を窒息すると思います。 Shebangがテキストを解釈でき、Shebangを無視できる限り、Shebangも独自のアプリケーションでシームレスに動作するはずです。
F.ex. JavaScriptインタープリターは、そのような「Javascriptシバン」を無視することができます:)