サンプルスクリプトがあります(クレジットは kos に移動します):
#!/bin/bash
cat <(cat /etc/lsb-release)
このスクリプトをホームディレクトリにsomename.shとして保存します。
次に、このファイルを3つの異なる方法で開こうとします。
sh somename.sh
bash somename.sh
./somename.sh
したがって、2つの質問があります。
同じスクリプトを実行しているにもかかわらず、上記のコマンドの出力が異なるのはなぜですか?
shは構文エラーを生成します
bashは望ましい結果を出力します
./Permission Deniedエラーが発生します
./を使用してスクリプトを実行する場合にのみスクリプトに実行許可を与える必要があり、他の場合には必要ないのはなぜですか?
前もって感謝します!
EDIT:最初の部分は duplicate リンクされた部分に似ているかもしれませんが、2番目の質問もありました。
チャットで説明したように:
インタプリタ(この場合はsh
)を直接呼び出すとシバンが無視され、スクリプトはsh
で実行されるため、sh script
はエラーを生成します。 sh
は、Bash-ismであるプロセス置換(<([...])
)をサポートしていないため、スクリプトはエラーで終了します。
bash script
はエラーを生成しません。Shebangは無視されますが、スクリプトはまだプロセス置換をサポートするBashで実行されているためです。
script
は実行可能でないため、./script
はエラーを生成します。
./
を使用してスクリプトを実行するには、mustにユーザーの実行ビットを設定する必要があります。これはOSの制約です。
したがって、実際の質問は次のとおりです。なぜbash script
がscript
のユーザーに実行ビットを設定する必要がないのですか?
これは、bash script
の実行時にスクリプトがBashによって読み取られ、Bashhasがユーザーに設定された実行ビットであるためです。
つまり、コードを実行する権限を持つBashは、そのスクリプトに対するOSの制約を「バイパス」でき、スクリプトに必要なものはすべてBashで読み取り可能になるということです。
sh
はdash
Shellへのシンボリックリンクであり、sh
構文には<( . . .)
がないため、構文エラーが生成されます。それはbashにのみあります(正しく覚えていればzsh
とksh
にあります)。
bashは正しいbash構文であるため、目的の結果を出力します。
./は、基本的に「おい、シェル、そのファイルのパーミッションを見て、私の現在のディレクトリの最初の行(#!/bin/bash
が付いているもの)を見て、このスクリプトを実行する方法を見つけてください」。 (サイドノート:$PATH
変数に含まれる場所にスクリプトがある場合は、myScriptName.sh
を実行するだけです。それでも同じです。考えは同じです。execを確認する必要があります。許可と使用するインタープリター)
bash
およびdash
を実行して、ファイルからコマンドを読み取るように指示する前。 bash
とdash
は、スクリプトではなく今回実行可能です。スクリプトは現在、コマンドのソース、パラメーターです。読み取り権限は常にすべてのユーザーに設定されているため、シェルはそれを読み取ります。
一般的にsh
、ash
、dash
、bash
、csh
、tcsh
、zsh
...はすべてシェルです。独自の構文と特性。いくつかの互換性がありますが、それらはorientedです [ 1 ]:bash
シェルはsh
スクリプトを実行しますが、viceversaとは言われていません。 sh
の呼び出しは、bash
の呼び出しよりも少ないリソースで済みます。単一のインスタンスでは問題になりませんが、数千では問題になります。
実行方法。
Linuxでファイルをプログラムとして実行するには、スクリプトまたはコンパイルされたファイルの両方である場合、execute bitを設定する必要があります。 [ 2 ] また、$PATH
のいずれかのディレクトリに含める必要があります。
スクリプトの場合、相対シェルに引数として渡すことができます(sh
、bash
...myfile.whatever
):間違ったシェルに渡される場合正しくない動作を取得し、エラーがラッキーだった場合;この場合は実行可能である必要はありませんスクリプト内に直接記述された行を記述する場合と同じように新しいシェルで呼び出します。同じシェルで代わりに実行するには、現在のシェルで行ごとにを記述するのと同等のsource myfile
または. myfile
を使用できますスクリプトのコンテンツ。
場所
実行可能プログラムがパスに含まれていない場合は、それがどこにあるかを指定する必要があります。
./
はシェルの現在のディレクトリのみを意味します。また、~/myfile.whatever
はホームのmyfile.whatever
ディレクトリにあるファイル~/
を指定する必要があります。/home/$USER/dir/myfile.whatever
などを使用して、別の場所から呼び出すことができます。myfile.whatever
で呼び出すことができます。複数の実行可能ファイルが同じ名前を共有している場合、フルパスを指定すると、実行する実行可能ファイルについて確実になります。 which mycommand
は、現在実行されているもの(関数、エイリアス、組み込み、またはパスで最初に検出されたもの)を通知できますが、将来実行されるか、または別のユーザーから実行されるかはわかりません。完全なパスを明示的に記述した場合、このあいまいさは修正されます。特定のバージョンのプログラムを同時に複数インストールした場合に実行し、トロイの木馬を回避すると便利です。スクリプトでは、bash
の代わりに_/bin/bash
を記述することが常に推奨されます。