当开始没有shebang行(#!/ path / to / shell)时,哪个shell执行脚本?我假设/ bin / sh但我无法确认。
内核拒绝执行此类脚本并返回ENOEXEC,因此确切的行为取决于您从中运行此类脚本的程序。
- bash 4.2.39 –自用
- busybox-ash 1.20.2 –自用
- 破折号0.5.7 –运行/ bin / sh
- 鱼1.23.1 –抱怨ENOEXEC,然后指责错误的文件
- AT&T ksh 93u + 2012.08.01 –自用
- mksh R40f –运行/ bin / sh
- pdksh 5.2.14 –运行/ bin / sh
- sh-heirloom 050706 –自用
- tcsh 6.18.01 –运行/ bin / sh
- zsh 5.0.0 –运行/ bin / sh
- cmd.exe 5.1.2600 –看起来很有趣。
在glibc中,函数execv()
或execve()
仅返回ENOEXEC。但是execvp()
隐藏此错误代码并自动调用/ bin / sh。(这在exec(3p)中有说明。)
在编写可在任何平台上运行的shell脚本方面,什么被称为“最佳实践”?(好的,这是开放式的)
要么坚持sh
,只有POSIX定义的功能,或者只是去完全的bash(这是广泛使用的),并提到它在你的要求,如果发送邮件。
(现在我想到了,Perl或Python)将更加可移植,更不用说具有更好的语法了。)
始终添加shebang行。如果使用bash或zsh,请使用#!/usr/bin/env bash
而不是对外壳程序的路径进行硬编码。(但是,保证POSIX shell位于at /bin/sh
,因此请跳过env
这种情况。)
(不幸的是,甚至/bin/sh
并不总是相同。GNUautoconf程序必须处理许多不同的问题。)
如果zsh不可用,是否有可能编写尝试使用zsh并退回到bash的脚本?我已经尝试过放置两个shebang行,如下所示,但是由于解释器错误而导致错误:/ bin / zsh:如果在没有zsh的计算机上尝试,则没有这样的文件或目录。
射帮线只能有一条。换行符之后的所有内容甚至都不会被内核读取,并被shell视为注释。
它可以编写一个脚本,运行的#!/bin/sh
,检查其外壳是可用的,并且运行exec zsh "$0" "$@"
或exec bash "$0" "$@"
取决于结果。但是,bash和zsh所使用的语法在许多地方都非常不同,因此我不建议您出于自己的理智而这样做。