Trên Linux, shebang không linh hoạt; theo nhiều câu trả lời (câu trả lời của Stephen Kitt và Jörg W Mittag's ), không có cách nào được chỉ định để vượt qua nhiều đối số trong một dòng shebang.
Tôi không chắc liệu nó có được sử dụng cho bất kỳ ai không, nhưng tôi đã viết một đoạn script ngắn để thực hiện tính năng thiếu. Xem https://gist.github.com/loxaxs/7cbe84aed1c38cf18f70d8427bed1efa .
Cũng có thể viết cách giải quyết nhúng. Dưới đây, tôi trình bày bốn cách giải quyết ngôn ngữ không thể áp dụng cho cùng một kịch bản kiểm tra và kết quả mỗi bản in. Tôi cho rằng kịch bản có thể thực thi được và nằm trong /tmp/shebang
.
Gói kịch bản của bạn trong một bash heredoc bên trong quá trình thay thế
Theo như tôi biết, đây là cách làm ngôn ngữ đáng tin cậy nhất. Nó cho phép vượt qua các đối số và bảo tồn stdin. Hạn chế là trình thông dịch không biết vị trí (thực) của tệp mà nó đọc.
#!/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
) "$@"
Gọi echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
in:
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
Lưu ý rằng quá trình thay thế tạo ra một tập tin đặc biệt. Điều này có thể không phù hợp với tất cả các thực thi. Chẳng hạn, #!/usr/bin/less
phàn nàn:/dev/fd/63 is not a regular file (use -f to see it)
Tôi không biết nếu có thể có di truyền trong quá trình thay thế trong dấu gạch ngang.
Gói kịch bản của bạn trong một di sản đơn giản
Ngắn hơn và đơn giản hơn, nhưng bạn sẽ không thể truy cập stdin
từ tập lệnh của mình và nó yêu cầu trình thông dịch có thể đọc và thực thi tập lệnh từ đó 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
Gọi echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
in:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\\ uses\\ \\\\escapes\\\\']
__debug__ :: True
PYTHON_SCRIPT_END
Sử dụng system()
cuộc gọi awk nhưng không có đối số
Chuyển chính xác tên của tệp được thực thi, nhưng tập lệnh của bạn sẽ không nhận được các đối số bạn đưa ra. Lưu ý rằng awk là ngôn ngữ duy nhất tôi biết có cả hai trình thông dịch được cài đặt trên linux theo mặc định và đọc các hướng dẫn của nó từ dòng lệnh theo mặc định.
#!/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")
Gọi echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
in:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: []
__debug__ :: False
PYTHON_SCRIPT_END
Sử dụng system()
cuộc gọi awk 4.1+ , miễn là các đối số của bạn không chứa khoảng trắng
Đẹp, nhưng chỉ khi bạn chắc chắn rằng tập lệnh của bạn sẽ không được gọi với các đối số có chứa khoảng trắng. Như bạn có thể thấy, các đối số của bạn chứa khoảng trắng sẽ được phân tách, trừ khi các khoảng trắng được thoát.
#!/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")
Gọi echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
in:
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
Đối với các phiên bản awk dưới 4.1, bạn sẽ phải sử dụng nối chuỗi trong vòng lặp for, xem hàm ví dụ https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .