首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Shebang多参数

Shebang多参数
EN

Stack Overflow用户
提问于 2017-08-10 19:35:02
回答 2查看 1.5K关注 0票数 2

我目前正在编写一个awk脚本,如下所示:

代码语言:javascript
复制
#!/usr/bin/awk -f
BEGIN {
    print "Starting extracting data"
}
{
    print $0
}
END {
    print "End of file"
}

我的脚本在我的电脑上运行得很好,但它不能移植……我想做一些像这样的事情

代码语言:javascript
复制
#!/usr/bin/env awk -f
...

但是Debian shell不接受单个shebang中的多个参数。我得到了"awk -f" no such file or directory。有没有什么我可以使用的变通方法,或者这是完全不可能的?

EN

回答 2

Stack Overflow用户

发布于 2017-10-11 03:44:17

没有简单的方法可以干净利落地做到这一点;正如在glenn jackman's comment中提到的,shebangs是由execve()实现的,它只接受一个解释器和一个可选参数。

您需要一个变通方法。

这个问题的注释暗示您不需要包装器脚本,但是如果它包含在最终的~awk脚本中呢?

代码语言:javascript
复制
#!/bin/sh
awk -f - "$@" << 'EOF'
#!/usr/bin/awk -f

BEGIN {
    print "Starting extracting data"
}
{
    print $0
}
END {
    print "End of file"
}

这在它的shebang中使用了可移植的POSIX shell,然后立即从标准输入(-f -)上的heredoc调用awk代码,将更多的参数和选项("$@")作为文件传递给awk。此处的文档是用引号(<< 'EOF')引用的,因此POSIX shell不会解释$0之类的内容。由于不存在仅由EOF组成的行,因此此处的文档以该文件结尾。

(第二个shebang不是由任何人读取的。对于阅读代码的人来说,它纯粹是装饰性的。如果使用.awk后缀命名此文件,vim等编辑器将默认将其语法突出显示设置为awk,而不考虑第一个shebang的内容。)

该代码不能将内容通过管道传输到文件中,因为脚本本身是通过管道传输到awk中的。如果你想支持管道,它需要更丑陋一点,使用bash的输入process substitution (<(…)):

代码语言:javascript
复制
#!/bin/bash
exec awk -f <(awk 'NR > 2' "$0") "$@"
#!/usr/bin/awk -f

BEGIN {
    print "Starting extracting data"
}
{
    print $0
}
END {
    print "End of file"
}

这告诉bash在第二个awk命令创建的命名管道上执行awk,该命令读取完整的脚本(bash将$0解释为它正在运行的文件的名称),并打印第3行和更高的行。同样,第二个shebang纯粹是表面上的,因此只是一个评论。

票数 1
EN

Stack Overflow用户

发布于 2017-10-11 04:07:23

真的没有理由在shebang中调用awk。只需通过sh调用它:

代码语言:javascript
复制
#!/bin/sh
exec awk '
BEGIN {
    print "Starting extracting data"
}
{
    print $0
}
END {
    print "End of file"
}
' "$@"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45612626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档