本文中,我们将分享多个高效可靠的 bash 脚本的实用技巧,它们包括如何命令文件、如何命名变量而不随意命名、如何使用数据和函数,如何运行脚本和测试脚本。
1.文件名
虽然在linux中有没有文件名后缀都可以,但为了区别其他文件,特别要标明bash代码,最好后.sh后缀。
文件名虽支持中文,为了国际交际,不要用汉语拼音,简单英文单词可网上搜一下。
为了表达文件功能、作用等,可采用蛇形命令法、大驼峰命令法、小驼峰命令法等。最好形成一种习惯。
2.头部编写
第一行按要求正确编写:
#!/bin/bash
第二行最好是空行
第三行及后几行可注明代码作者、代码主要功能或作用、编写日期等。
3.注意空行
空行不是多此一举。主要作用是区分代码功能、自定义函数、变量、主函数等。把空行作为功能分隔符。
4.多添加注释
注释的作用无须咨疑。为个人代码作标志,也方便其他人理解阅读脚本的不同部分所做的工作。
特别是初学者,练习对每一行代码作注释,会提高个人代码阅读能力,进而提高编程水平,这是基本功,应多做练习。
这是不仅可应用于shell脚本程序中,也可用在其他所有类型的编程中的一种推荐做法。
单行注释用#号来定义。为清晰,可在#与注释内容间添加一个空格。用一个#与用两个##相同。
单行注释可以放在代码前一行,独立成行。也可以放在代码右边单独说明此行代码的作用或目的。
多行注释在bash代码中用的不多,可用在需要注释的每行行首添加#。
如想添加多行注释,bash也定义了格式:
:<<!
多行注释内容
!
其中符号!可用@$%|等替换(不能用#替换,原因很明显,#已用作单行注释)。
5.循环实现
常用循环是for循环,有两种常用写法:一是C语言风格,另一是for * in ***
while循环也是常用循环,主要用于不确定的循环次数的情况。写法有许多变化,掌握循环三要素十分重要:循环起点,循环条件,终止条件。
6.条件判断
条件判断有两种写法:test与[ ]。建议使用[ ],一定条件下可考虑[[ ]]。
7.多条件编写
可用&& ||连接,也可用-a -o连接。注重二者的使用差别。
8.符号运用
学会使用单括号()及双括号(( ))、方括号及双方括号[[ ]]。大括号C语言用的多,bash用缩进来表达代码块,大括号用的不多。
!是非运算,有时与not功能相同。
使用双引号来引用变量
当变量引用时(目的是使用一个变量的值)用双引号有助于防止由于空格导致单词分割开和由于识别和扩展了通配符而导致的不必要匹配。
看看下面的例子:
=和==的区别
字符串比较时用 = 或者 ==
变量赋值时只能用=,而不能用 ==。如用==,是另外的含义
一般规定:=是变量赋值 ==是判断是否相等
经测试:
字符串比较时可用=或者==
数字比较时也可以用=或==
命令替换
命令替换是用这个命令的输出结果取代命令本身。用 $(command) 而不是反引号`command`来做命令代换。
这种做法也是 shellcheck tool (可针对 shell 脚本显示警告和建议)所建议的。
readonly声明静态变量
静态变量不会改变;它的值一旦在脚本中定义后不能被修改:
环境变量
环境变量用大写字母命名,而自定义变量用小写
所有的 bash 环境变量用大写字母去命名,因此用小写字母来命名你的自定义变量以避免变量名冲突:
9.函数编写
在脚本中使用函数,减少代码重复。特别是有些代码重复率高时,更应该编写函数。
除了非常小的脚本(只有几行代码),总是记得用函数来使代码模块化且使得脚本更可读和可重用。
写函数的语法如下所示:
写成单行代码时,每个命令后要用终止符号:
sum_two(){ a=$1; b=$2; sum=$a+$b; return $sum;}
定义函数时,可加关键字function,也可以省略。
10.数组运用
bash只支持一维数组,但参数个数没有限制。
如声明一个数组:
declare -a array
a.定义数组
(1) 使用[]操作符
age[0]=18
age[1]=19
(2) 使用()直接赋值
age=(18 19 20)
# 或
age=([0]=18 [1]=19 [2]=20)
(3)从文件中读取数组
cat test.txt
zhang3
lisi
zhaoliu
chener
wuda
# 将每一行读取为数组的一个元素
test=($(cat test.txt))
b.读取数组
(1) 数组取值
bash使用[]操作符和基于0的下标来取值
(2)数组长度(元素个数)
使用"@"这个特殊的下标,可以将数组扩展成列表,然后就可以使用bash中的获取变量长度的操作符"#"来获取数组中元素的个数:
age5=(18 19 20)
echo ${#age5[@]}
# 打印
# 3
11.执行文件方式
三种执行方式,推荐第一种,其他两类,可以测试时使用。
a.为文件添加执行权限,执行
如准备运行test_sum.sh脚本文件,首先加权限:
chmod u+x test_sum.sh
加权限后可用ll查看
ll test_sum.sh
执行时,可用相对路径 ./test_sum.sh
./的意思是说在当前的工作目录下执行test_sum.sh。如果不加上./,bash可能会响应找到不到hello.sh的错误信息。因为目前的工作目录(/home/zhang3)可能不在执行程序默认的搜索路径之列,也就是说,不在环境变量PATH的内容之中。查看PATH的内容可用echo $PATH命令。现在的/home/zhang3就不在环境变量PATH中的,所以必须加上./才可执行。
也可用绝对路径/home/zhang3/test_sum.sh
b.直接用bash(或sh)命令,把文件名作为参数
bash test_sum.sh
sh test_sum.sh
c.直接用命令source(或 .)
source test_sum.sh
. test_sum.sh
.后面要有空格
此时用source命令和.,不能用相对路径。文件名可以作为命令参数,而加上./将产生错误。这是与bash(sh)命令的重大不同。
当脚本文件中有不可执行的命令或代码时,将退出整个bash,而不是仅仅退出当前shell。
修改脚本代码后,可以用绝对路径执行,而用相对路径仍然退出终端(相当于退出整个bash进程)。
12.调试
如果你在写有数千行代码的bash脚本,排错可能变成噩梦。为了在脚本执行前易于修正一些错误,要进行一些调试。
编写代码都不能保证不出问题,如何检查,如何调试十分重要。学习bash命令的几个常用选项,方便调试代码:
a. -x 显示执行过程
当 Bash 声明变量时使脚本退出
Bash 也可能会使用能导致引起逻辑错误的未声明的变量。因此用下面行的方式去通知 bash 当它尝试去用一个未声明变量时就退出脚本执行:
-u 遇到未定义的变量,退出程序
当运行失败时使脚本退出
有时即使某些命令运行失败,bash可能继续去执行脚本,这样就影响到脚本的其余部分(会最终导致逻辑错误)。用下面的行的方式在遇到命令失败时来退出脚本执行:
-e遇到程序语法错误,退出程序
在执行脚本文件时,加-v选项,将执行过的脚本命令打印到屏幕:
在执行脚本文件时,加-n选项,仅检查脚本国的语法错误。
b.打印命令使用
在代码的关键处,可添加打印输出,调试代码成功后,可把部分打印输出命令注释掉。
这是一个好习惯!
小结
bash使用中,有许多规定,也有相当多的使用技巧,只有多加学习与训练,才能真正掌握。