经常见到shell脚本的开头有这么一句 #!/bin/bash 或者 #!/bin/bash -x。
#!`的后面紧跟可执行程序的完整路径,在后面可以跟参数,但操作系统把这后面的所有参数当成一个参数。
#!后面如果跟参数,最好只跟一个,多了还得自己处理
试验
脚本:advice2
#!./fakeawk -f hello world 'ok are you'
C程序
// file: fakeawk.c
#include <stdio.h>
int main(int argc, char *argv[]){
for (int i = 0; i<argc; i++){
printf("%d: %s\n", i, argv[i]);
}
return 0;
}
CentOS 7
使用的是bash。
$ gcc fakeawk.c -o fakeawk
$ chmod u+x advice2
$ ./advice2
0: ./fakeawk
1: -f hello world 'ok are you'
2: ./advice2
# 调用脚本传递参数
$ ./advice2 a b c 'd e'
0: ./fakeawk
1: -f hello world 'ok are you'
2: ./advice2
3: a
4: b
5: c
6: d e
不同的系统对argv[0]的设置不一样,可能是
- 可执行文件的完整路径
/bin/bash,./fakeawk - 可能是可执行文件的主文件名
bash,fakeawk - 可能是脚本文件名
./advice
所以不要把argv[0]当作判断依据。
MSYS
换个环境再试试。
$ ./bang.sh
0:./args
1:-f 'hello world' ok
2:./bang.sh
$ ./bang.sh hello world
0:./args
1:-f 'hello world' ok
2:./bang.sh
3:hello
4:world
- argv[0] 是可执行文件的完整路径
- argv[1] 是#!后的参数
- argv[2] 是脚本名
- 其它跟着调用脚本的参数
如果跟着假的程序
# 换成 #!../fakeawk
$ ./advice2
-bash: ./advice2: ../fakeawk: bad interpreter: No such file or directory
# 换成 #!./blabla
$ touch blabla
$ ./advice2
-bash: ./advice2: ./blabla: bad interpreter: Permission denied
参考
gun的awk手册中有一段关于#!的注解

本文探讨了Shell脚本中#!/bin/bash行的作用及参数处理方式,通过实验对比了不同系统下解释器对参数的解析差异,揭示了argv[0]在不同环境中的表现,为脚本编写者提供了实用的参考。
1468





