在 bash 中$0
包含脚本的名称,但在 awk 中,如果我创建一个名为 myscript.awk 的脚本,其中包含以下内容:
#!/usr/bin/awk -f
BEGIN{ print ARGV[0] }
并运行它,它只会打印“awk”。此外,i>0 的 ARGV[i] 仅用于命令行中的脚本参数。那么,如何让它打印脚本的名称,在本例中为“myscript.awk”?
答案1
在 cygwin 上的 bash 中使用 GNU awk 4.1.3:
$ cat tst.sh
#!/bin/awk -f
BEGIN { print "Executing:", ENVIRON["_"] }
$ ./tst.sh
Executing: ./tst.sh
我不知道它有多便携。不过,与往常一样,我不会在 shell 脚本中使用 shebang 来执行 awk 脚本,因为它只会剥夺您可能的功能。保持简单,只需这样做:
$ cat tst2.sh
awk -v cmd="$0" '
BEGIN { print "Executing:", cmd }
' "$@"
$ ./tst2.sh
Executing: ./tst2.sh
最后一个可以与任何平台上任何 shell 中的任何现代 awk 一起使用。
答案2
我不知道从 awk 中获取命令名称的任何直接方法。不过,您可以通过子 shell 找到它。
呆呆地
使用 GNU awk 和ps
命令,您可以使用进程 ID 来PROCINFO["PID"]
检索命令名称作为解决方法。例如:
cmdname.awk
#!/usr/bin/gawk -f
BEGIN {
("ps -p " PROCINFO["pid"] " -o comm=") | getline CMDNAME
print CMDNAME
}
莫克和诺克
您可以使用相同的方法,但从特殊的 shell 变量(父级的 PID)awk
派生 PID :$PPID
cmdname.awk
#!/usr/bin/mawk -f
BEGIN {
("ps -p $PPID -o comm=") | getline CMDNAME
print CMDNAME
}
测试
像这样运行脚本:
./cmdname.awk
两种情况下的输出:
cmdname.awk
答案3
答案4
使用 GNU awk
检查GNU awk 用户指南 - 7.5.2 传递信息的内置变量我偶然发现:
程序信息#
该数组的元素提供对正在运行的 awk 程序的信息的访问。以下元素(按字母顺序列出)保证可用:
PROCINFO["pid"]
当前进程的进程ID。
这意味着你可以在运行时知道程序的PID。然后,需要使用system()
这个给定的 PID 来查找进程:
#!/usr/bin/gawk -f
BEGIN{ pid=PROCINFO["pid"]
system("ps -ef | awk '$2==" pid " {print $NF}'")
}
我使用ps -ef
,它在第二列上显示 PID。假设执行完成awk -f <script>
并且没有其他参数,我们可以假设该行的最后一个字段包含我们想要的信息。
如果我们有一些参数,我们将不得不以不同的方式解析该行 - 或者,更好的是,使用一些选项来ps
仅打印我们感兴趣的列。
测试
$ awk -f a.awk
a.awk
$ cp a.awk hello.awk
$ awk -f hello.awk
hello.awk
另请注意,GNU awk 用户指南的另一章告诉我们 ARGV 不是正确的选择:
最后,ARGV[0] 的值(请参阅内置变量)根据您的操作系统而变化。有些系统在那里放置“awk”,有些系统放置 awk 的完整路径名(例如 /bin/awk),有些系统放置脚本的名称(“advice”)。 (直流)不要依赖 ARGV[0] 的值来提供脚本名称。