33

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

#!/bin/sh

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

私はbashシェルを使用しており、/bin/sh実際にはbash.

lrwxrwxrwx 1 root root /bin/sh -> bash

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

perl で shebang 行を見逃して、実行権限を与えて run を実行すると./myscript.pl、機能しません。

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

4

3 に答える 3

32

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

失敗したexecveため、シバン行が存在する前の古代の UNIX 互換機能が有効になりました。実行権限はあるが、カーネルによって有効な実行ファイルとして認識されないファイルは、シェル スクリプトに違いないと推測しました。

通常、親シェルはスクリプトが同じシェル用に書かれていると推測します (最小の Bourne のようなシェルはスクリプトを で実行し/bin/sh、bash は bash サブプロセスとして実行します)、 csh は最初の文字に基づいてより複雑な推測を行います。 Bourne シェルと共存する必要がありました)。

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

于 2012-09-06T09:16:11.167 に答える
18

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

編集:質問を読み違えて申し訳ありません。シバン行が欠落しているか認識されていない場合は、/bin/shが使用されます。しかし、私はインタープリターについて明確にすることを好みます。

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

于 2012-09-06T08:51:51.193 に答える
4

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

シェルコマンドのファイルの最初の行が文字「#!」で始まる場合 、結果は指定されていません。

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

一般的な意見にもかかわらず、Bash シェルと Korn シェルは異なります。シェル スクリプトを作成する場合、どのシェルから実行されるか、または別のシェルから実行されるかどうかさえもわかりません (ほとんどのプログラミング言語は、他のプログラムを実行できます)。Bourne/POSIX 構文以外の何かを使用するとすぐに台無しになります。

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

于 2012-09-06T09:24:43.687 に答える