Linuxでは、シバンはあまり柔軟ではありません。複数の回答(Stephen Kittの回答およびJörgW Mittag の回答)によると、シバン行で複数の引数を渡す指定された方法はありません。
誰に役立つかはわかりませんが、不足している機能を実装するための短いスクリプトを作成しました。https://gist.github.com/loxaxs/7cbe84aed1c38cf18f70d8427bed1efaを参照してください。
埋め込まれた回避策を記述することもできます。以下に、同じテストスクリプトに適用される4つの言語に依存しない回避策と、それぞれが出力する結果を示します。スクリプトは実行可能で、にあると思います/tmp/shebang
。
プロセス置換内のbash heredocでのスクリプトのラップ
私の知る限り、これは最も信頼できる言語に依存しない方法です。引数を渡すことができ、標準入力を保持します。欠点は、インタープリターが読み取るファイルの(実際の)場所を知らないことです。
#!/bin/bash
exec python3 -O <(cat << 'EOWRAPPER'
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
) "$@"
echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
プリントの呼び出し:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /dev/fd/62
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\\ uses\\ \\\\escapes\\\\']
__debug__ :: False
PYTHON_SCRIPT_END
プロセス置換により特別なファイルが生成されることに注意してください。これは、すべての実行可能ファイルに適合するとは限りません。たとえば、#!/usr/bin/less
文句を言う:/dev/fd/63 is not a regular file (use -f to see it)
ダッシュのプロセス置換内にヒアドキュメントを含めることが可能かどうかはわかりません。
単純なヒアドキュメントでスクリプトをラップする
短くてシンプルですがstdin
、スクリプトからアクセスできず、インタープリターがからスクリプトを読み取って実行できる必要がありますstdin
。
#!/bin/sh
exec python3 - "$@" << 'EOWRAPPER'
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
プリントの呼び出し:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\\ uses\\ \\\\escapes\\\\']
__debug__ :: True
PYTHON_SCRIPT_END
system()
引数なしでawk 呼び出しを使用する
実行されたファイルの名前を正しく渡しますが、スクリプトは指定した引数を受け取りません。awkは私が知っている唯一の言語であり、どちらのインタプリタもデフォルトでLinuxにインストールされ、デフォルトでコマンドラインからその命令を読み取ることに注意してください。
#!/usr/bin/gawk BEGIN {system("python3 -O " ARGV[1])}
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
プリントの呼び出し:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: []
__debug__ :: False
PYTHON_SCRIPT_END
system()
引数にスペースが含まれていない場合は、awk 4.1+ 呼び出しを使用します
すてきですが、スペースを含む引数でスクリプトが呼び出されないことが確実な場合のみです。ご覧のとおり、スペースをエスケープしない限り、スペースを含む引数は分割されます。
#!/usr/bin/gawk @include "join"; BEGIN {system("python3 -O " join(ARGV, 1, ARGC, " "))}
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
プリントの呼び出し:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: ['arg1', 'arg2', 'contains', 'spaces', 'arg3 uses \\escapes\\']
__debug__ :: False
PYTHON_SCRIPT_END
4.1より前のawkバージョンでは、forループ内で文字列連結を使用する必要があります。関数の例https://www.gnu.org/software/gawk/manual/html_node/Join-Function.htmlを参照してください。