分发脚本:我应该将/ bin / gawk或/ usr / bin / gawk用于shebang吗?


12

gawk通常在/ bin或/ usr / bin中吗?我愿意,#!/usr/bin/env gawk但是我不能使用参数。现在我正在使用#!/bin/gawk -f。该脚本很长,包含很多单引号,并且可以与stdin一起使用。

GNU Awk手册的第1.1.4节“可执行awk程序”在其示例中使用#!/ bin / awk,但接着说:

请注意,在许多系统上都awk可以在中找到/usr/bin而不是/bin。买者自负。

大多数人做什么?我已经读过sed应该在/ bin中标准化,而perl应该在/ usr / bin中标准化(与sed链接相同的页面,但是他们不会让我为此帖子做第三个链接)。那awk / gawk呢?有谁知道哪个更普遍或更受欢迎?


你为什么用-f?还/bin/gawk不够吗 同样,可能是相关的。
terdon

Answers:


7

Shebang并不是那样灵活。在某些情况下,可以使用第二个参数,我认为FreeBSD就是其中之一。

gawk和操作系统附带的大多数实用程序都应该在/usr/bin/

在较早的UNIX时代,通常会/usr/挂载在NFS或一些较便宜的介质上,以节省本地磁盘空间和每个工作站的成本。/bin/本应该具有在单用户模式下引导的所有东西。由于/usr/未安装在可靠的介质上,因此/bin/包含足够的实用程序,使其对于常规管理和故障排除足够友好。

它最初是在Linux中继承的,但是由于磁盘空间不再是问题,并且在大多数情况下/usr/是在根文件系统中,所以当前的趋势是将所有内容都移入其中/usr/bin(至少在Linux世界中)。因此,预计可以在此找到大多数由发行版安装的实用程序。连最起码的公共事业,如cprmls等(当然,目前还没有)。

关于shebang的选择。传统上,这是管理员或用户必须根据其环境进行编辑的内容。对于所有的开发者都知道,在别人的系统,解释可能是在文件系统中的任何地方(例如/usr/local/bin/opt/gawk-4.0.1/bin)。正确打包的脚本(rpm,deb等)附带对发行版软件包的依赖(即,解释器的位置已知)或配置脚本,该脚本可在安装过程中设置正确的hashbang。


14

如果您不需要将参数传递给命令,那么这#!/usr/bin/env gawk是可行的方法,但是许多内核(包括Linux)仅接受一个单独的参数来运行shebang程序。

否则,您可以制作一个既是外壳包装程序又是awk脚本的多语言程序。这是一个awk。

#!/bin/sh
true + /; exec gawk -f "$0"; exit; / {}
# awk script starts here

Shell解析:

  • true + /;true具有两个惰性参数+和的命令(不执行任何操作)/
  • 呼叫gawk。这可以是任何不包含换行符且在其中写入斜线的外壳程序片段\/(除了在引号内,外壳程序不在乎)。
    该调用用于exec用gawk替换外壳,而不是将gawk作为子进程执行。
  • exit;—退出外壳,以防找不到gawk。此后的所有内容都将被忽略,除非它应该是有效的shell语法,以防shell在开始执行之前试图解析整行。

AWK解析:

  • 斜线之间的位是一个正则表达式。
  • true + /REGEX/- 一个条件。true是一个未定义的变量,因此其数值为0,并不重要。
  • {} —如果满足上述条件,则什么也不做。

5

Gilles提出的解决方案确实是一种非常好的方法(最终在他的帖子中享有投票的声誉:))。

在任何情况下,据我所知,该exec命令使之后的exit权限变得不必要,实际上是无法到达的,因为shell进程被替换了awk

另外,为了允许awk脚本访问其调用参数,我建议对建议的解决方案进行一些更改:

#!/bin/sh
true + /; exec -a "$0" gawk -f "$0" -- "$@"; / {}
# awk script starts here

-a "$0"允许脚本访问其调用的名称,否则将永远得到awkgawk访问时,ARGV[0]变量。同样,"$@"允许脚本访问ARGV[1...N]数组中的其余参数,并且--前面的脚本允许脚本接收-<something>参数而无需gawk解释它们的目的。

要记住/考虑的一件事是在脚本程序块exit(0);的末尾添加一条语句,否则将威胁作为输入文件传递给脚本的所有参数。(请注意,与我们从行中删除的语句完全无关,这是一个无法到达的shell语句,而此建议的退出位于awk代码中)。BEGIN { ... }awkawkexittrue + ...


exit(0)非常有用!另外,对于macOS用户,请参见以下要点:很难找到一个好的便携式awk shebang。
Seamus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.