答案1
sed、awk、perl 和 sh 哪个最可移植?
sed
sh
并且是可移植的,awk
由 POSIX 指定,perl
并不代表不受标准支持。
有人可以把这些工具按可移植性排序吗?
如果您坚持使用兼容的代码,则三个 POSIX 命令不应该有可移植性的顺序。
即使在最小的 *nix 系统上也肯定能找到其中的哪一个?
三个 POSIX 工具以及许多其他实用程序对于操作系统来说是 POSIX 所必需的。但由于最小化或提供不完整/不合格的实现而缺乏其中一些的操作系统确实存在。
事实上,大多数(如果不是全部)免费和开源的类 Unix 操作系统可能不会通过一致性流程,即使它们试图通过,而且它们也从不尝试。
他们中有人 100% 肯定会出现吗?
我会惊讶地发现 *nix 之类的操作系统缺少基于 Bourne 语法的 shell,但一切皆有可能,尤其是对于嵌入式系统。
我的猜测是顺序如下:某些 shell 将作为默认值出现,它总是位于 /bin/sh 吗?
/bin/sh
可能是 Bourne 语法系列 shell,但不保证兼容 POSIX,即使是 POSIX 兼容系统。例如,它适用/usr/xpg4/bin/sh
于 Solaris 10 及更早版本,而/bin/sh
它是传统的原始 Bourne shell,不是 POSIX。
答案2
sed
从 Autotools 中汲取灵感:如果您必须编写必须有效的东西,请坚持 Bourne 和 POSIX shell 的最低公分母(可能会增强)到处。可能存在一些系统出现问题,但您可以通过重写来解决这些问题。
例如,一些古老的系统存在 中的扩展错误问题test
,又名[
:
if [ $foo = bar ] ; then...
所以Autoconf的做法是重写它用带有单字符前缀的双引号引起来,如下所示:
if [ x"$foo" = "xbar" ] ; then...
您也可以"x$foo"
在这里使用。这可以防止$foo
成为 的有效选项的可能性test(1)
,并且由于[
是 的别名test
,因此它可能会误解表达式。解决方案是设置一种情况,其中未知参数 to[
始终以 开头x
,这意味着它不能具有特殊含义 to [
。
(Autoconf 还建议使用test
而不是[
,但该建议是对与M4[
,它也在其语法中使用。)
awk 是 POSIX,所以理论上它随处可用。甚至在 Busybox 中也有awk
,因此即使在一些非常严格的嵌入式 Linux 系统中您也可以实现。不过,如果遇到一个awk
没有.NET 的系统,我不会感到惊讶sed
。我认为这归结于复杂性:更简单的工具更有可能在积极的分类中幸存下来。
Perl 不属于任何广泛使用的标准(POSIX 或其他标准),因此如果您事先对目标环境一无所知,那么您就不能指望它。默认情况下,Perl 未安装在:
- 西格文
- FreeBSD 和 NetBSD
- 某些 Linux 的“最小”安装,包括 Slackware
- 许多嵌入式 Linux 主要依赖 Busybox 作为用户空间
Autoconf手册有关于可移植 shell 编程的一章这应该对你有帮助。最后一部分介绍了sed
、awk
、 和许多其他工具。