私のshebangとして「#!/path/to/NAME」の代わりに「#!/usr/bin/env NAME」を使用する方が良いのはなぜですか?

私のshebangとして「#!/path/to/NAME」の代わりに「#!/usr/bin/env NAME」を使用する方が良いのはなぜですか?

#!/path/to/NAME私は他の人から得たいくつかのスクリプトにshebangsがあり、他のスクリプト(同じツールNAMEを使用)にはshebangsがあることがわかりました#!/usr/bin/env NAME

どちらもうまくいくようです。チュートリアル(Pythonチュートリアルなど)では、後者がより良いと提案されているようです。しかし、なぜこれが起こるのかよく理解していません。

後者のshebangを使用するには、NAMEがPATHになければなりませんが、最初のshebangにはこの制限がないことに気づきました。

また、(私にとっては)最初のものがNAMEの場所を正確に指定するので、より良いShebangのようです。したがって、この場合、NAMEの複数のバージョン(例:/usr/bin/NAME、/usr/local/bin/NAME)がある場合、最初のケースでは使用されるバージョンを指定します。

私の質問は、最初のshebangが2番目のshebangよりも優れている理由は何ですか?

ベストアンサー1

これは必ずしも良いわけではありません。

利点#!/usr/bin/env pythonは、pythonユーザーの$PATH

これダメージその#!/usr/bin/env python理由は、pythonユーザーの$PATH

これは、スクリプトを実行している人によってスクリプトが異なる動作をする可能性があることを意味します。ユーザーの場合は、/usr/bin/pythonオペレーティングシステムと一緒にインストールされているものを使用できます。一方、うまく/home/phred/bin/python機能しない実験を使用することもできます。

pythonのみインストールされている場合、/usr/local/binin/usr/local/binを持たないユーザーは$PATHスクリプトを実行することもできません。 (これは最新のシステムでは不可能かもしれませんが、より曖昧なソルバーでは簡単に発生する可能性があります。)

指定すると、#!/usr/bin/pythonスクリプトの実行に使用するインタプリタを正確に指定できます。特定のシステムで

もう一つの潜在的な問題はこの#!/usr/bin/envトリックです。インタプリタに引数を渡すことはできません。(暗黙的に渡されたスクリプト名を除く)通常問題ではありませんが、問題かもしれません。多くのPerlスクリプトがで書かれていますが、#!/usr/bin/perl -w今ではuse warnings;代わりにお勧めします。 Cshスクリプトは -- を使用する必要が#!/bin/csh -fありますが、cshスクリプトは推奨しない最初。ただし、他の例があるかもしれません。

新しいシステムにアカウントを設定するときに、パーソナルソース管理システムに複数のPerlスクリプトをインストールしました。私は各スクリプトを#!$HOME/bin#!/usr/bin/perl

小さな点:この#!/usr/bin/envトリックはコマンドの誤用と呼ばれることがありますenv。元の目的は、(名前が示すように)変更された環境でコマンドを呼び出すことです。また、一部の古いシステム(私の記憶が正しい場合はSunOS 4を含む)はおそらく深刻な問題ではありません env。このように動作し、多くのスクリプトがこのトリックを使用し、オペレーティングシステムプロバイダがこれを破るために何もしません。それ/usr/binenv#!/usr/bin/env可能非常に古いシステムでスクリプトを実行するのは問題ですが、とにかくスクリプトを変更する必要があるかもしれません。

別の考えられる問題(コメントで指摘したSopalajo de Arrierezに感謝します)は、cronジョブが限られた環境で実行されていることです。特に、一般的$PATH/usr/bin:/bin。正確なパスを指定するか、crontabに行を追加することで設定できます(詳細)。$PATH/usr/bin/env$PATHman 5 crontab

KevinのコメントはPythonvirtualenv$PATH。 (私はvirtualenvを直接使用したことがありません。)#!/usr/bin/env pythonpython3

おすすめ記事