Answers:
不,它不是,主要是因为它不需要系统默认遵循或仅符合POSIX标准(不包括任何其他标准)。
例如,Solaris(经过认证的兼容系统)在中选择了其实用程序的向后兼容性/bin
,这解释了为什么它们以奥秘的方式运行,并在不同的位置(/usr/xpg4/bin
,/usr/xpg6/bin
...针对不同版本的XPG(现已合并)提供兼容POSIX的实用程序。(POSIX)标准,这些实际上是Solaris中可选组件的一部分。
甚至sh
不能保证在/bin
。在Solaris上,/bin/sh
在Solaris 10之前,它一直是Bourne shell(因此不兼容POSIX),而在Solaris 11中它现在是ksh93(仍然不完全与POSIX兼容,但实际上比POSIX更重要/usr/xpg4/bin/sh
)。
从C语言开始,您可以使用exec*p()
并假设您处于POSIX环境中(尤其是关于PATH
环境变量)。
您还可以设置PATH
环境变量
#define _POSIX_C_SOURCE=200809L /* before any #include */
...
confstr(_CS_PATH, buf, sizeof(buf)); /* maybe append the original
* PATH if need be */
setenv("PATH", buf, 1);
exec*p("ps"...);
或者,您可以在构建时确定要运行的POSIX实用程序的路径(请记住,在某些系统(如GNU的系统上,您需要执行更多的步骤,如设置POSIXLY_CORRECT
变量以确保合规性))。
您还可以尝试以下操作:
execlp("sh", "sh", "-c", "PATH=`getconf PATH`${PATH+:$PATH};export PATH;"
"unset IFS;shift \"$1\";"
"exec ${1+\"$@\"}", "2", "1", "ps", "-A"...);
希望有一个sh
in $PATH
,它像Bourne一样,也有一个in ,并且它是getconf
您感兴趣的POSIX版本的一个。
/usr/bin/env
存在并且主要符合POSIX。
/usr/bin/env
是一个偶数少便携式比(实际上)破解/bin/sh
。每POSIX,写一个shell脚本的可移植的方法是,没有#!
在所有。如果文件是可执行文件,但ENOEXEC
不是有效的二进制文件,execvp
则通过标准外壳执行该文件。:-)当然,在实践中这不是一个好主意,您应该使用#!/bin/sh
。
$PATH
从外壳而不是从C 进行设置。
实际上,我会在很大程度上回答是。POSIX保证:
虽然它并不一定保证每个实用程序应在所有系统(特定的目录/bin/ps
),它总是保证能够在系统默认路径可以发现,作为一个可执行文件。
事实上,在标准做到这一点的唯一标准规定的方法是(C)中通过unistd.h
的_CS_PATH,或壳,通过组合command
和getconf
实用工具,即PATH="$(command -p getconf PATH)" command -v ps
必须始终返回的唯一绝对路径的 POSIX兼容ps
在特定系统上提供。也就是说,虽然实现定义了系统默认PATH变量中包括哪些路径,但这些实用程序在其中指定的路径之一中必须始终可用,唯一且合规。
PATH=$(command -p getconf PATH)
仅在POSIX环境中的POSIX Shell中有效。POSIX并没有说明您如何进入该环境,而只是对其进行了记录。例如,在Solaris上,您有一个/usr/xpg4/bin/getconf
和和一个/usr/xpg6/bin/getconf
将_CS_PATH
为该标准的两个不同版本返回不同的值,并且默认值/usr/xpg4/bin
也不/usr/xpg6/bin
为$PATH
。有一个/usr/bin/getconf
它IIRC给你XPG4一致性。
sh
从任何默认的shell 。
getconf
在$PATH
给定系统的默认情况下应该有一个命令。例如,获得POSIX环境可能涉及启动仿真层,否则,您将根本不会运行任何类似Unix的命令(例如Windows)。进入兼容环境后,getconf PATH
您$PATH
将可以进入兼容实用程序,但是如果您处于POSIX环境中,情况可能已经如此。请注意,getconf ps
可能会返回ps
。其ps
内置是允许的。
/bin
,即/bin/ed
必须可用如果已安装ed。我现在找不到它,但是我知道LSB依赖于它,并且我已经成功地使用它作为理由来捍卫bug报告,因此至少在某些时候它必须是正确的。(或者这不是POSuX,我记错了,但是其余的都是真的。)