我正在阅读UNIX中的高级编程,并偶然发现了这个例子。什么是shebang线在这里做什么?这是代码的顶部。
#!/usr/bin/awk -f
BEGIN {
printf("#include \"apue.h\"\n")
printf("#include <errno.h>\n")
printf("\n")
printf("static void pr_sysconf(char *, int);\n")
printf("static void pr_pathconf(char *, char *, int);\n")
printf("\n")
printf("int\n")
printf("main(int argc, char *argv[])\n")
printf("{\n")
printf("\tif (argc != 2)\n")
printf("\t\terr_quit(\"usage: a.out <dirname>\");\n\n")
FS="\t+"
while (getline <"sysopt.sym" > 0) {
printf("#ifdef %s\n", $1)
printf("\tprintf(\"%s is defined (val is %%ld)\\n\", (long)%s+0);\n", $1, $1)
printf("#else\n")
printf("\tprintf(\"%s is undefined\\n\");\n", $1)
printf("#endif\n")
printf("#ifdef %s\n", $2)
shebang可以理解execve(2)系列(在Linux和大多数Unix上)。但是,POSIX没有指定任何内容。你的脚本应该由例如GNU awk
,假设脚本是一个可执行文件(你可能希望它可以从你的PATH
variable访问)。
所以当某个东西(可能是你的Unix shell,但可能是其他的东西)正在用execve
那个脚本执行时,/usr/bin/awk
程序就会被执行。你打赌这个awk
程序是AWK的一些实现
操作系统执行文件的例程在文件开头查找两个字符#!
,如果存在,而不是直接将文件作为二进制可执行文件加载,它们会调用该行的其余部分引用的可执行文件,以及其中有任何命令行参数,然后将原始文件作为最终参数。
这是一个非常复杂的描述;几个例子让它更清晰:
如果myFile
包含:
#!/bin/echo My path is
......我们让它可执行:
$ chmod +x myFile
...然后当我们运行它时,我们得到:
$ ./myFile
My path is /home/slim/myFile
或者,如果我们将其内容更改为:
#!/bin/cat
Hello
world
然后,当我们运行它时,它打印自己......
$ ./myFile
#!/bin/cat
Hello
world
当它调用的命令是一个可以处理内容的解释器时,这通常很有用,并且它本身忽略了shebang。当然,在许多语言中,#
表示评论,因此我们免费获得:
#!/bin/bash
#!/usr/bin/perl
#!/bin/awk -f
所以基本上它排列的问题是直接运行myFile
,相当于运行awk -f myFile
。