何というぞ!Shebangは本当に


ファイルを起動したときに何が起こるのか#! ( aka Shebang )、なぜ何人かの人々が使う#!/usr/bin/env bash .

ハウツー#! 作品
The #! Shebangはファイルに存在するコマンドを実行するためにインタプリタを使用するカーネルを伝えるために使われます.
ファイルを起動すると#! , カーネルはファイルを開き、#! 行の最後まで.教訓的な目的のために、それはcommand 文字列の後に始まる文字列.
この後、カーネルはcommand 最初の引数として、実行しようとしているファイルのファイル名を指定します.
したがって、実行可能ファイルがmyscript.sh シェルコマンドと#!/bin/bash , 実行するとカーネルが実行されます/bin/bash myscript.sh .
下記の例では、あなたはそれを非常にはっきりと見るつもりです.
古典から始まるhello.sh :
#!/bin/bash
echo "Hello World!"
このファイルが実行許可を持っていると仮定します.
$ ./hello.sh
カーネルは#! 非常に最初の行では、その後、このケースでは、何かを取得します/bin/bash . そして、実行されることには、以下のような効果があります.
$ /bin/bash hello.sh
別の例を使いましょう#!/bin/cat . ファイルの名前はshebangcat :
#!/bin/cat
All the contents of this file will be
printed in the screen when it's executed
(including the '#!/bin/cat' in the first line).
思い出しましょう
  • Shebangの後に何がありますか/bin/cat
  • ファイル名./shebangcat
  • したがって、これは実行されます./bin/cat ./shebangcat自分で見る
    $ ./shebangcat
    #!/bin/cat
    All the contents of this file will be
    printed in the screen when it's executed
    (including the '#!/bin/cat' in the first line).
    
    別の例を見て、物事が私が言っているようなものであることをはっきりさせましょう.以下のファイルをshebangecho :
    #!/usr/bin/echo
    The contents of this file will *NOT* be
    printed when it's executed.
    
    チェックしましょう
    $ ./shebangecho
    ./shebangecho
    
    出力は、カーネルによって実行されたものであるので、ファイルの名前でした/usr/bin/echo ./shebangecho .
    別の興味深いことは、スクリプトを呼び出すときに引数を渡すと、そのような引数もカーネルが実行するコマンドに渡されることです.以下の例でご覧ください.shebangls.sh :
    #!/bin/ls
    The contents here doesn't matter.
    
    さて、実行するとき:
    $ ./shebangls.sh
    ./shebangls.sh
    
    $ ./shebangls.sh -l
    -rwxr-xr-x 1 meleu meleu 41 Nov 28 14:42 ./shebangls.sh
    
    $ ./shebangls.sh notfound
    /bin/ls: cannot access 'notfound': No such file or directory
    ./shebangls.sh
    

    なぜ一部の人々を使用#!/usr/bin/env ?
    あなたはおそらく#!/usr/bin/env bash あなたがちょうど見に慣れているところ#!/bin/bash . この理由は、スクリプトの移植性を向上させることです(後述するように、それが問題になると考えても).
    The env コマンドは引数なしで使用される場合、すべての環境変数を使って大きなリストを出力します.でもenv を使用してコマンドを実行し、シェルの別のインスタンスでそのコマンドを実行します.
    🤔 - が、どのように移植性に影響を与えるのですか?
    あなたが使うとき#!/bin/bash あなたは明らかにbash が存在する/bin/ ディレクトリ.これはすべてのLinuxディストリビューションではデフォルトのようですが、他のUnixフレーバーがあります.bash に設定することができます/usr/bin/ ). そのようなシステムでは#!/bin/bash を引き起こすbad interpreter: No such file or directory .
    あなたが走るときenv bash , the env を検索するbash あなたの$PATH 変数を指定し、最初に見つかったものを実行します.通常bash である/bin/ , しかし、他のシステムでスクリプトを実行しているユーザは/usr/bin/ または別のバージョンでもテスト/home/user/bin/bash .
    それで、スクリプトをより多くの手に入れて、Linux以外の環境で使用されるようにするために、一部の人々はenv テクニック.
    🤔 - でも待って!何が保証するenv は常に/usr/bin/ ?
    保証はない.😇
    再構成はUnixシステムで一般的に見られるものに基づいている.なるほど/usr/bin/env いくつかの現代的なプロジェクトで使用されるRetroPie ), しかし、それが特に役に立つとき、あなたはPythonかnodejsスクリプトさえ走らせる必要があるときです.
    例としてこのnodejs使用をしましょう.スクリプトのファイル名を呼び出すだけでnodejsスクリプトを呼び出します.そのようなことができました.
    #!/usr/bin/node
    console.log('Hello World from NodeJS');
    
    問題は、通常、Node Version Manager , 配布パッケージのマネージャを使用する代わりに.だから、私node 以下のようになります.
    $ which node
    /home/meleu/.nvm/versions/node/v14.15.1/bin/node
    
    どうしても私は入れたい#!/home/meleu/.nvm/versions/node/v14.15.1/bin/node 私のスクリプトで!
    そこで、ここでの解決策は#!/usr/bin/env node .

    そして、私が使用したくないならば#! まったく?
    私は、あなたなしでシェルスクリプトを走らせないことを強く推薦します#! シバ!
    私たちが言ったように、Shebangはファイルに存在するコマンドを実行するためにインタプリタが使用されるカーネルに伝えます.インタプリタを指定せずにスクリプトを実行すると、シェルは自分自身の別のインスタンスを生成し、スクリプト内のコマンドを実行します.これは、zsh、ksh、dash、fish、node、python、あるいは何のためにも書かれていても、ファイル内で見つかったコマンドを実行することを意味します.
    要約:常にあなたのスクリプトを#! シバ好ましくは#!/usr/bin/env .

    リンク
  • http://mywiki.wooledge.org/BashProgramming#Shebang
  • https://wiki.bash-hackers.org/scripting/basics#the_shebang

  • Here's an email from Dennis Ritchie 1980年に、これらの「魔法の性格」について話してください.
  • man env
  • Node.js shebang