文章目录
简介
- 在计算机科学中,Shell俗称壳(用来区别于核),是指“为使用者提供操作界面”的软件(命令解析器)。它类似于DOS下的command.com和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序。
- 简单来说“Shell编程就是对一堆Linux命令的逻辑化处理”。
Shell编程入门例子
1、新建一个文件 helloworld.sh:touch helloworld.sh,扩展名为 sh(sh代表Shell,扩展名并不影响脚本执行,见名知意就好);
2、给脚本赋予执行权限:chmod +x helloworld.sh;
3、使用 vim 命令编辑helloworld.sh文件:vim helloworld.sh(vim 文件------>进入文件----->命令模式------>按i进入编辑模式----->编辑文件 ------->按Esc进入底行模式----->输入:wq/q! (输入wq代表写入内容并退出,即保存;输入q!代表强制退出不保存);
4、运行脚本:./helloworld.sh 或 /bin/bash helloworld.sh。
变量
规则
- 变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样;
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头;
- 命名中间不能有空格,可以使用下划线(_);
- 命名不能使用标点符号;
- 命名不能使用bash里的关键字(可用help命令查看保留关键字)。
使用变量
变量名外面的花括号是可选的,加不加都可以,加花括号是为了帮助解释器识别变量的边界。
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
删除变量
- 使用 unset 命令可以删除变量;
- 变量被删除后不能再次使用;
- unset 命令不能删除只读变量。
变量类型
- 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量;
- 环境变量:所有的程序(包括shell启动的程序),都能访问环境变量,有些程序需要环境变量来保证其正常运行(必要的时候shell脚本也可以定义环境变量);
- 根据用途可以分为四种变量:
①内部变量、②用户自定义变量、③环境变量、④参数变量 (变量的划分,每本书都不相同)
部分常用的内部变量
内部变量 | 解释 |
---|---|
$0 | 当前脚本名称 |
$n | 传递给脚本或函数的参数,n为数字,表示第几个参数 |
$# | 传递给脚本或函数的参数个数 |
$* | 传递给脚本或函数的所有参数 |
$@ | 传递给脚本或函数的所有参数 |
$? | 上一个命令的退出状态,或函数的返回值 |
$! | 后台运行的最后一个进程的ID号 |
$$ | 当前Shell进程的ID号 |
$* 和 $@ 的区别
- 当它们被双引号包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;
- “$@” 会将各个参数分开,以$1, $2, … , $n 的形式输出所有参数。
字符串
字符串可以用单引号,也可以用双引号,也可以不用引号。
单引号和双引号的区别
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用;
- 双引号里可以有变量;
- 双引号里可以出现转义字符,也可以出现双引号,实现字符串拼接。
拼接字符串
获取字符串长度
- 使用“$#”获取;
- 使用“expr length”获取(使用 expr 命令时,表达式中的运算符左右必须包含空格,如果不包含空格,将会输出表达式本身。);
查找子字符串的位置
脚本中表达式使用的是反引号(`) ,而不是单引号( ')。
截取字符串
- “#” :删除左边字符,保留右边字符;(从左开始,匹配第一个符合要求的)
- “##” :删除左边字符,保留右边字符;(从左开始,匹配到最后一个符合要求的)
- “%”:删除右边字符,保留左边字符;(从右开始,匹配第一个符合要求的)
- “%%”:删除右边字符,保留左边字符;(从右开始,匹配第一个符合要求的)
- “:n”:从左边下标为n的字符开始,一直到结束;(下标n从0开始)
- ":n:m ":从左边下标为n的字符开始,字符的个数为m;(下标n从0开始)
- “:0-n”:从右边第n个字符开始,一直到结束;(n从1开始)
- :“0-n:m”:从右边第n个字符开始,字符的个数为m。(n从1开始)
数组
定义数组
格式:数组名=(值1 值2 … 值n)
注意:数组元素用"空格"符号分割开,可以不使用连续的下标,而且下标的范围没有限制。
读取数组
- $ {数组名[下标]};
- $ {数组名[@]};(读取所有元素)
- $ {数组名[*]}。(读取所有元素)
获取数组长度
- $ {#数组名[下标]};(取得数组单个元素的长度)
- $ {#数组名[@]};(取得数组元素的个数)
- $ {#数组名[*]}。(取得数组元素的个数)
注解
- 单行注解:以 # 开头的行就是注释,会被解释器忽略;
- 多行注解:EOF 也可以使用其他符号。
运算符
数学运算符
假定变量 a 为 2,变量 b 为 4,乘号(*)前边必须加反斜杠()才能实现乘法运算。
运算符 | 解析 |
---|---|
+ | 加法,expr $a + $b 结果为 6。 |
- | 减法,expr $a - $b 结果为 -2。 |
* | 乘法,expr $a \* $b 结果为 8。 |
/ | 除法,expr $b / $a 结果为 2。 |
% | 取余,expr $b % $a 结果为 0。 |
% | 赋值,a=$b 将把变量 b 的值赋给 a。 |
% | 相等,[ $a == $b ] 返回 false。 |
% | 不相等,[ $a != $b ] 返回 true。 |
关系运算符
假定变量 a 为 2,变量 b 为 4。
运算符 | 解析 |
---|---|
-eq | 检测两个数是否相等,相等返回 true,[ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true,[ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true,[ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true,[ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true,[ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true,[ $a -le $b ] 返回 true。 |
布尔运算符
假定变量 a 为 2,变量 b 为 4。
运算符 | 解析 |
---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true, [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true,[ $a -lt 4 -o $b -gt 8 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true,[ $a -lt 4 -a $b -gt 8 ] 返回 false。 |
逻辑运算符
假定变量 a 为 2,变量 b 为 4。
运算符 | 解析 |
---|---|
&& | 逻辑与,[[ $a -lt 8 && $b -gt 8]] 返回 false |
|| | 逻辑或,[[ $a -lt 8|| $b -gt 8]] 返回 true |
字符串运算符
假定变量 a 为 “hello”,变量 b 为 “world”
运算符 | 解析 |
---|---|
= | 检测两个字符串是否相等,相等返回 true,[ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true,[ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true,[ -z $a 返回 false。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true,[ -n "$a" ] 返回 true。 |
$ | 检测字符串是否不为空,不为空返回 true,[ $a ] 返回 true。 |
文件检测运算符
运算符 | 解析 |
---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 |
-r file | 检测文件是否可读,如果是,则返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 |
控制语句
if条件语句
条件成立(true),执行对应的控制块。
格式:condition1为条件、command为操作
if condition1
then
command1
elif condition2
then
command2
else
command3
fi
for条件循环语句
条件成立(true),一直循环。
格式:
for var in a1 a2 ... an
do
command1
command2
...
done
------------------------
for((i=1; i<= n;i++))
do
command1
done
while条件循环语句
条件成立(true),一直循环。
格式:
while condition
do
command
done
until循环语句
执行一系列命令直至条件为 true 时停止。
格式:
until condition
do
command
done
case选择语句
与其他语言中的 switch … case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 “;;” 表示 break,即执行结束.
格式:
case in 值
模式1)
command1
command2
...
;;
模式2)
command3
command4
...
;;
esac
select语句
一般用于选择菜单的创建,可以配合PS3来做菜单的打印输出信息。
select 值 in 值1 值2 ...
do
command
done
break和continue
- break:允许跳出所有循环(终止执行后面的所有循环);
- continue:不会跳出所有循环,仅仅跳出当前循环。
函数
- 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数;
- 参数返回,可以显示加:return 返回;如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)。
格式:中括号([])表示可选。
[function] 函数名[()]
{
操作;
[return i;]
}