シバンとパス


22

なぜシバンにはパスが必要なのですか?

違う

#!ruby

正しい

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

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

回答:


22

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

また、カーネルにはパスが何であるかという概念はないと思います。 $PATH環境変数であり、プロセスのみが環境を持っています。カーネルはしません。execを実行したプロセスの環境にアクセスできると思いますが、現在カーネルにあるものがそのような環境変数にアクセスすることはないと思います。


5

PATHを使用して-searchingセマンティクスを取得できますenv

#!/usr/bin/env ruby  

あなたが望むセマンティクスを持っています

#!ruby

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

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

各レベルは、シーケンスの後半のバイナリの存在を想定するべきではありません。バイナリはより「アプリケーション」であり、より早期のバイナリに依存する可能性があります。また、PATH変数は、アプリケーションからファンダメンタルまで実行される傾向があります。これは、上記の自然な依存関係とは逆の方向です。

問題を説明するために、~/binスクリプト/usr/local/binがRubyを呼び出すスクリプトを呼び出すとどうなるかを自問してください。そのスクリプトは、OSがインストールされているバージョン/usr/bin/ruby、またはユーザーがたまたま持っている個人用コピーに依存する必要があります~/bin/rubyか? PATH検索は、後者に関連付けられた予測不可能なセマンティクス(おそらく~/bin/ruby壊れたシンボリックリンク)を#!提供し、パスをベイクして前者を提供します。

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


0

必要な場合、または必要に応じて、別の通訳を指定できると思います。例えば:

#!/home/user/myrubyinterpreter

シェルスクリプトでよく見られます:

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

4
しかし、なぜそれが必要になるのでしょうか?あなたは直接ルビー実行することができますrubyが、それは指定からあなたを停止しない/home/user/myrubyinterpreterあなたがしたい場合
マイケルMrozek

マイケルのポイントはまさに私が求めていることです。

0

クラシックシェルスクリプトブック:

通常、シェルスクリプトはで始まり#! /bin/shます。/bin/shPOSIXに準拠していない場合は、POSIX準拠のシェルへのパスを使用します。また、注意すべき低レベルの「落とし穴」もあります。

  • 実行するインタープリターへのフルパス名を知っている必要があります。異なるベンダーは異なる場所に物を置くので、これはクロスベンダーの移植性を防ぐことができます(例/bin/awk:)/usr/bin/awk

-2

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

ユーザーはパスをいじって物を壊すかもしれません-ユーザーを信頼しないでください:-)ユーザーがパスで間違ったことをすることを頼りに多くの攻撃を行いました-通常は間違った順序で物事を取得するので、私は破壊することができます通常のスクリプト呼び出し。

はい、スクリプトを自分で書いた場合、自分の道を整理したとかなり正しく主張できますが、インタープリターはそれらの決定を下すことはできません。


この懸念は、スクリプトが昇格された特権で実行されている場合にのみ適用されます。shebangとsetxidが一緒にうまく動作しないため、それは珍しいことです$PATH。心配することはもっとあります。。昇格された権限がない場合LD_PRELOAD、使用されたらどうなりますか?セキュリティに関する誤った警告を与えることはセキュリティに有害であるため、PS Downvoted。
ジル 'SO-悪であるのをやめる'

setxidについてのあなたのポイントは有効です、しかし、それはそう間違いなく完璧に便利な攻撃ベクトルである偽の警告ではありません
ロリー・オールソップ

1
あなたは例の例与える可能性がありPATH、攻撃ベクトルであり、かつ全体的なアプローチを再考する必要がありますように、他の多くの攻撃ベクトルが存在しませんの?
ジル「SO-悪であるのをやめる」

@Gilles-間違いなく、これが壊れている場合と同じように有効な他の方法があるかもしれませんが、修正できる壊れた点に関しては、これは簡単な方法です。
ロリーアルソップ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.