余分なアイテムは#
常に尖った感嘆符を相殺しますか?良い:
有効:
#!/foo/bar
障害者:
##!/foo/bar
お持ちですか?みんな知ってるexecを実行できますか?認識されるマジック環境はありますかbar
?\x23\x23\x21...
答え1
素晴らしい、POSIX規格とにかく言うことはありません:
一般的な歴史的実装は、execl()、execv()、execle()、およびexecve()関数が実行可能ファイル(シェルスクリプトを含む)として認識されないすべてのファイルに対して[ENOEXEC]エラーを返すことです。 execlp() および execvp() 関数は、これらのファイルが見つかると、そのファイルがシェルスクリプトであると仮定し、そのファイルを解釈することが知られているコマンドソルバーを呼び出します。 POSIX.1-2008ではこれが必要です。 execvp() および execlp() のこの実装は、コマンドソルバーの実行可能ファイルに問題があるまれな場合にのみ [ENOEXEC] エラーを発生させます。これらの実装では、execlp()またはexecvp()に対する[ENOEXEC]エラーについての言及はありませんが、実装ではエラーが発生する可能性があります。
いくつかの歴史的実装がシェルスクリプトを処理する別の方法は、ファイルの最初の2バイトを"#!"文字列として認識し、ファイルの最初の行の残りの部分を実行するコマンドソルバーの名前として使用することでした。
標準開発者が指摘した混乱の潜在的な原因の1つは、プロセスイメージファイルの内容がexec機能ファミリの動作にどのような影響を与えるかです。以下は、行われたアクションの説明です。
プロセスイメージファイルがシステムに有効な実行可能ファイル(適切な権限を持つ実行可能で有効な形式)の場合、システムはファイルを実行します。
プロセスイメージファイルに適切な権限があり、実行可能であるがシステムに無効な形式(たとえば、他のアーキテクチャで認識されたバイナリ)の場合、これはエラーであり、errnoは[EINVAL]に設定されます(理由を参照)。後ろ ) on [EINVAL])。
プロセスイメージファイルに適切な権限があるが認識されない場合:
これがexeclp()またはexecvp()の呼び出しである場合は、コマンドソルバーを呼び出し、プロセスイメージファイルがシェルスクリプトであるとします。
execlp() または execvp() の呼び出しでない場合はエラーが発生し、errno は [ENOEXEC] に設定されます。
指定していないことがわかります。どのように3.1のコマンドソルバーが認識されます。
しかし、Linux、shebangが#!
正しく起動するように要求します。バラよりman 2 execve
:
execve() executes the program pointed to by filename. filename must
be either a binary executable, or a script starting with a line of
the form:
#! interpreter [optional-arg]
そしてこれは、Shebangが他の効果なしに削除されるように見える#
理由であるほど十分に一般的な解説文字です。##!
しかし、スクリプトはまだ実行を使用するのでsh
、そうでなくても/foo/bar
期待した結果ではないかもしれません。バラよりman 3 exec
:
If the header of a file isn't recognized (the attempted execve(2)
failed with the error ENOEXEC), these functions will execute the
shell (/bin/sh) with the path of the file as its first argument. (If
this attempt fails, no further searching is done.)
私はそれ以外のshebangを可能にするシステムを知らず、#!
それが特別に扱われるとは確かに疑いがあります##!
が、確かに可能です。標準はそれを排除しません。