web-dev-qa-db-ja.com

なぜ#!/ usr / bin / env bashが#!/ bin / bashより優れているのですか?

#!/usr/bin/env bashに優先して#!/bin/bashを使用するために、このサイトの推奨事項( 推奨Bashシバンとは? )を含め、多くの場所で見ました。私は1人の進取の気性に富んだ個人さえ見ました #!/bin/bashを使用する提案はwrong であり、bash機能はそう。

とはいえ、私はbashを厳密に制御されたテスト環境で使用しています。この環境では、流通しているすべてのドライブが本質的に単一のマスタードライブのクローンです。私は移植性の議論を理解していますが、私の場合は必ずしも当てはまりません。代替よりも#!/usr/bin/env bashを好む他の理由はありますか。移植性が懸念されると仮定して、それを使用すると機能が損なわれる可能性がありますか?

170
spugm1r3

#!/usr/bin/envPATHbashを検索しますが、bashは常に/binにあるとは限りません。特にLinux以外のシステムではそうです。たとえば、私のOpenBSDシステムでは、オプションパッケージとしてインストールされているため、/usr/local/binにあります。

bash/binにあり、常にそうであると確信している場合、Shebangに直接配置しても害はありません。しかし、スクリプトとプログラムはすべて私たちの生活を超えているのでお勧めしません最初は彼らが持っていると信じています。

192
zigg

Bashの標準の場所は/binであり、すべてのシステムに当てはまると思います。ただし、そのバージョンのbashが気に入らない場合はどうでしょうか?たとえば、bash 4.2を使用したいのですが、Macのbashは3.2.5です。

/binにbashを再インストールすることもできますが、それは悪い考えかもしれません。 OSを更新すると、上書きされます。

ただし、bashを/usr/local/bin/bashにインストールし、PATHを次のように設定できます。

PATH="/usr/local/bin:/bin:/usr/bin:$HOME/bin"

bashを指定した場合、/bin/bashで古い汚いものを取得するのではなく、/usr/local/binで新しい、より光沢のあるものを取得します。いいね!

私のシェルスクリプトには!# /bin/bash Shebangがあります。したがって、シェルスクリプトを実行すると、連想配列さえ持たないbashの古くてひどいバージョンになります。

/usr/bin/env bashを使用すると、私のPATHにあるバージョンのbashが使用されます。 /usr/local/bin/bashが実行されるようにPATHをセットアップすると、それがスクリプトで使用されるbashになります。

これをbashで見ることはめったにありませんが、PerlとPythonではもっと一般的です:

  • 安定性に焦点を当てた特定のUnix/Linuxリリースは、これら2つのスクリプト言語のリリースに遅れをとることがあります。少し前まで、RHELのPerlは5.8.8でした-Perlの8年前のバージョンです!誰かが最新の機能を使用したい場合は、独自のバージョンをインストールする必要がありました。
  • PerlbrewやPythonbrewなどのプログラムを使用すると、これらの言語の複数のバージョンをインストールできます。これらは、必要なバージョンを取得するためにPATHを操作するスクリプトに依存しています。パスをハードコーディングすると、スクリプトをbrewで実行できなくなります。
  • PerlとPythonがほとんどのUnixシステムに含まれる標準パッケージではなかったことは、それほど昔ではありませんでした(そう、かなり前です)。つまり、これらの2つのプログラムがどこにインストールされているかわからなかったということです。 /binの下にありましたか? /usr/bin/opt/bin?知るか? #! /usr/bin/env Perlを使用すると、知る必要がありませんでした。

そして、なぜ#! /usr/bin/env bashを使用すべきではないのか

Shebangでパスがハードコーディングされている場合、そのインタープリターで実行する必要があります。したがって、#! /bin/bashは、デフォルトでインストールされたbashの使用を強制します。 bash機能は非常に安定しているので(Python 3.xの下で2.xバージョンのPythonスクリプトを実行してみてください)、特定のBASHスクリプトが機能しないことはほとんどありません。私のbashスクリプトはおそらくこのシステムと他のシステムで使用されていますが、非標準バージョンのbashを使用すると望ましくない効果が生じる可能性があります。シェルスクリプトでbashの安定した標準バージョンが使用されていることを確認したい可能性が非常に高いです。したがって、おそらくシバンにパスをハードコーディングしたいと思います。

30
David W.

bashを呼び出すためには、少しやり過ぎです。 〜/ binに独自のbashバイナリが複数ある場合を除きますが、これは、コードに適切なものが含まれている$ PATHに依存することも意味します。

pythonのようなものにも便利です。代替のpythonバイナリが使用されるラッパースクリプトと環境があります。

ただし、本当に必要なバイナリであることが確実な限り、バイナリへの正確なパスを使用しても何も失われません。

11
Sean Perry

ほんの数例を挙げると、/bin、FreeBSD、OpenBSDにBashを持たないシステムはたくさんあります。スクリプトが多くの異なるUnicesに移植できるようになっている場合は、#!/usr/bin/env bashの代わりに#!/bin/bashを使用できます。

これはshには当てはまらないことに注意してください。 Bourne準拠のスクリプトの場合は、#!/bin/shのみを使用します。これは、ほとんどすべてのUnixが/binshを持っていると思うからです。

10
James Ko
 #!/usr/bin/env bash

システム環境変数からbash実行可能パスを見つけるため、間違いなく優れています。

Linuxシェルに移動して入力します

env

すべての環境変数が出力されます。

シェルスクリプトに移動して入力します

echo $bash.

スクリプトで正しいシェバンパスを構築するために使用する必要があるbashパス(環境変数リストによる)を出力します。

0
kta