Linux 通过shebang线路链接口译员是否可移植?
Linux 通过shebang线路链接口译员是否可移植?,linux,shell,unix,posix,executable,Linux,Shell,Unix,Posix,Executable,在POSIX操作系统上,通过所谓的shebang行将脚本绑定到特定的解释器是一种众所周知的做法。例如,如果执行以下脚本(给定足够的文件系统权限),操作系统将启动/bin/sh解释器,并将脚本的文件名作为其第一个参数。随后,shell将执行脚本中的命令,跳过shebang行,并将其视为注释
#! /bin/sh
date -R
echo hello world
可能的产出:
Sat,2017年4月1日12:34:56+0100
你好,世界
我过去认为解释器(/bin/sh在本例中)必须是本机
在POSIX操作系统上,通过所谓的shebang行将脚本绑定到特定的解释器是一种众所周知的做法。例如,如果执行以下脚本(给定足够的文件系统权限),操作系统将启动/bin/sh
解释器,并将脚本的文件名作为其第一个参数。随后,shell将执行脚本中的命令,跳过shebang行,并将其视为注释
#! /bin/sh
date -R
echo hello world
可能的产出:
Sat,2017年4月1日12:34:56+0100
你好,世界
我过去认为解释器(/bin/sh
在本例中)必须是本机可执行文件,而不能是脚本本身,而脚本本身又需要启动另一个解释器
然而,我还是继续做了下面的实验
使用以下保存为/tmp/explorer.py
的哑shell
#/usr/bin/python3
导入系统
导入子流程
对于sys.argv[1:]中的脚本:
以打开(脚本)作为istr:
状态=任何(
地图(
subprocess.call,
地图(
斯普利特街,
滤器(
lambda s:s而不是s.startswith(“#”),
地图(str.strip,istr)
)
)
)
)
如果状态:
系统退出(状态)
…并将以下脚本另存为/tmp/script.xyz
#! /tmp/interpreter.py
date -R
echo hello world
…我能够(在使这两个文件都可执行之后)执行script.xyz
5gon12eder:/tmp> ls -l
total 8
-rwxr-x--- 1 5gon12eder 5gon12eder 493 Jun 19 01:01 interpreter.py
-rwxr-x--- 1 5gon12eder 5gon12eder 70 Jun 19 01:02 script.xyz
5gon12eder:/tmp> ./script.xyz
Mon, 19 Jun 2017 01:07:19 +0200
hello world
5gon12eder:/tmp>ls-l
总数8
-rwxr-x---1 5gon12eder 5gon12eder 493 Jun 19 01:01解释器.py
-rwxr-x---1 5gon12eder 5gon12eder 70 Jun 19 01:02 script.xyz
5gon12eder:/tmp>/script.xyz
2017年6月19日星期一01:07:19+0200
你好,世界
这让我很惊讶。我甚至可以通过另一个脚本启动scrip.xyz
所以,我要问的是:
- 我的实验观察到的行为是可移植的吗
- 实验是否正确进行,或者是否存在不起作用的情况?不同的(类Unix)操作系统如何
- 如果这是可行的,那么就调用而言,本机可执行文件和解释脚本之间是否没有明显的差异
类Unix操作系统中的新可执行文件由系统调用execve
(2)启动。execve
的手册页包括:
解释器脚本
解释器脚本是已执行的文本文件
已启用权限,且其第一行的格式为:
#! 解释器[可选参数]
解释器必须是可执行文件的有效路径名
它本身不是一个脚本。如果execve()的filename参数
指定解释器脚本,然后将调用解释器
有以下论点:
解释器[可选参数]文件名参数。。。
其中arg。。。是argv指向的一系列单词
execve()的参数。
对于便携使用,可选arg应该不存在,或者不存在
指定为单个单词(即,不应包含白色
空间);见下文注释。
因此,在这些限制(类似Unix,最多一个单词的可选参数)中,shebang脚本是可移植的。阅读手册页了解更多详细信息,包括二进制可执行文件和脚本之间调用的其他差异
见下文黑体字:
这种机制允许脚本在几乎任何上下文中使用
正常编译程序可以是,包括作为完整系统程序,
甚至作为其他脚本的翻译。不过,作为警告,有些
早期版本的内核支持限制了解释器的长度
指令,大约32个字符(第一个字符中只有16个字符
实现),将无法将解释器名称从任何
指令中的参数,或具有其他怪癖。此外,一些
现代系统允许对整个机构进行约束或调整
出于安全目的禁用(例如,设置用户id支持已禁用)
已在许多系统上禁用脚本)。——
来自COLUMNS=75 man execve | grep-nA 23”的输出
解释器脚本“| head-39
在Ubuntu 17.04上,
特别是第186-189行,它告诉我们什么可以在Linux上工作(即脚本可以是解释器,最多四层):
166:解释器脚本
167-解释器脚本是具有执行权限的文本文件
168-已启用,其第一行的形式为:
169-
170- #! 解释器[可选参数]
171-
172-解释器必须是可执行文件的有效路径名。
173-如果execve()的filename参数指定解释器
174-脚本,然后将使用以下参数调用解释器
175-附件:
176-
177-解释器[可选参数]文件名参数。。。
178-
179-在哪里arg。。。是argv argu指向的一系列单词
从argv[1]开始执行execve()的180个字符。
181-
182-对于便携式使用,可选arg应该不存在,或者
183-指定为单个单词(即不应包含白色
184-空间);见下文注释。
185-
186-自Linux2.6.28以来,内核允许脚本的解释器
187年的今天,它本身就是一个剧本。此权限是递归的,最多为
188-限制四个递归,以便解释器可以是脚本
189-由脚本解释,依此类推。
--
343:解释器脚本
344-第一行允许的最大行长为127个字符
345-解释器脚本中的行。
346-
347-解释器的可选arg参数的语义
348-脚本在implem中有所不同
166: Interpreter scripts
167- An interpreter script is a text file that has execute permission
168- enabled and whose first line is of the form:
169-
170- #! interpreter [optional-arg]
171-
172- The interpreter must be a valid pathname for an executable file.
173- If the filename argument of execve() specifies an interpreter
174- script, then interpreter will be invoked with the following argu‐
175- ments:
176-
177- interpreter [optional-arg] filename arg...
178-
179- where arg... is the series of words pointed to by the argv argu‐
180- ment of execve(), starting at argv[1].
181-
182- For portable use, optional-arg should either be absent, or be
183- specified as a single word (i.e., it should not contain white
184- space); see NOTES below.
185-
186- Since Linux 2.6.28, the kernel permits the interpreter of a script
187- to itself be a script. This permission is recursive, up to a
188- limit of four recursions, so that the interpreter may be a script
189- which is interpreted by a script, and so on.
--
343: Interpreter scripts
344- A maximum line length of 127 characters is allowed for the first
345- line in an interpreter scripts.
346-
347- The semantics of the optional-arg argument of an interpreter
348- script vary across implementations. On Linux, the entire string
349- following the interpreter name is passed as a single argument to
350- the interpreter, and this string can include white space. How‐
351- ever, behavior differs on some other systems. Some systems use
352- the first white space to terminate optional-arg. On some systems,
353- an interpreter script can have multiple arguments, and white spa‐
354- ces in optional-arg are used to delimit the arguments.
355-
356- Linux ignores the set-user-ID and set-group-ID bits on scripts.