Shebangにパスが必要なのはなぜですか?
間違った
#!ruby
正しい
#!/usr/local/bin/ruby
#!/usr/bin/env ruby
オペレーティングシステムには、登録されたコマンドのパスに関する情報が必要ですが、なぜそのコマンドがまだ提供されると期待していますか?
答え1
おそらくカーネルをより簡単にするためのようです。カーネルが実行可能ファイルパスを検索しないと思います。これはCライブラリで処理されます。 #!
処理はカーネルで行われ、標準Cライブラリを使用しません。
また、カーネルはあなたのパスが何であるかを知らないと思います。 $PATH
環境変数であり、プロセスだけが環境を持つ。カーネルはそうではありません。実行を実行するプロセスの環境にアクセスできると仮定しますが、現在カーネルにはそのような環境変数にアクセスできるものがないと思います。
答え2
PATH
以下を使用して検索の意味を得ることができますenv
。
#!/usr/bin/env ruby
欲しい意味があります
#!ruby
依存関係がPATH
良いケースと見なされない理由は、スクリプトがPATH環境変数の内容について何も仮定できないため、バイナリの「順次依存モデル」が壊れたためです。
/bin
起動に必要な実行ファイルが含まれています。/usr/bin
オペレーティングシステムのインストールに使用される他の実行可能ファイルが含まれています。/usr/local/bin
システム管理者がインストールし、基本オペレーティングシステムの一部ではない実行可能ファイルが含まれています。~/bin
独自の実行可能ファイルが含まれています。
各レベルは、シーケンスの後半に「適用」されるバイナリがあると仮定してはいけませんが、より「基本的な」以前のバイナリに依存する可能性があります。 PATH変数はしばしばアプリケーションから基礎に移動します。これは上記の自然依存関係とは反対の方向です。
説明のためにRubyのスクリプトが~/bin
Rubyのスクリプトを呼び出すとどうなりますか?自分に聞いてください。/usr/local/bin
スクリプトはインストールされているオペレーティングシステムのバージョンによって異なりますか/usr/bin/ruby
、またはユーザーが偶然に持っている個人のコピーに依存する必要がありますか~/bin/ruby
? PATH
検索は後者(~/bin/ruby
壊れたシンボリックリンクである可能性があります)に関連する予測不可能な意味を提供しましたが、パスを焼くと前者が提供され#!
ました。
プラットフォームに依存しない他の「オペレーティングシステム...登録されたコマンドのパスに関する情報」は実際にはないので、最も簡単な方法は#!
。
答え3
私はこれがあなたが必要な場合や必要に応じて予備通訳者を指定できると信じています。たとえば、
#!/home/user/myrubyinterpreter
シェルスクリプトでより一般的です。
#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh
答え4
他の理由もありますが、セキュリティの観点からは、スクリプトが正しいパスを想定することは決して望ましくありません。問題が発生して間違ったシェルまたはインタプリタが実行された場合はどうなりますか?悪意のあるユーザーが挿入したのですか?それとも、特定のシェルに依存し、間違ったシェルを使用すると競合が発生した場合はどうなりますか?
ユーザーは自分のパスを混乱させ、物事を破ることができます。ユーザーを信じないでください :-) 私は、ユーザーが自分のパスで間違ったことをすることに頼って、複数の攻撃を実行しました。通常、仕事を間違った順序で取得します。だから普通のスクリプトを反転することができます。電話。
はい、スクリプトを自分で書いた場合は、自分のパスを整理したと正しく主張できますが、通訳者はそのような決定を下すことができないことを知っています。