当类似Bash的脚本以二进制形式执行而没有shebang时,如何确定由谁执行?
我猜想 使用 shebang
运行普通脚本是由binfmt_script
Linux模块处理的,该模块检查shebang,解析命令行并运行指定的脚本解释器。
但是,如果有人在没有脚本的情况下运行脚本会发生什么?我已经测试了直接execv
方法,发现里面没有内核魔术,即像这样的文件:
$ cat target-script
echo Hello
echo "bash: $BASH_VERSION"
echo "zsh: $ZSH_VERSION"
运行仅执行execv
调用的已编译C程序将产生:
$ cat test-runner.c
void main(){
如果(execv(“ ./ target-script”,0)== -1)
perror();
}
$ ./测试运行器
./target-script:执行格式错误
但是,如果我从另一个shell脚本执行相同的操作,它将使用与原始脚本相同的shell解释器运行目标脚本:
$ cat test-runner.bash
#!/ bin / bash
./target-script
$ ./test-runner.bash
你好
bash:4.1.0(1)-发布
zsh:
如果我对其他外壳(例如,Debian的默认设置sh
- /bin/dash
)执行相同的操作,那么它也可以工作:
$ cat test-runner.dash
#!/ bin /破折号
./target-script
$ ./test-runner.dash
你好
重击:
zsh:
奇怪的是,它与zsh的配合使用效果不佳,也没有遵循一般的方案。看起来zsh /bin/sh
毕竟对这样的文件执行了:
greycat @ burrow-debian〜/ z / test-runner $ cat test-runner.zsh
#!/ bin / zsh
回声ZSH_VERSION = $ ZSH_VERSION
./target-script
greycat @ burrow-debian〜/ z / test-runner $ ./test-runner.zsh
ZSH_VERSION = 4.3.10
你好
重击:
zsh:
请注意,ZSH_VERSION
在父脚本中有效,而ZSH_VERSION
在子脚本中则无效!
如果没有shebang,shell(Bash,破折号)如何确定执行什么操作?我试图在Bash /
dash来源中挖掘该位置,但是,a,我似乎迷失了。任何人都可以阐明一种神奇的方法,这种方法确定应将没有shebang的目标文件作为脚本执行还是作为Bash
/ dash中的二进制文件执行?或者可能存在 的 某种互动的内核/ libc和那么我会在它是如何在Linux和FreeBSD内核/
libcs工作欢迎解释吗?
由于这种情况发生在破折号中,并且破折号比较简单,因此我首先看了一下。
看起来像exec.c是查找的地方,而相关的函数是tryexec
,shellexec
只要需要执行shell指令,就会从中调用。tryexec函数(的简化版本)如下:
STATIC void
tryexec(char *cmd, char **argv, char **envp)
{
char *const path_bshell = _PATH_BSHELL;
repeat:
execve(cmd, argv, envp);
if (cmd != path_bshell && errno == ENOEXEC) {
*argv-- = cmd;
*argv = cmd = path_bshell;
goto repeat;
}
}
因此,如果发生的话,它总是简单地用其自身的路径替换要执行的命令(_PATH_BSHELL
默认为"/bin/sh"
)ENOEXEC
。这里真的没有魔术。
我发现FreeBSD bash
本身就表现出相同的行为sh
。
的方式bash
处理这个问题是类似的,但要复杂得多。如果您想进一步研究它,我建议您阅读bash的内容,然后execute_command.c
专门阅读execute_shell_script
然后shell_execve
。这些评论具有描述性。
问题内容: 我正在尝试执行zc.buildout自动生成的python脚本,因此我无法控制它们。我的问题是,对于bash(最多80个字符)或直接执行(某些我不知道的Linux内核常量),shebang行(#!)太长了。 这是一个示例脚本,可帮助您重现我的问题: bash或内核如何配置为允许更大的shebang行? 问题答案: 由于内核编译时间缓冲区的限制,在99.9%的系统上限制为127个字符。
问题内容: 当应该从python运行脚本时 ,文件的正确Shebang是什么? 作为示例测试用例,尚未安装我的系统(OSX)上的默认python 。pyenv virtualenv可以。我试图从virtualenv获取python可执行文件的路径。 所以我举了一个例子: 但是,当我尝试运行脚本时,出现错误: 尽管在命令行上运行该路径可以正常工作: 什么是适当的shebang?理想情况下,我想要一些
我正在尝试创建一个bash脚本,它允许我在每次执行它时扩展路径。下面是我要指出的代码: 当我运行它并且cmd请求一个新目录时,我输入了我想要添加的目录,但它显示“第6行:路径:未找到命令” 欢迎所有建议,提前感谢。
问题内容: 是否可以在Linux和Mac上调用无需备份的待办事情就地编辑?虽然似乎需要OS X附带的BSD ,但是GNU Linux发行版通常随附将引号解释为空的输入文件名(而不是备份扩展名),而是需要使用引号。 是否有任何两种语法都适用的命令行语法,所以我可以在两个系统上使用相同的脚本? 问题答案: 如果您真的只想使用“简单”的方法,那么以下DOES可以在GNU和BSD / Mac上运行: 注意
目录表 Linux和BSD用户 Windows®用户 概括 Linux和BSD用户 如果你正在使用一个Linux的发行版比如Fedora或者Mandrake或者其他(你的选择),或者一个BSD系统比如FreeBSD,那么你可能已经在你的系统里安装了Python。 要测试你是否已经随着你的Linux包安装了Python,你可以打开一个shell程序(就像konsole或gnome-terminal)
问题内容: 的 备用屏幕 用于通过像vim,HTOP,屏幕,alsamixer中,以下,…它像一个不同缓冲液中的终端的内容的,其消失的应用程序退出时,所以整个终端许多“用户交互式”应用终端恢复后,看起来应用程序没有输出任何东西。 我想在自己的shell(bash)脚本中实现完全相同的功能,除了它不必具有可移植性。我只会使用linux和基于xterm的终端仿真器;但解决方案应尽可能使用类似的方法。但