Kyl*_*yle 48 shell utilities shell-script posix shell-builtin
这个问题的目的是回答好奇心,而不是解决特定的计算问题。问题是:为什么 POSIX 强制实用程序通常不内置到 shell 实现中?
例如,我有一个脚本,它基本上读取一些小文本文件并检查它们的格式是否正确,但由于大量的字符串操作,在我的机器上运行需要 27 秒。这种字符串操作通过调用各种实用程序来创建数千个新进程,因此速度很慢。我非常有信心,如果内置了一些实用程序,即grep
, sed
, cut
,tr
和expr
,那么脚本将在一秒或更短的时间内运行(根据我在 C 中的经验)。
似乎在很多情况下,构建这些实用程序会影响 shell 脚本中的解决方案是否具有可接受的性能。
显然,选择不内置这些实用程序是有原因的。也许在系统级别拥有一个实用程序版本可以避免该实用程序的多个不同版本被各种 shell 使用。我真的想不出还有很多其他原因来保持创建这么多新进程的开销,而且 POSIX 对实用程序的定义足够多,以至于有不同的实现似乎不是什么大问题,只要它们都是 POSIX合规。至少没有像拥有这么多流程的低效率那样大的问题。
jll*_*gre 67
为什么 POSIX 强制实用程序没有内置到 shell 中?
因为要符合 POSIX,系统需要1将大多数实用程序作为独立命令提供。
将它们内置意味着它们必须存在于两个不同的位置,即外壳内部和外壳外部。当然,可以通过对内置程序使用 shell 脚本包装器来实现外部版本,但这将不利于调用实用程序的非 shell 应用程序。
请注意,BusyBox通过在内部实现许多命令并使用指向自身的链接提供独立变体,采用了您建议的路径。一个问题是,虽然命令集可能非常大,但实现通常是标准的一个子集,因此不合规。
另请注意,至少ksh93
,bash
并zsh
通过为正在运行的 shell 提供自定义方法以从共享库动态加载内置函数来进一步。从技术上讲,没有什么可以阻止所有 POSIX 实用程序被实现并作为内置程序提供。
最后,在现代操作系统中,生成新进程已成为一种非常快速的操作。如果您真的遇到性能问题,可能会进行一些改进以使您的脚本运行得更快。
但是,所有标准实用程序,包括表中的常规内置函数,但不包括特殊内置实用程序中描述的特殊内置函数,都应以某种方式实现,以便它们可以通过 exec 系列POSIX.1-2008 的系统接口卷中定义的函数,可以由需要它的标准实用程序直接调用(env、find、nice、nohup、time、xargs)。
Ed *_*lle 11
预计 Shell 脚本不会以这种速度运行。如果您想提高脚本的速度,请在 perl 中尝试。如果这仍然太慢,那么您将不得不转向静态类型语言,例如 java 或 c,或者为 perl 编写一个 C 模块来运行太慢的部分。
Shell 是原型设计的第一级,如果你可以用 shell 证明这个概念,那么就转向一种更好的脚本语言,它可以做更多的边界检查,这将占用大量的 shell。
一个 Unix 操作系统预计将包含许多小程序,这些小程序可以完成构成更大图景的明确定义的任务。这是一件好事,因为它划分了更大的程序。例如,看看 qmail 并将其与 sendmail 进行比较。qmail 由许多程序组成:
http://www.nrg4u.com/qmail/the-big-qmail-picture-103-p1.gif
利用网络守护进程不会帮助您利用队列管理器。
如果您查看 AT&T 软件工具包的历史(自核心团队离开以来目前处于休眠状态),这正是他们对 AT&T Korn shell(又名 ksh93)所做的。
性能始终是 ksh93 维护者的一部分动机,在构建 ksh 时,您可以选择构建许多常见的 POSIX 实用程序作为动态加载的库。通过将这些命令绑定到一个目录名称,例如/opt/ast/bin
,您可以根据该目录名称在$PATH
.
例子:
cat chmod chown cksum cmp cp cut date expr fmt head join ln
mkdir mkfifo mktemp mv nl od paste rm tail tr uniq uuencode wc
Run Code Online (Sandbox Code Playgroud)
完整列表可以在github ast存储库中找到。
请注意,大多数 ast 工具都有自己的出处,并且与更常见的 gnu 实现有很大不同。AT&T 研究团队遵守官方标准,这是在无法共享代码时实现互操作性的方法。
所以我们没有将资源整合到优化原始工具中,以满足每个特定的需求。我想我们需要解释的是这个特定愿望的实现成本是多少。
POSIX 对实用程序进行了足够的定义,因此拥有不同的实现似乎不是什么大问题。
这是一个糟糕的假设:-P。
Post-POSIX 系统继续变得更加强大和方便,这是有充分理由的;作为事后标准,它从未真正赶上。
Ubuntu 开始努力为脚本切换到精简的 POSIX shell,以优化旧的 System V init 引导过程。我并不是说它失败了,但它确实触发了许多必须清理的错误:“bashisms”,/bin/sh
假设bash
功能可用时运行的脚本。
POSIX sh 不是一种好的通用编程语言。它的主要目的是作为一个交互式外壳很好地工作。一旦您开始将命令保存到脚本中,请注意您接近了图灵 tarpit。例如,不可能检测到正常管道中间的故障。 为此bash
添加set -o pipefail
,但这不在 POSIX 中。
几乎所有比true
.
对于您概述的任务类别,您可以粗略地概括为 Awk、Perl 和现在的 Python。不同的工具被创造出来,并独立发展。您是否希望将例如 GNU Awk 包含到 libutilposixextended 中?
我并不是说我们现在有一种普遍更好的方法,我可以向您指出。我对 Python 情有独钟。Awk 出奇的强大,虽然我一直对 GNU Awk 特有的一些功能感到沮丧。但关键是单独处理大量字符串(大概来自文件的行)并不是 POSIX shell 的设计目标。
归档时间: |
|
查看次数: |
4965 次 |
最近记录: |