web-dev-qa-db-ja.com

Shebangラインに従ってスクリプトを実行するコマンドはありますか?

実行許可が設定されていないbashスクリプトを実行する場合、次の操作を実行できます。

bash script.sh

スクリプトが実行可能でなく、正しいインタープリターがわからない場合、bashの代わりに何を使用する必要がありますか? Shebang行からインタープリターを検索し、それを使用してスクリプトを実行するコマンドはありますか?

45
Aivar

うん。 Perlと呼ばれます:

Perl foo.bash    # works
Perl foo.lua     # works
Perl foo.clisp   # works
Perl foo.csh     # works
Perl foo.php     # works
Perl foo.gnuplot # works (no arguments)
Perl foo.pl      # works (obviously)
Perl foo.py      # works
Perl foo.sh      # works
Perl foo.tcl     # works
Perl foo.rb      # works
Perl foo.nodejs  # works
Perl foo.r       # works
Perl foo.oct     # works
Perl foo.csharp  # works (no arguments)

これは Perlのドキュメント で言及されています:

#!行にWord "Perl"もWord "indir"も含まれていない場合、Perlインタープリターの代わりに#!にちなんで名付けられたプログラムが実行されます。これは少し奇妙ですが、#!を実行していないマシンのユーザーを助けます。シェルが/ usr/bin/Perlであることをプログラムに伝えることができ、Perlがプログラムを正しいインタープリターにディスパッチするからです彼らのために。

66
Ole Tange

スクリプトには必ずしもシバンがありません

スクリプトがインタープリターから実行された場合、シバンがすべてであることを確認できません。 スクリプト、インタープリターから実行する場合、Shebangifインタープリターを呼び出してコードを実行します。

したがって、答えは「いいえ」です。スクリプトを実行する言語(インタープリター)を確実に確認するコマンドはありません。ただし、スクリプトの内部をいつでも確認して、それが調べるべきシバンがあるかどうかを確認できます。

要するにルール:

  1. スクリプトを実行するときに、インタープリターalwaysを呼び出すと、実行可能なシバン、シバンまたはシバンの可能性を無効にします。
  2. 実行可能でなく、インタープリターからfromを実行する場合、スクリプトにはShebangは不要です。
  3. 最初にインタープリターを呼び出さずにスクリプトを実行すると、needs(および使用)Shebangを呼び出してどのインタープリターを呼び出すかを見つけますandインターバンターをシバンから呼び出す「許可」を得るには、実行可能である必要があります。

ただし、スクリプトにシバンがない場合は、使用するインタープリターを指示する(直接*)情報がスクリプト内にありません。

そうは言っても

もちろん、常にtryにラッパースクリプトを記述して、スクリプトにシバンが含まれているかどうかを確認し、そこからインタープリターを読み取って、その後、通訳が見つかりました。

#!/usr/bin/env python3
import subprocess
import sys

args = sys.argv[1:]; script = args[0]

try:
    lang = open(script).readlines()[0].replace("#!", "").strip().split()[-1]
    cmd = [lang, script]+args[1:]
    subprocess.call(cmd)
except (PermissionError, FileNotFoundError, IndexError):
    print("No valid Shebang found")
  • $PATHtryrunとして保存します(例:~/bin、存在しない場合はディレクトリを作成し、ログアウトしてからログインし直します)executable。次に実行:

    tryrun /path/to/nonexecutablescript
    

    実行可能でないpythonおよびbashスクリプトで正しいインタープリターを呼び出します(テスト済み)。

説明

  • スクリプトは、スクリプトの最初の行を読み取り、#!を削除し、残りを使用してインタープリターを呼び出します。
  • 有効なインタープリターの呼び出しに失敗すると、PermissionErrorまたはFileNotFoundErrorのいずれかが発生します。

注意

拡張機能(.sh.pyなど)は、Linuxで適切なインタープリターを決定する際に何の役割も果たしません。


(*「スマート」推測アルゴリズムを開発して、コードから構文を決定することはもちろん可能です。)

25
Jacob Vlijm

次のようなスクリプトでこれを実現できます。

#!/bin/bash

copy=/tmp/runner.$$
cp $1 ${copy}
chmod u+x ${copy}
${copy}
rm ${copy}

副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example:

$ echo "echo hello" > myscript
$ ./myscript
bash: ./myscript: Permission denied
$ ./runscript myscript 
hello

これをしないことをお勧めします。許可には理由があります。これは、権限を破壊するためのプログラムです。

Shebangの処理はkernel関数(Linuxソースコード- fs/binfmt_script.c )であることに注意してください。基本的に、スクリプトを直接呼び出すプロセスは#!を認識しません-カーネルはそれを使用してインタープリターを起動する必要があることを判断します。

6
slim