GNU/Linux >> Linux の 問題 >  >> Linux

#!/usr/bin/env bash と #!/usr/bin/bash の違いは何ですか?

シェル スクリプトが 05 で始まる場合 、常に 17 で実行されます 29 から .ただし、36 で始まる場合 、 46 を検索します 53 で そして、最初に見つけたものから始めます。

なぜこれが役立つのでしょうか? 61 を実行したいとします。 bash 4.x 以降を必要とするスクリプトですが、システムには 76 しかありません 3.x がインストールされており、現在、ディストリビューションで新しいバージョンが提供されていないか、管理者ではないため、そのシステムにインストールされているものを変更できません。

もちろん、bash のソース コードをダウンロードして、80 に配置して独自の bash をゼロから作成することもできます。 例えば。 93 を変更することもできます 105 の変数 112 を含めるファイル 最初のエントリとして (125 133 として 143 では展開されません )。 158 を呼び出す場合 、シェルは最初に 166 でそれを探します 順番に、176 から始まります 184 が見つかる場所 .スクリプトが 198 を検索すると、同じことが起こります 207 を使用 、したがって、これらのスクリプトは、カスタム 212 を使用してシステムで動作するようになります ビルドします。

1 つの欠点は、これが予期しない動作につながる可能性があることです。同じマシン上の同じスクリプトが、さまざまな環境やさまざまな検索パスを持つユーザーのさまざまなインタープリターで実行される可能性があり、あらゆる種類の頭痛の種になります。

226 の最大の欠点 一部のシステムでは 1 つの引数しか許可されないため、これを行うことはできません 231 、システムは 242 を認識します。 1つの引数として(式が引用されているかのように扱います)、したがって 251 263 という名前のインタープリターを検索します .これは 274 の問題ではないことに注意してください。 コマンド自体、常に複数のパラメーターを渡すことができましたが、287 を呼び出す前にこの行を解析するシステムのシバンパーサーを使用していました .その間、これはほとんどのシステムで修正されていますが、スクリプトを非常に移植可能にしたい場合、実行するシステムでこれが修正されているとは限りません.

セキュリティに影響を与えることさえあります。 291 の場合 環境または 301 をクリーンアップするように構成されていませんでした クリーンアップから除外されました。これを実演してみましょう:

通常 313 325しかない、十分に保護された場所です そこで何でも変えることができます。ただし、ホームディレクトリはそうではありません。実行するプログラムは、ホームディレクトリに変更を加えることができます。つまり、悪意のあるコードが偽の 334 を配置する可能性があります 隠しディレクトリに移動し、349 を変更します そのディレクトリを 352 に含める 、したがって 366 を使用するすべてのスクリプト その偽の 370 で実行されることになります . 384 の場合 393 を保持 、あなたは大きな問題を抱えています。

例えば。ツールがファイル 401 を作成することを検討してください 次の内容で:

#!/bin/bash

if [ $EUID -eq 0 ]; then
  echo "All your base are belong to us..."
  # We are root - do whatever you want to do
fi

/bin/bash "[email protected]"

簡単なスクリプト 417 を作ってみましょう :

#!/usr/bin/env bash

echo "Hello World"

概念実証 (428 のシステム上) 438 を保持 ):

$ ./sample.sh
Hello World

$ sudo ./sample.sh
Hello World

$ export PATH="$HOME/.evil:$PATH"

$ ./sample.sh
Hello World

$ sudo ./sample.sh
All your base are belong to us...
Hello World

通常、クラシック シェルはすべて 448 に配置する必要があります。 何らかの理由でそれらをそこに配置したくない場合は、シンボリックリンクを 459 に配置しても問題ありません 実際の場所を指している (または 466 かもしれません) それ自体がシンボリック リンクです) ので、私は常に 475 を使用します。 と 486 .これらが機能しなくなると壊れてしまうものが多すぎます。 POSIX がこれらの位置を必要とするわけではありません (POSIX はパス名を標準化していないため、シバン機能をまったく標準化していません)。コード> 、おそらくまだ 505 を理解するでしょう それをどうするかを知っていて、既存のコードとの互換性のためだけかもしれません.

しかし、Perl、PHP、Python、Ruby などのより現代的で非標準のオプションのインタープリターの場合、それらがどこに配置されるべきかは実際にはどこにも指定されていません。 514 にある可能性があります しかし、それらは 528 にあるかもしれません または完全に異なる階層ブランチ (538549 など)。そのため、これらは 557 をよく使用します シバン構文。


562 の使用 $PATH 環境変数で NAME の最初の一致をシェルに検索させます。絶対パスがわからない場合や、絶対パスを検索したくない場合に役立ちます。


575 でコマンドを実行する プログラムのデフォルト バージョンが現在の env にあるものを探すという利点があります

この方法では、システムの特定の場所でパスを探す必要はありません。これらのパスは、異なるシステムの異なる場所にある可能性があるからです。あなたのパスにある限り、それを見つけます。

1 つの欠点は、複数の引数を渡すことができないことです (たとえば、 583 を書くことができなくなります)。 ) Linux をサポートしたい場合、POSIX は行がどのように解釈されるかについて曖昧であり、Linux は最初のスペースの後のすべてを単一の引数を示すために解釈します。 590 を使用できます 607 の一部のバージョン これを回避するには、スクリプトの移植性がさらに低下し、かなり最近のシステム (たとえば、Ubuntu 16.04 でさえ、それ以降ではない場合でも) で機能しなくなります。

もう 1 つの欠点は、明示的な実行可能ファイルを呼び出していないため、間違いが発生する可能性があり、マルチユーザー システムでセキュリティ上の問題が発生する可能性があることです (誰かが 617 という名前の実行可能ファイルを取得できた場合)。 たとえば、あなたのパスで)

#!/usr/bin/env bash #lends you some flexibility on different systems
#!/usr/bin/bash     #gives you explicit control on a given system of what executable is called

状況によっては、最初の方法が優先される場合があります (複数のバージョンの python で python スクリプトを実行し、実行可能行を作り直す必要がない場合など)。ただし、セキュリティが重視される状況では、コード インジェクションの可能性が制限されるため、後者が優先されます。


Linux
  1. Linuxは複数の連続したパスセパレーター(/ home //// username /// file)をどのように処理しますか?

  2. #の間にスペースは許可されていますか?そして/bin/ bash In Shebang?

  3. Bash =〜正規表現とHttps://regex101.com/?

  1. / sbin/nologinと/bin/ falseの違いは何ですか?

  2. Linux – / usr/binと/usr/sbinを/bin(gnu / linux)にマージしますか?

  3. バイナリを /bin、/sbin、/usr/bin、および /usr/sbin にインストールし、 --prefix および DESTDIR と対話します

  1. cmake --version は /usr/bin/cmake を指し、どの cmake は /usr/local/bin を指しますか

  2. /tmp と /run の違いは何ですか?

  3. /bin の内容を /usr/bin に移動しました。元に戻すことはできますか?