追加読書

追加読書

~からシェルコマンド言語POSIX仕様ページ:

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

#!POSIXが指定されていない動作であるのはなぜですか?移植性に優れ、広く使用されているものが指定されていない動作を持つべきであることは恥ずかしいです。

答え1

私は主に次の理由によると思います。

  • 動作は実装ごとに大きく異なります。バラよりhttps://www.in-ulm.de/~mascheck/various/shebang/すべての詳細を確認してください。

    ただし、ほとんどの Unix 様実装の最小サブセットを指定できるようになりました。たとえば、#! *[^ ]+( +[^ ]+)?\n(移植可能なファイル名の文字セットの文字のみを含む 1 つまたは 2 つの単語で)、最初の単語はデフォルトの実行可能ファイルの絶対パスの単語ですが、実行可能ファイルが setuid/setgid、実装がインタプリタパス、またはスクリプトパスがインタプリタに渡さargv[0]れるするかどうかを定義すると、長すぎず、アクションは指定されません。

  • POSIX はとにかく実行可能ファイルのパスを指定しません。一部のシステムには/bin/にPOSIX以前のユーティリティがあり、/usr/bin他の場所にはPOSIXユーティリティがあります(たとえば、Solaris 10には/bin/shBourneシェルがあり、POSIXユーティリティはにあります/usr/xpg4/bin。は置き換えられました。のツールは/binまだPOSIXではなく古代のツールです。一部のシステムはPOSIXシステムではありませんが、POSIXモード/エミュレーションを備えています。すべてのPOSIX要件は、システムがPOSIX方式で動作できる文書化された環境です。

    たとえば、Windows + Cygwinを参照してください。実際、Windows + Cygwinの場合、デフォルトのWindowsアプリケーションではなくcygwinアプリケーションからスクリプトを呼び出すと、シェーバンが尊重されます。

    したがって、POSIXがshebangメカニズムを指定してもPOSIX sh// sed...awkスクリプトを作成するために使用することはできません(また、shebangメカニズムは閉じるオプションマーカーを渡すことを許可しないため、信頼できるsed/スクリプトを作成するためには使用できません)。awk

#!今、指定されていないという事実がそれを使用できないという意味ではありません。しかし、そうすることで、POSIXはいかなる保証も提供しません。

私の経験では、shebangを使用すると、POSIXシェルスクリプトを書く方法よりも優れた移植性が保証されます。 she-bangを捨て、shPOSIX構文でスクリプトを作成し、そのスクリプトを呼び出すすべてがPOSIX互換スクリプトを呼び出すことを願っています。shつまり、大丈夫です。スクリプトが正しい環境で正しいツールによって呼び出されることを知っていれば、そうでなければそうではありません。

以下を行う必要があります。

#! /bin/sh -
if : ^ false; then : fine, POSIX system by default
else
  # cover Solaris 10 or older. ": ^ false" returns false
  # in the Bourne shell as ^ is an alias for | there for
  # compatibility with the Thompson shell.
  PATH=`getconf PATH`:$PATH; export PATH
  exec /usr/xpg4/bin/sh - "$0" ${1+"$@"}
fi
# rest of script

Windows + Cygwinに移植するには、ファイル名を.bat拡張子として指定し、同様のトリックを使用して同じファイルからcygwinを呼び出す必要があります。.ps1cmd.exepowershell.exesh

答え2

すべてのPOSIX互換シェルの動作は一貫しているようです。ここでは揺れる必要はないと思います。

あなたは十分に深く見ていません。

1980年代初頭、このメカニズムはいいえ事実上の標準化。 Dennis Ritchieがこれを実装しましたが、AT&T側ではまだ実装が大衆の手に届いていません。実際には公的にのみ利用可能で、BSDでのみ知られています。 AT&T Unixでは利用できない実行可能なシェルスクリプトがあります。したがって、それを標準化するのは不合理です。これは多くのdocoの1つである現代のdocoによって示されています。

BSDは#! interpreteraで始まるファイルの直接実行を許可し、SysVはa.outファイルの直接実行のみを許可します。これは、プログラムのインタプリタが(通常)実行されるためexec…()には、BSDプログラムのルーチンの1つのインスタンスがSysVで変更される必要があることを意味します。/bin/sh
— スティーブン・フリード(1988)。 「システムXバージョンYプログラミング」。オーストラリアUnixシステムユーザーグループニュースレター。 9巻4号。 111.

ここで重要なのはシェルを見ていますが、実行可能なシェルスクリプトが存在することは実際にはその機能に問題があるということですexec…()。シェルの機能は次のとおりです。電球材料今日でも、いくつかのシェルに見られる実行可能なスクリプトマシンの一部は、やや誤解を招く可能性がexec…p()あります。これに関して標準で扱うべきことは、exec…()スクリプトの仕組みとPOSIXが最初に作成された時期を説明することです。最初からターゲットオペレーティングシステムの主要部分では実行されません。

マイナーな質問は、特にスクリプトインタプリタのためのマジックナンバーメカニズムとして、それ以降標準化が行われていない理由です。持つAT&T Universe側で大衆に公開されexec…()システム5インタフェースの定義、1990年代に入り、

インタプリタファイルは、次の形式の行で始まります。

#!パス名[パラメータ]
どこパス名通訳者への道であり、アルギニンオプションのパラメーターです。インタプリタファイルを使用すると、execシステムはexec指定されたインタプリタを使用します。
execSystem V インターフェースの定義。 1991年1巻。

残念ながら、この振る舞いは1980年代のように今日でも変わりません。一部のUnices(たとえば、有名なHP-UXやFreeBSD)は、スクリプトのソルバーとしてスクリプトをサポートしていません。最初の行がスペースで区切られた1つ、2つ以上の要素であるかどうかは、MacOS(および2005年以前のFreeBSDバージョン)とは異なるオペレーティングシステムによって異なります。サポートされる最大パス長はさまざまです。 POSIX 移植可能なファイル名文字セットの外側の文字は、前後のスペースと同様にトリッキーです。 0番目、1番目、2番目のパラメーターの最終結果も難しく、システムによって大きく異なります。一部は現在POSIXと互換性がありますが、いいえ-Unixシステムはまだそのようなメカニズムをサポートしていません。

追加読書

答え3

他の回答で指摘したように、実装はさまざまです。これは標準化を困難にします。そして既存のスクリプトとの逆互換性を維持します。これは最新のPOSIXシステムでも同様です。たとえば、Linux は shebang 行を空白として完全には表示しません。 macOSでは、スクリプトソルバーが別のスクリプトになることはできません。

また見てくださいhttp://en.wikipedia.org/wiki/Shebang_(Unix)#移植性

関連情報