Linux系统Shell脚本语言之反引号、单引号以及双引号的区别

内容分享7小时前发布
1 0 0

双引号能解析变量,单引号原样输出,反引号却容易搞混。

Linux系统Shell脚本语言之反引号、单引号以及双引号的区别

昨天晚上写了个脚本,想把服务器上的数据用FTP自动备份一下。结果运行完发现,文件一个都没传过去,日志里还一直在报错说“找不到文件”。心里挺纳闷的,路径明明是对的,怎么会找不到?我一直以为是哪里拼接错了,就从头到尾一行行看,折腾了快两个小时,最后才发现问题出在引号上。

Linux的Shell脚本看着简单,但有三个符号真的特别容易搞混——单引号、双引号和反引号。它们长得不像,但在键盘上的确 容易按错,尤其是反引号,就在Esc键下面,和撇号离得太近了。我这次就是反引号写成单引号了,导致命令没执行,变量也没替换出来。

先说单引号。这个最简单,也最老实。只要用单引号把一段内容括起来,不管里面是什么,统统原样输出。列如我定义一个变量叫filename=”backup_2025.tar.gz”,然后写echo '$filename',结果打出来的就是$filename这几个字符,而不是真实文件名。由于它啥也不解释,看见啥就输出啥,变量不起作用,命令也不执行。

Linux系统Shell脚本语言之反引号、单引号以及双引号的区别

这在某些情况下挺有用的。列如你要打印一段警告信息,里面带了$或者`这种符号,你又不想让系统去执行什么动作,那就用单引号包住,保证万无一失。但坏处也明显,太死板了,不灵活。你要是在里面想用变量,那就白搭。

再说双引号。这个就机智多了。它允许变量解析,也能执行命令替换。还是上面那个例子,如果改成echo “$filename”,系统就会先把$filename换成真实的值,再输出backup_2025.tar.gz。这样你在拼接路径、组合命令的时候就方便多了。

而且双引号里还能嵌套命令。列如我想输出当前时间,可以写echo “目前时间是:$(date)”。它会自动执行date命令,把结果塞进去。包括用反引号也行,echo “目前时间是:`date`”效果一样。不过目前一般推荐用$(date),由于括号更清晰,嵌套的时候不容易乱。

Linux系统Shell脚本语言之反引号、单引号以及双引号的区别

不过要注意的是,双引号虽然能解析变量和命令,但它对空格处理比较严格。如果你变量里有空格,不用引号包住的话,shell可能会把它当成多个参数处理。所以保险起见,变量替换时最好都用双引号包一下,除非你明确知道不会出问题。

最让我头疼的是反引号。它的作用是命令替换。说白了,就是让系统先把引号里的内容当作命令执行一遍,然后用输出结果取代原来的位置。列如写file=`date +%Y%m%d`,这条语句就会执行date命令,生成一个类似20251227这样的日期字符串,然后赋值给file变量。

我在脚本里本来是想用`date`来生成当天的文件夹名,结果手一滑写成了单引号,变成'date'。这样一来,系统就不执行命令了,直接把两个字符“date”当成了文件夹名。当然找不到路径,备份也就失败了。我还奇怪为什么路径拼出来是
/home/user/date/backup.tar.gz,而不是带日期的那个。

Linux系统Shell脚本语言之反引号、单引号以及双引号的区别

后来测试的时候才发现,反引号和$(命令)是一样的功能。但反引号有个大问题,就是它和单引号太像了。特别是在一些字体下,看屏幕看久了根本分不清。而且如果命令本身又包含反引号,那还得转义,嵌套起来特别麻烦。所以目前大家都提议用$(),看起来清楚,写起来也顺手。

还有一个细节是,反引号里如果放了个变量,列如sub=date,然后写`$sub`,理论上它会执行date命令。但实际运行时,如果变量名拼错了或者命令不存在,就会报错。而且输出结果如果有换行或多行内容,也可能影响后续处理,这些都得提前想到。

写脚本这东西,看着只是敲几行命令,但真等到出问题的时候,查起来特别费劲。一个小引号不对,就能让你折腾半天。这次的问题解决了,下次可能又是别的坑。反正我已经记住了,变量用双引号,纯文本用单引号,命令替换优先用$(),尽量别用反引号。

Linux系统Shell脚本语言之反引号、单引号以及双引号的区别

引号这事,说大不大,说小不小。用对了啥都顺,用错了就得返工。好在目前有各种编辑器能高亮显示,稍微注意点就行。不过下次再写备份脚本,我必定先测一遍路径生不生效,省得半夜被人打电话叫起来修bug。

© 版权声明

相关文章

暂无评论

none
暂无评论...