Aiv*_*var 47 command-line scripts executable shebang
如果我想执行一个没有设置执行权限的 bash 脚本,我可以这样做:
bash script.sh
Run Code Online (Sandbox Code Playgroud)
bash如果脚本不可执行并且我不知道正确的解释器,我应该使用什么来代替?是否有一个命令可以从 shebang 行查找解释器并用它执行脚本?
Ole*_*nge 73
是的。它被称为perl。一些示例,在文件的 shebang 行中使用相应的解释器(实际的文件扩展名无关紧要):
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)
Run Code Online (Sandbox Code Playgroud)
Perl 的文档中提到了这一点:
如果该
#!行既不包含单词“perl”也不包含单词“indir”,#!则执行以 命名的程序而不是 Perl 解释器。这有点奇怪,但它可以帮助那些不这样做的机器上的人#!,因为他们可以告诉程序他们的 SHELL 是 /usr/bin/perl,然后 Perl 会将程序分派给正确的解释器。
Jac*_*ijm 25
如果脚本是从解释器中运行,你不能确保它具有家当都。脚本,从解释器中运行不需要家当,如果你调用解释器来运行代码。
因此答案是否定的,没有命令可以确定运行脚本的语言(解释器)是什么。但是,您始终可以查看脚本内部,看看它是否有要找出的shebang。
规则简而言之:
但是,如果脚本没有shebang,则脚本内部没有(直接*)信息来告诉要使用什么解释器。
您当然可以始终编写一个包装脚本来尝试找出脚本是否具有 shebang 并从中读取解释器,然后从找到的解释器中运行它。
一个例子
#!/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")
Run Code Online (Sandbox Code Playgroud)
将其保存为tryrunin $PATH(例如~/bin,如果目录不存在,则创建该目录,注销并重新登录),使其可执行。然后运行:
tryrun /path/to/nonexecutablescript
Run Code Online (Sandbox Code Playgroud)
在我的非可执行文件python和bash脚本上调用(测试)正确的解释器。
#!并使用其余部分来调用解释器。PermissionError或 a FileNotFoundError。扩展(.sh,.py等)中扮演的角色没有任何确定在Linux上适当的解释。
(*当然可以开发一种“智能”猜测算法来确定代码中的语法。)
您可以使用这样的脚本来实现这一点:
#!/bin/bash
copy=/tmp/runner.$$
cp $1 ${copy}
chmod u+x ${copy}
${copy}
rm ${copy}
Run Code Online (Sandbox Code Playgroud)
因此:
$ echo "echo hello" > myscript
$ ./myscript
bash: ./myscript: Permission denied
$ ./runscript myscript
hello
Run Code Online (Sandbox Code Playgroud)
我建议不要这样做。权限存在是有原因的。这是一个颠覆权限的程序。
请注意,shebang 处理是一个内核函数(在 Linux 源代码中 - fs/binfmt_script.c)。从根本上说,直接调用脚本的进程并不知道#!——内核使用它来确定它需要启动一个解释器。