1.变量
1.1 变量的定义与使用
定义形如:class_name=“value”
使用形如:echo $class_name
在使用变量的时候一定需要在变量名前面添加一个$符号,该要求在其他语言也存在(例如PHP)
变量名的规范:
注意,变量名后面的等号左右不能有空格!
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线“_”
不能使用标点符号。
不能使用bash里的关键字。
**例子:**使用变量改写test.sh脚本。
关于单双引号的问题:
双引号能够识别变量,双引号能够转义(例如* 默认为通配符,但是加个斜杠,\*,就代表转义)
单引号是不能识别变量,只会原样输出,单引号不能够转义的
**例子:**定义一个变量,输出当前时间,要求格式为“年-月-日 时:分:秒”。
注意:反引号(esc键下方的那个键),当在脚本中需要执行一些指令并且将执行结果赋值给变量的时候需要使用“反引号”!
1.2 只读变量
语法:readonly 变量名
例子:定义变量a并且其值为10,随后设置其为只读变量,再去尝试重新赋值
1.3 接受用户输入
语法:read -p 提示信息 变量名
例子:编写一个脚本 test6.sh,要求窒息感之后提示用户输入文件的名称(路径),然后自动为用户创建该文件
1.4 删除变量
语法:unset 变量名
例子:定义变量b=20,再输出b的值,然后删除b,最后再输出b
2.条件判断语句
语法1:
if condition
then
command1
command2
…
fi
单行写法(一般在命令行):if [ condition ];then command;fi
语法2:
if conditon
then
command1
command2
…
else
command
fi
语法3:
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
3.运算符
在shell中,运算符和其他编程语言一样,常见的有算术运算符、关系运算符、逻辑运算符、字符串运算符、文件测试符等。
3.1算术运算符
下表列出了常用的算术运算符,假定变量a为10,变量b为20:
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | `expr $a + $b`,结果为30 |
- | 减法 | `expr $a - $b`,结果为-10 |
* | 乘法 | `expr $a \* $b`,结果为200 |
/ | 除法 | `expr $a / $b`,结果为200 |
% | 取余 | `expr $a % $b`,结果为200 |
= | 赋值 | a=$b,将变量b的值赋给a |
== | 相等。用于比较两个数字,相同则返回true。 | [ $a == $b ],返回false |
!= | 不相等。用于比较两个数字,不相同则返回true。 | [ $a != $b ],返回true |
注意:条件表达式要放在方括号之间,并且要有炯哥,例如[$a==$b]是错误的,必须写成[ $a == $b ]
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如awk和expr,expr最常用
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
例如,两个数相加(注意使用的是反引号 ` 而不是单引号 ’ ):
#!/bin/bash
val=`expr 2 + 2`
echo “两数之和为:$val”
两点注意:
表达式和运算符之间要有空格,例如2+2是不对的,必须写成 2 + 2,这与我们熟悉的多数编程语言不一样
完整的表达式要被``包含,注意这个字符不是常用的单引号,而是反引号。
3.2关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量a=10,变量b=20:
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回true | [ $a -eq $b ],返回false |
-ne | 检测两个数是否相等,不相等返回true | [ $a -ne $b ],返回true |
-qt | 检测左边的数是否大于右边的,如果是,则返回true | [ $a -gt $b ],返回false |
-lt | 检测左边的数是否小于右边的,如果是,则返回true | [ $a -lt $b ],返回true |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回true | [ $a -ge $b ],返回false |
-le | 检测左边的数是否小于等于右边的,如果是,则返回true | [ $a -le $b ],返回true |
-eq:equal
-ne:not equal
-gt:greater than
-lt:less than
-ge:great than or equal
-le:less thab or equal
例子:使用a=10,b=20实现本例子
3.3逻辑运算符
下表列出了常用的布尔运算符,假定变量a=10,变量b=20:
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为true则返回false,否则返回true | [ ! false ],返回true |
-o | 或运算,有一个表达式为true则返回true | [ $a -lt 20 -o $b -gt 100 ],返回true |
-a | 与运算,两个个表达式都为为true才返回true | [ $a -lt 20 -a $b -gt 100 ],返回false |
3.4字符串运算符
下表列出了常用的字符串运算符,假定变量a为“abc”,变量b为“efg”:
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回true | [ $a = $b ],返回false |
!= | 检测两个字符串是否相等,不相等返回true | [ $a != $b ],返回true |
-z | 检测字符串长度是否为0,为0返回true | [ -z $a ],返回false |
-n | 检测字符串长度是否为0,不为0返回true | [ -n $a ],返回true |
str | 检测字符串是否为空,不为空返回true | [ $a ],返回true |
例子:
将上述语法验证一下:
3.5文件运算符(重点)
文件测试运算符用于检测Unix和Linux文件的各种属性。
属性检测如下
运算符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回true | [ -b $file ],返回false |
-c file | 检测文件是否是字符设备文件,如果是,则返回true | [ -c $file ],返回false |
-d file | 检测文件是否是目录,如果是,则返回true | [ -d $file ],返回false |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回true | [ -f $file ],返回true |
-g file | 检测文件是否设置了SGID位,如果是,则返回true | [ -g $file ],返回false |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回true | [ -k $file ],返回false |
-p file | 检测文件是否是有名管道,如果是,则返回true | [ -p $file ],返回false |
-u file | 检测文件是否设置了SUID位,如果是,则返回true | [ -u $file ],返回false |
-r file | 检测文件是否是可读,如果是,则返回true | [ -r $file ],返回true |
-w file | 检测文件是否可写,如果是,则返回true | [ -w $file ],返回true |
-x file | 检测文件是否可执行,如果是,则返回true | [ -x $file ],返回true |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回true | [ -s $file ],返回true |
-e file | 检测文件(包括目录)是否存在,如果是,则返回true | [ -e $file ],返回true |
例子:测试上述一些比较重要/常用运算符的效果:
注意:权限几个判断,如果只有一个部分符合,则认为是有权限的。
shell脚本附带选项(重点)
问题描述:在Linux shell中如何处理 tail -n 10 access.log 这样的命令行选项?
步骤:
调用tail指令
系统内核把后续选项传递给tail
tail先去打开指定的文件
取出最后10行
自己写的shell是否也可以向内置命令一样传递一些选项呢?
可以的,传递方式与上述描述是一样的,关键是怎么接受。例如:
传递:
#./test.sh a b c
接收:
在脚本中可以用“$1”来表示a,“$2”来表示b,“$3”来表示c
,依次类推。
接收可以用“$”加上选项对应的序号即可。
测试:编写test13.sh,传递a,b,c,输出其值
其实:$1,$2是变量,$0是脚本名。
例子:创建自定义命令“user”,可以直接执行,要求该指令湖北以下语法和功能:
a.#user -add 用户名 【添加用户】
b.#user -del 用户名 【删除用户及其家目录】
在~/.bashrc中添加一个一个别名,然后su,切换一下,使得别名生效