前情提要
在Java中,我们使用单引号来表示一个字符,用双引号来表示一个字符串。而在Python中,单引号和双引号对于字符串来说,毫无区别。那么在shell中单引号和双引号有区别吗?除了单双引号,还有反引号,那么反引号又是用来做什么的?
我使用Python来验证我的想法,argv.py的代码如下:
1 | #!/usr/local/bin/python3 |
直接上结果吧:
1 | 1. 只输入脚本名字 |
从上面的结果中我们不难发现:
- 反引号里面的内容会被当成命令先执行,再把结果放到里面执行。
- 在shell中如果只是单纯引用字符串来说,那么单引号和双引号没有任何区别,这点同Python
- 如果不是单纯引用字符串,比如有了反引号,或者
$,那么在单引号里面全部失效,即反引号还是它自己,美元符还是它自己。但是在双引号里面这些值还是自己。 - 不论是在Python还是在shell里面,都推荐使用单引号来把字符串括起来。
- 在windows的cmd里面,只能使用双引号来把名字中带空格的文件夹引起来。
拓展argv
C语言中,最为“标准”的main函数写法是int main(int argc, char *argv[]),而在java中是public static void main(String[] args),因为java里面的数组是有长度的,所以不需要argc。
那么第一个问题,为什么用python xxx.py和直接使用./xxx.py执行程序,这个argv是一样的呢?

我们之前学过,argv的第一个参数(也就是数组中的argv[0])应该是程序名,那么照理来说,上面的第一个程序应该是python3,但是仍然是 ./argv,那这是为什么呢?
可以通过strace命令来帮助查看对应的调用:
1 | execve("/usr/local/bin/python3", ["python3", "args.py"], [/* 25 vars */]) = 0 |
而如果我们再加入java进行对比的话:
1 | execve("/usr/bin/java", ["java", "ArgsTest", "123"], [/* 25 vars */]) = 0 |
java中的argv[0]就是123,会发现java和Python的处理方法是不一样的,即java会忽略掉字节码文件的名字,而是把参数当成是第一个参数;而在Python中,会把执行的文件名字作为第一个参数。