web-dev-qa-db-ja.com

スクリプトを実行するための./とshの違いは何ですか?

簡単なスクリプトを書きました。 sh <myscriptname.sh>を実行すると正しい出力が得られましたが、./<myscriptname.sh>を実行するとエラーが発生しました。

sh./を実行するときの違いは何ですか?

70
mr_eclair

ファイル名をスクリプトインタープリタープログラムに渡してスクリプトを実行すると、スクリプトを引数として渡してインタープリタープログラムを実行します。たとえば、これは引数 'filename.sh'を持つプロセス 'sh'のように見えます。 shインタープリターがファイルを開いています。

一方、スクリプト自体を実行する場合、システムは指定されたインタープリタープログラムを呼び出し、スクリプトの内容をフィードします。この場合、プロセスは引数なしの「filename.sh」のように見えます。

強打線があることを確認する必要があります。

#!/bin/bash
# bash script here

バング行は、スクリプト内の非常に最初の行であり、同じ2文字#!で始まります。これらは、システムがスクリプトを実行しようとし、システムが渡すときに読み取るものです直後のプログラムへのスクリプト。この行はbashとは関係がなく、pythonとPerlでも非常に異なる言語ですが、同様に機能することに注意してください。たとえば#!/usr/bin/pythonを使用し、その後にpythonコードを続けます。

スクリプトを作成したら、実行権限を設定していることを確認してください。

chmod a+x filename.sh

その後、スクリプトを独自のプロセスとして実行できます。

./filename.sh

または、/usr/sbinなどの素敵なプログラム名を持つ既知の場所にファイルを置き、どこからでも実行します。

Sudo cp filename.sh /usr/sbin/program-name
program-name

そして、これは本当に実用的適切な権限でbang行を使用する利点です-それはすべてdeploymentについてです。スクリプトを実行するプログラムを覚えておく必要がある場合、ユーザーにスクリプトを実行させるのは非常に困難です。スクリプトを実行するたびに、スクリプトへの完全なパスを忘れずに指定してください。たとえば/usr/local/binに配置して実行可能にすることで、スクリプトを使用しようとする人々の悲しみを大幅に節約できます。これらのプログラムは、コンピューター上のallユーザーが利用できるようになります。

識別にも適しています。 topプログラムにアクセスすると、bang行なしで実行されるスクリプトには、インタープリターの名前(つまり、bashPerl、またはpython)のみが付きます。ただし、適切な権限でスクリプトを実行すると、スクリプトの名前が表示されます。

注:誰でもアクセスできるスクリプトを配布する場合は、manページとdebパッケージを作成してインストールしてください。オンラインでのランダムスクリプトの数を減らし、アンインストールできるデバッグの数を増やす必要があります。

ショートバージョン:

  • shはコマンドラインインタープリター(ダッシュ)です。
    _sh my_scriptを実行すると、ダッシュがスクリプトを解釈します。

  • ./は、最初の行を見て、使用するインタープリターを見つけようとします。例えば。 #!/bin/bash、または#!/bin/RubyRuby my_scriptの実行とは異なります)。

41
Stefano Palazzo

あなたがする違いは、

  • shを使用すると、ターミナルの対話型プロンプトで入力したのと同じようにスクリプトの行を解釈するプログラムを実行しています。

  • ./を使用すると、スクリプトが現在のディレクトリのちょうどここにあり、実行可能(たとえば、chmod +x myscript.shを発行したため)であると仮定してショートカットを作成し、貴重なデータを保存します未来の時間:-)

5
meduz

エラーが発生する主な理由は3つあります。

  • ファイルは実行可能ではありません
    chmod +x <myscriptname.sh>を実行して修正します
  • パーティションはスクリプトの実行を許可しません(「noexec」にマウントされます)
    スクリプトを/usr/local/binにコピーします
  • #!行にエラーがあります
    最初の行が#!/bin/shまたは#!/bin/bashであることを確認してください

最初の行が正しく見えても動作しない場合は、ファイルにDOS行末記号がないことを確認してください。

エラーは次のようになります。

$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory

dos2unix <myscriptname.sh>を実行することで修正できます。または、お持ちでない場合は、
Perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>

3
Mikel

答えは、shは非常に人気のあるシェルの名前だということです。しかし、時代遅れで、他のものに置き換えられました。現在、shはマシンにインストールされている他のシェルにリンクされています。例えば私はそこにパッシュを入れました。 shからシェルを実行すると、通常、元の「シェル」動作との「互換性」モードがトリガーされます。

したがって、解決策は非常に簡単です。 shコマンドの背後にあるもの(ls -al/bin/sh)を見て、#!/ bin/whatever_you_find_thereを最初の行に追加します(またはスクリプトにそのようなものがある場合は編集します)。

または、スクリプト自体にバグがある可能性があります。 shが満たす依存関係と同様ですが、実際に使用されるインタープリターはそうではありません。

0
przemo_li
mkdir ~/bin ; cp myscript.sh ~/bin/

echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ; 

/usr/sbinではなく、それは必須ではない管理ツール用です。/usr/local/binは、~/bin/を使いたくない場合に適していますが、Sudoをできるだけ避けることをお勧めします。

0
Joey1978