可移植 shell 编程的资源

可移植 shell 编程的资源

有哪些可移植 shell 编程的资源?最终的答案是在所有目标平台上进行测试,但这很少实用。

POSIX/单一 UNIX 规范是一个开始,但它既不告诉您每个实现的支持级别是什么,也不告诉您存在哪些常见扩展。您可以阅读每个实现的文档,但这非常耗时且不完全准确。

在我看来,理想的格式是 POSIX 规范的某种社区注释版本,其中每个功能都通过其在不同实现中的支持级别进行注释。有这样的事吗?或者还有其他有用的资源吗?

例如,有Sven Mascheck 的 shell 可移植性页面,但它仅涉及语法元素和一些内置函数,并且仅涵盖旧 shell。我正在寻找更全面的资源。

答案1

autoconf 手册有一节介绍 便携式 shell 编程

尽管这并不是专门针对 POSIX,但它可能是尝试编写可移植 shell 代码时该做什么和不该做什么的最完整的集合。

答案2

除了dash和之外posh,还有bournesh(或bsh),传家宝伯恩贝壳,可用于检测巴什主义

Heirloom 项目还包括“The Heirloom Toolchest”,它是 100 多个标准 Unix 实用程序的集合(可以作为比较命令行选项的起点)。

答案3

如同这个答案,尝试执行你的脚本豪华

另外,不要忘记将POSIXLY_CORRECT环境变量设置为 true,因为这会导致许多程序(不仅是 shell)更严格地遵守 POSIX 标准。

答案4

如今,您通常可以在系统上找到 POSIX shell,因此这通常意味着您可以使用 POSIX 语言编写脚本(模数运行到合规性错误)。

唯一的问题是/bin/sh有时不是 POSIX shell。并且您必须将该行硬编码#!到脚本中,使其表现得像可执行文件一样;您不能只要求用户研究问题,然后将您的脚本调用为/path/to/posix/shell myscript.

因此,技巧是在脚本中使用 POSIX 功能,但让脚本自动查找 POSIX shell。一种方法是这样的:

#!/bin/sh

# At this point, we may be running under some old shell
# we have to tread carefully.

# note how we use test rather than [ ] syntax and avoid
# depending on test with no argument producing a failure;
# i.e. "test $posix_shell".

if ! test x$posix_shell = x ; then
  # the three possible shell paths are just an example;
  # please extend as necessary.

  for shell in /usr/xpg4/bin/sh /bin/bash /usr/bin/bash ; do
    if test -x $shell ; then
       posix_shell=$shell
    fi
  done
  if test x$posix_shell = x ; then
    echo "no POSIX shell found"
    exit 1
    # or we could avoid bailing here and just fall back on /bin/sh:
    # echo "falling back on /bin/sh: cross your fingers that it works"
    # posix_shell=/bin/sh
  fi
  export posix_shell

  # plain "$@" is broken in ancient shells! 
  # I seem to recall ${@+"$@"}: not sure if that's the right trick.

  exec $posix_shell $0 ${@+"$@"}  # can we count on exec in legacy shells? 
fi

# phew, at this point in the script we have been re-executed and are
# being interpreted by some reasonably modern shell. We can use $(...)
# command substitution, and other features.

还有其他方法,例如代码生成。使用一个小脚本来增强您的脚本,该脚本采用不带 #! 的脚本文件主体。行,并加一。

您能做的最糟糕的事情就是开始编写整个脚本,使其在 1981 年的 Bourne shell 上运行。只有当您必须为实际上没有任何其他 shell 的系统编写代码时,才需要这样做。

相关内容