スボンと道

スボンと道

Shebangにパスが必要なのはなぜですか?

間違った

#!ruby

正しい

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

オペレーティングシステムには、登録されたコマンドのパスに関する情報が必要ですが、なぜそのコマンドがまだ提供されると期待していますか?

答え1

おそらくカーネルをより簡単にするためのようです。カーネルが実行可能ファイルパスを検索しないと思います。これはCライブラリで処理されます。 #!処理はカーネルで行われ、標準Cライブラリを使用しません。

また、カーネルはあなたのパスが何であるかを知らないと思います。 $PATH環境変数であり、プロセスだけが環境を持つ。カーネルはそうではありません。実行を実行するプロセスの環境にアクセスできると仮定しますが、現在カーネルにはそのような環境変数にアクセスできるものがないと思います。

答え2

PATH以下を使用して検索の意味を得ることができますenv

#!/usr/bin/env ruby  

欲しい意味があります

#!ruby

依存関係がPATH良いケースと見なされない理由は、スクリプトがPATH環境変数の内容について何も仮定できないため、バイナリの「順次依存モデル」が壊れたためです。

  1. /bin起動に必要な実行ファイルが含まれています。
  2. /usr/binオペレーティングシステムのインストールに使用される他の実行可能ファイルが含まれています。
  3. /usr/local/binシステム管理者がインストールし、基本オペレーティングシステムの一部ではない実行可能ファイルが含まれています。
  4. ~/bin独自の実行可能ファイルが含まれています。

各レベルは、シーケンスの後半に「適用」されるバイナリがあると仮定してはいけませんが、より「基本的な」以前のバイナリに依存する可能性があります。 PATH変数はしばしばアプリケーションから基礎に移動します。これは上記の自然依存関係とは反対の方向です。

説明のためにRubyのスクリプトが~/binRubyのスクリプトを呼び出すとどうなりますか?自分に聞いてください。/usr/local/binスクリプトはインストールされているオペレーティングシステムのバージョンによって異なりますか/usr/bin/ruby、またはユーザーが偶然に持っている個人のコピーに依存する必要がありますか~/bin/rubyPATH検索は後者(~/bin/ruby壊れたシンボリックリンクである可能性があります)に関連する予測不可能な意味を提供しましたが、パスを焼くと前者が提供され#!ました。

プラットフォームに依存しない他の「オペレーティングシステム...登録されたコマンドのパスに関する情報」は実際にはないので、最も簡単な方法は#!

答え3

私はこれがあなたが必要な場合や必要に応じて予備通訳者を指定できると信じています。たとえば、

#!/home/user/myrubyinterpreter

シェルスクリプトでより一般的です。

#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh

答え4

他の理由もありますが、セキュリティの観点からは、スクリプトが正しいパスを想定することは決して望ましくありません。問題が発生して間違ったシェルまたはインタプリタが実行された場合はどうなりますか?悪意のあるユーザーが挿入したのですか?それとも、特定のシェルに依存し、間違ったシェルを使用すると競合が発生した場合はどうなりますか?

ユーザーは自分のパスを混乱させ、物事を破ることができます。ユーザーを信じないでください :-) 私は、ユーザーが自分のパスで間違ったことをすることに頼って、複数の攻撃を実行しました。通常、仕事を間違った順序で取得します。だから普通のスクリプトを反転することができます。電話。

はい、スクリプトを自分で書いた場合は、自分のパスを整理したと正しく主張できますが、通訳者はそのような決定を下すことができないことを知っています。

関連情報