我读到,符合 POSIX 标准的操作系统(例如:Linux)必须有 shell sh
。
但是否必须sh
在/bin
目录中,还是可以在任何目录中?
答案1
POSIX 仅强制/dev
和/tmp
目录存在、 、/dev/null
、/dev/tty
、 和/dev/console
文件。标准实用程序必须存在,但没有指定特定位置。可能/bin
根本不存在 a ,如果存在也可能不包含 a sh
,如果包含则可能不是 POSIX sh
。
您可以使用以下方式获取PATH
包含 POSIX 工具(包括)的有效变量sh
getconf
命令:
$ PATH=$(getconf PATH)
$ sh
例如,这在 Solaris 上很有用,其中默认值sh
不兼容 POSIXsh
,但提供了合规性并以这种方式访问(因为Solaris 是经过认证的 Unix)。getconf PATH
将包含/usr/xpg4/bin
在前面,其中包含 POSIXsh
和许多其他所需的工具(包括无用的,比如cd
)。
答案2
不,不需要sh
加入/bin
。它明确引用/bin
、/usr/bin
、 和/usr/xpg4/bin
作为可能的位置。 POSIX 规范仅要求位于sh
PATH 中。
这POSIX 规范状态:
应用程序应注意,shell 的标准 PATH 不能假定为
/bin/sh
或/usr/bin/sh
,并且应通过询问 getconf PATH 返回的 PATH 来确定,确保返回的路径名是绝对路径名而不是 shell 内置路径名。例如,要确定标准 sh 实用程序的位置:
command -v sh
在某些实现上,这可能会返回:
/usr/xpg4/bin/sh
答案3
正如其他人所说,这并不是 POSIX 合规性的严格要求。
但可以说与现有软件的兼容性要重要得多(毕竟,POSIX 的目的是让某些功能在所有符合标准的操作系统上运行),并且如果操作系统不提供 sh at /bin/sh
,则会破坏某些功能。
最明显的是,脚本#!/bin/sh
依赖于这条标准化路径。这不是工作所必需的;POSIX 甚至不要求#!
支持行,尽管它提到这种功能很常见:
一些历史实现处理 shell 脚本的另一种方法是将文件的前两个字节识别为字符串“#!”并使用文件第一行的其余部分作为要执行的命令解释器的名称。
但如果不支持,许多现有软件将崩溃或需要额外的工作来移植。