web-dev-qa-db-ja.com

シェルスクリプトはシバン行なしで正常に動作しますか?どうして?

私は簡単なシェルスクリプトを書いていて、私のシェルスクリプトはシバン行を必要としないことがわかりました

#!/bin/sh

スクリプトに実行権限を与え、./myscript.shを使用して実行した場合。それはうまくいきます。

私はbashシェルを使用しており、/bin/shは実際にはbashを指しています。

lrwxrwxrwx 1 root root /bin/sh -> bash

Shebang行は、スクリプトの残りの部分で使用するインタープリターをシェルに指示するために使用されることを知っています。

Perlでシバン行を見逃し、実行権限を与えて./myscript.plを実行すると、機能しません。

ここで実際に何が起こっていますか? ./を使用する場合、シバン行が実際に必要になるのはいつですか?

27
user966588

シバン行が必要inファイルであり、それが実行可能ファイルとして実行されることを意図している場合のみ(sh file.sh呼び出しとは対照的です。実際にはスクリプトでは必要ありません。システムが認識しているためです)通訳を見つける方法。

[〜#〜] edit [〜#〜]:質問を誤解して申し訳ありません。シバン行がないか、認識されない場合は、/bin/shが使用されます。しかし、私は通訳について明示することを好みます。

この動作は普遍的ではないことに注意してください。IIRCでは、一部のexec*ファミリー関数のみがこれを実行します(異なるプラットフォームは言うまでもありません)。そのため、ここで明示する必要があります。

./myscript.shを入力した親シェルは、最初にexecveを試行しました。これは、存在する場合にShebang行が有効になる場所です。これが機能する場合、カーネルはELFを処理するため、親はスクリプトとELFの違いを認識しません。

execveが失敗したため、シバンラインの存在を前提とした古いUNIX互換機能がアクティブ化されました。実行権限はあるが、カーネルによって有効な実行可能ファイルとして認識されないファイルは、シェルスクリプトである必要があると推測されました。

通常、親シェルは、スクリプトが同じシェル用に記述されていると推測します(最小限のBourneのようなシェルは/bin/shでスクリプトを実行し、bashはbashサブプロセスとして実行します)、 cshはいくつかを実行します最初の文字に基づいた推測は、シバンよりも古く、ボーンシェルと共存する必要があったためです。

これらの推測が間違っていることがわかっている場合(たとえば、Shebangが#!/usr/bin/Perlである場合)、または推測が一貫して機能することが信頼できない場合、またはスクリプトがスクリプトによって実行可能である必要がある場合は、Shebang行が必要です。シェル自体ではない親プロセス。

18
Alan Curry

POSIX(Single UNIX Specification 4)標準は役に立ちません。

シェルコマンドのファイルの最初の行が文字「#!」で始まる場合、結果は不定です。

したがって、標準では、#がない場合は!次に、POSIXシェルを実行する必要があります。しかし、最近のシェルはPOSIXに準拠していません。古いKorn Shell 88(ksh88)は#なしでBourne Shell(POSIX Shellに近い)を実行していました。行、しかしksh93はそれを壊し、Bashもそうします。 ksh93とBashの両方で、#がない場合は独自のシェルを実行します。ラインが存在します。

世論にもかかわらず、BashシェルとKornシェルは異なります。シェルスクリプトを作成するときは、どのシェルから実行するか、または別のシェルから実行するかどうかを確認することはできません(ほとんどのプログラミング言語は他のプログラムを実行できます)。 Bourne/POSIX構文の外で何かを使用すると、すぐに混乱してしまいます。

常に#を使用してください!ライン、それを偶然に任せないでください。

3
cdarke