ファイルはシステムによって認識される実行可能ファイルのタイプではないため、そのファイルを実行する権限があると仮定すると、execve()システムコールは通常ENOEXEC(実行可能ファイルではない)エラーで失敗します。
その場合に発生するのは、コマンドを実行するために使用されるアプリケーションまたはライブラリ関数、あるいはその両方です。
たとえば、シェル、execlp()/ execvp()libc関数などです。
他のほとんどのアプリケーションは、コマンドを実行するときにこれらのいずれかを使用します。それらはの方法によって、例えばシェルを呼び出すsystem("command line")典型的に起動するlibcの関数shそのコマンドラインを解析する(パスはそのようなコンパイル時(で決定することができる/bin/shVS /usr/xpg4/bin/shSolaris上))、またはシェルたinvokeに格納されている$SHELLように、それ自体でviその   !コマンド、またはxterm -e 'command line'他の多くのコマンド(のsu user -c代わりにユーザーのログインシェルを呼び出します$SHELL)。
一般に、先頭にないシバンレステキストファイル#はshスクリプトと見なされます。shただし、どちらであるかは異なります。
execlp()/ execvp()、execve()返さENOEXECれると通常shそれを呼び出します。sh複数の標準に準拠できるために複数のシステムshがある場合、通常、コンパイル時に(異なるパスを参照する異なるコードのblobをリンクすることによりexecvp()/ を使用してアプリケーションの)決定されます。たとえば、Solarisでは、(標準のPOSIX )または(Solaris 10以前の場合はBourneシェル(旧式のシェル)、Solaris 11の場合はksh93)になります。execlp()sh/usr/xpg4/bin/shsh/bin/sh
シェルに関しては、さまざまなバリエーションがあります。bash、AT&T ksh、Bourneシェルは通常exec、をシミュレートした後(execve()エクスポートされていないすべての変数を設定解除し、すべてのclose-on-exec fdsを閉じ、すべてのカスタムトラップを削除し、エイリアス、関数...(モードでbashスクリプトを解釈しshます)。yash(と自分自身が実行されますshようargv[0]にあるのでsh、それを解釈するモード)。
zsh、pdksh、ashベースシェルは、典型的に呼び出すsh(コンパイル時に決定されたパス)。
用cshしてtcsh(とshいくつかの初期のBSD)、ファイルの最初の文字がある場合#、その後、彼らはそれを解釈するために自分自身を実行し、そしてだろうshそう。それは、シェバン前の時代にさかのぼり、Bourneシェルではなくコメントとしてcsh認識#したため、#cshスクリプトであるというヒントになりました。
fish(少なくともバージョン2.4.0)、execve()失敗した場合にエラーを返します(スクリプトとして処理しようとしません)。
一部のシェル(bashまたはAT&Tなどksh)は、最初にファイルがスクリプトである可能性が高いかどうかをヒューリスティックに判断しようとします。そのため、最初の数バイトにNUL文字が含まれていると、一部のシェルがスクリプトの実行を拒否する場合があります。
またexecve()、ENOEXECで失敗したが、ファイルにシェバン行がある場合、一部のシェルはシェバン行自体を解釈しようとすることに注意してください。
いくつかの例:
- とき$SHELLで/bin/bash、xterm -e 'myscript with args'きますmyscriptによって解釈bashでshモード。とともにxterm -e myscript with args、xtermを使用するexecvp()ため、スクリプトはによって解釈されshます。
- su -c myscriptSolaris 10でどこ- rootのログインシェルがある- /bin/shと- /bin/shBourneシェルが持つある- myscriptBourneシェルによって解釈します。
- /usr/xpg4/bin/awk 'BEGIN{system("myscript")'Solaris 10では、- /usr/xpg4/bin/sh(と同じ- /usr/xpg4/bin/env myscript)によって解釈されます。
- find . -prune -exec myscript {} \;Solaris 10(を使用- execvp())では、POSIX環境であっても(適合バグ)- /bin/shでも解釈され- /usr/xpg4/bin/findます。
- csh -c myscript- cshで始まる場合- #、- shそれ以外の場合で解釈されます。
全体として、どのスクリプトがどのように呼び出されるのかわからない場合、そのスクリプトを解釈するためにどのシェルが使用されるのかがわかりません。
いずれにせよ、構文read -pはbash-onlyなので、スクリプトが解釈されるようにしますbash(そして、その誤解を招く.sh拡張子を避けます)。bash実行可能ファイルのパスを知っており、次のいずれかを使用します。
#! /path/to/bash -
read -p ...
または、次を使用して$PATH、bash実行可能ファイル(bashインストール済みと仮定)のルックアップを試すことができます。
#! /usr/bin/env bash
read -p ...
(envほぼどこにでもあります/usr/bin)。または、POSIX + Bourne互換にすることもできます/bin/sh。この場合、を使用できます。すべてのシステムにはがあり/bin/shます。それらのほとんどで(ほとんど)POSIXと互換性がありますが、Bourneシェルが代わりに見つかることもあります。
#! /bin/sh -
printf >&2 'Enter a user name: '
read user
printf '%s\n' "$user"