いくつかの場所で、次のシェバンラインを使用するようにというアドバイスを見ました。
#!/usr/bin/env bash
の代わりに
#!/usr/bin/bash
私の反射的な反応は、「誰かがこの実行ファイルを、たとえば自分のものと置き換えたらどうなるのか~/.local/bin
?」ということです。そのディレクトリは、システム全体のパスよりも前に、ユーザーのパス内に設定されることがよくあります。私は、これがセキュリティの問題として取り上げられるのを、真剣に受け止めるよりも、しばしば副次的な問題として見ていますが、私はその理論をテストしたいと思いました。
これを試すために、次のようなことをしました:
echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/bash
chmod 755 $HOME/.local/bin/bash
PATH=$HOME/.local/bin env bash
これにより
/usr/bin/env: ‘bash’: No such file or directory
何かが拾われているかどうかを確認するために、私はまた
echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/perl
chmod 755 $HOME/.local/bin/perl
PATH=$HOME/.local/bin env perl
予想通り、
Hacked!
代替品bash
が見つからないのに、代替品が存在する理由を誰か説明してもらえますかperl
? これは (私の観点からすると) 要点を外した、ある種の「セキュリティ」対策なのでしょうか?
編集: プロンプトが表示されたので、 が/usr/bin/env bash
を使用することとどう違うのかを尋ねているのではありません/bin/bash
。 上記のように質問しているのです。
編集2: 何か間違ったことをしていたに違いありません。今日もう一度試してみましたが (env
暗黙的パスではなく明示的パスを使用)、そのような「見つかりません」という動作はありませんでした。
答え1
「誰かが ~/.local/bin などでこの実行ファイルを自分のものと置き換えたらどうなるでしょうか?
そうすると、スクリプトは機能しなくなります。
しかし、他の方法でスクリプトを破壊したり、 や をいじらずに別のプログラムを直接実行したりできる可能性があるため、それは問題ではありませPATH
んenv
。
ユーザーが他のユーザーは自分の 内のユーザーのディレクトリを閲覧PATH
したり、他のユーザーの を編集したりできますがPATH
、あるユーザーが他のユーザーを混乱させる可能性はまったくありません。
しかし、もしそれがシェルスクリプトではなく、何らかのプログラムのsetuidラッパーのような追加の権限を付与するものであった場合、状況は異なります。その場合、必要絶対パスを使用してプログラムを実行し、権限のないユーザーが変更できないディレクトリに配置し、プログラムの起動時に環境をクリーンアップします。
答え2
シェルと の動作の違いについてはperl
、perl
シェルが最初の行を検査して何を実行するかを決定するのとは異なります。
$ cat tcl
#!/usr/bin/env tclsh
puts "TCL running as [pid]"
$ perl tcl
TCL running as 39689
$ cat sbcl
#!/opt/local/bin/sbcl --script
(format t "~a running as ~a~%" 'lisp (sb-unix:unix-getpid))
$ perl sbcl
LISP running as 39766
$
この機能の用途としては、Perl以外の言語でテストを書くそのため、他の言語で TAP 互換のスクリプトを作成でき、prove
それらを正しく実行できるようになります。
答え3
ここではセキュリティ上のリスクはありません。/usr/bin/env
は、ユーザーの環境に応じて適切なバイナリを選択するはずです。したがって、ユーザーがbash
に独自の をインストールした場合~/.local/bin
、 は/usr/bin/env
実際にそれを使用するように試みるべきです (たとえば、システム全体のバージョンでは利用できない追加機能を含むバージョンをコンパイルし、システム全体のバージョンの代わりにそれを使用することを好む場合があります)。他のバイナリ/インタープリタについても同様です。ユーザーは、いずれにしても実行できないものを実行することはできないため、セキュリティ上のリスクはありません。
あなたのケースで代替が失敗する理由については、 とは何の関係もないと思います。 、(スクリプトを実行するときに呼び出される)/usr/bin/env
および を実行して、どれが失敗するかを確認してください。これにより、「ファイルが見つかりません」というエラーが何を示しているかの手がかりが得られるはずです。PATH=~/.local/bin bash
PATH=~/.local/bin bash <path-to-script>
PATH=~/.local/bin /usr/bin/env bash