GNU/Linux >> Linux の 問題 >  >> Linux

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

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

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

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

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

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


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

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

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

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


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

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

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


Linux
  1. シェルスクリプトを使用して各行のタブ数を数える方法は?

  2. シェルスクリプトだけを使用してテキストファイルから特定の行を取得する

  3. シェルスクリプトを使用して /etc/hosts ファイルに行を追加します

  1. シェルで .sh 拡張子のないファイルを実行する方法

  2. シェルスクリプトから、特定の行を出力した後にプログラムを強制終了します

  3. シバンまたはシバンではない

  1. どのシェルインタープリターがシバンなしでスクリプトを実行しますか?

  2. シェルスクリプトでタイムアウトしますか?

  3. シェルスクリプトの「sudoSu」がスクリプトの残りの部分をルートとして実行しないのはなぜですか?