分发脚本:我应该使用 /bin/gawk 还是 /usr/bin/gawk 作为 shebang?

分发脚本:我应该使用 /bin/gawk 还是 /usr/bin/gawk 作为 shebang?

gawk 通常在 /bin 或 /usr/bin 中吗?我会同意#!/usr/bin/env gawk,但我不能使用参数。现在我正在使用#!/bin/gawk -f.该脚本非常长,包含大量单引号,并且适用于标准输入。

GNU Awk 手册有1.1.4 可执行 awk 程序它在示例中使用 #!/bin/awk 但接着说:

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

大多数人做什么?我读了sed 据称在 /bin 中标准化而 perl 据说在 /usr/bin 中标准化(与 sed 链接相同的页面,但他们不允许我为这篇文章创建第三个链接)。 awk/gawk 怎么样?有谁知道哪个更常见或流行?

答案1

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

否则,你可以做一个多语言程序既是 shell 包装器又是 awk 脚本。这是 awk 的一个。

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

外壳解析:

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

awk解析:

  • 斜杠之间的位是正则表达式。
  • true + /REGEX/- 一个条件。true是一个未定义的变量,因此其数值为 0,但这并不重要。
  • {}— 如果上述条件成立,则不执行任何操作。

答案2

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

无论如何,据我了解该exec命令,它使得exit它后面的右边变得不必要,实际上无法访问,因为 shell 进程被替换为awk.

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

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

允许-a "$0"脚本访问它的调用名称,否则在访问变量时它总是会得到一个awkor 。类似地,允许脚本访问数组中的其余参数,前面的它允许脚本接收参数而不用 gawk 解释它们就是为此目的。gawkARGV[0]"$@"ARGV[1...N]---<something>

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

答案3

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 的配置脚本。

答案4

如果安装了更现代的 coreutils (IIUC 8.30+),您现在可以使用

#!/usr/bin/env -S gawk -f

所有选项都将作为一个参数传递给 env,并且它将拆分它们

相关内容