Di Linux, shebang tidak terlalu fleksibel; menurut beberapa jawaban (jawaban Stephen Kitt dan Jörg W Mittag ), tidak ada cara yang ditentukan untuk melewati beberapa argumen dalam garis shebang.
Saya tidak yakin apakah ini akan berguna bagi siapa pun, tetapi saya telah menulis skrip pendek untuk mengimplementasikan fitur yang kurang. Lihat https://gist.github.com/loxaxs/7cbe84aed1c38cf18f70d8427bed1efa .
Dimungkinkan juga untuk menulis solusi yang disematkan. Di bawah, saya sajikan empat solusi bahasa-agnostik yang diterapkan pada skrip uji yang sama dan hasil masing-masing dicetak. Saya kira bahwa script adalah dieksekusi dan di /tmp/shebang
.
Membungkus skrip Anda di bash heredoc di dalam subtitusi proses
Sejauh yang saya tahu, ini adalah cara agnostik bahasa yang paling dapat diandalkan untuk melakukannya. Ini memungkinkan lewat argumen dan mempertahankan stdin. Kekurangannya adalah bahwa penerjemah tidak mengetahui lokasi (sebenarnya) dari file yang dibacanya.
#!/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
) "$@"
Memanggil echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
cetakan:
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
Perhatikan bahwa substitusi proses menghasilkan file khusus. Ini mungkin tidak sesuai dengan semua yang dapat dieksekusi. Misalnya, #!/usr/bin/less
mengeluh:/dev/fd/63 is not a regular file (use -f to see it)
Saya tidak tahu apakah mungkin untuk memiliki heredoc di dalam proses substitusi di dash.
Membungkus naskah Anda dalam heredoc sederhana
Lebih pendek dan sederhana, tetapi Anda tidak akan dapat mengakses stdin
dari skrip Anda dan itu membutuhkan penerjemah untuk dapat membaca dan menjalankan skrip dari 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
Memanggil echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
cetakan:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\\ uses\\ \\\\escapes\\\\']
__debug__ :: True
PYTHON_SCRIPT_END
Gunakan system()
panggilan awk tetapi tanpa argumen
Benar melewati nama file yang dieksekusi, tetapi skrip Anda tidak akan menerima argumen yang Anda berikan. Perhatikan bahwa awk adalah satu-satunya bahasa yang saya tahu yang interpreter keduanya diinstal di linux secara default dan membaca instruksinya dari baris perintah secara default.
#!/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")
Memanggil echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
cetakan:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: []
__debug__ :: False
PYTHON_SCRIPT_END
Gunakan system()
panggilan 4.1+ awk , asalkan argumen Anda tidak mengandung spasi
Bagus, tetapi hanya jika Anda yakin skrip Anda tidak akan dipanggil dengan argumen yang berisi spasi. Seperti yang dapat Anda lihat, argumen Anda yang berisi spasi akan dipisah, kecuali spasi tersebut lolos.
#!/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")
Memanggil echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
cetakan:
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
Untuk versi awk di bawah 4.1, Anda harus menggunakan penggabungan string di dalam for for, lihat contoh fungsi https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .