一、前言
1、Shell语言的特点
Shell语言是指UNIX操作系统的命令语言,同时又是该命令语言的解释程序的简称。
Shell本身是一个用C语言编程的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是Shell完成的。
Shell既是一种命令语言,又是一种程序设计语言,作为命令语言,它交互式的解释和执行用户输入的命令。作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
它虽然不是Unix、Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序。建立文件并以并行的方式协调各个程序的运行。
2、Shell语言能做什么
1.自动化批量系统初始化程序(update、软件安装、时区设置、安全策略...)
2.自动化批量软件部署程序(LAMP、LNMP、Tomcat、Nginx)
3.应用管理程序(KVM、集群管理扩容、MySQL...)
4.日志分析处理程序(PV、UV、200代码、top100,grep/awk)
5.自动化备份恢复(MySQL..)
3、Shell执行方式
1)准备测试脚本
[root@bedo19c test]# vim file1.sh
echo "hello 2024"
read -p "name:" name
echo "hello $name"
2)执行方式1:bash
[root@bedo19c test]# bash file1.sh
3)执行方式2:sh
[root@bedo19c test]# sh file1.sh
3)执行方式3:.
[root@bedo19c test]# . file1.sh
4)执行方式4:source
[root@bedo19c test]# source file1.sh
二、变量
1、重复定义变量会导致什么?
[root@bedo19c home]# aa=1
[root@bedo19c home]# echo $aa
1
[root@bedo19c home]# aa="$aa"2
[root@bedo19c home]# echo $aa
12
[root@bedo19c home]# aa=${aa}3
[root@bedo19c home]# echo $aa
123
加花括号可以帮助解释器识别变量的边界,比如:
for skill in Ada Coffe Action Java; do
echo "I am good at ${skill}Script"
done
2、通过set命令查看所有变量,管道命令查看指定变量:set | grep aa
3、交互变量
read从键盘读入变量值
赋值方式:read 变量名
示例:
4、只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
下面的例子尝试更改只读变量,结果报错:
python@ubuntu:~/shell$ myUrl="http://www.google.com"
python@ubuntu:~/shell$ readonly myUrl
python@ubuntu:~/shell$ myUrl="http://www.baidu.com"
-bash: myUrl: 只读变量
5、删除变量
使用 unset 命令可以删除变量,但不能删除只读变量:
#!/bin/sh
myUrl="http://www.baidu.com"
unset myUrl
echo $myUrl
6、变量类型
运行shell时,会同时存在三种变量:
1)局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
2)环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
export 后面接的是环境变量
想使变量在当前用户登录后一直生效,可以将变量放到~/.bash_profile
想使变量在所有用户登录后一直生效,可以将变量放到/etc/profile
3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
4)位置变量
5)预定义变量
$0 脚本名
$* 所有的参数、 $#参数的个数、$? 上一个程序的返回值(0是成功,非0失败)
$$ 程序的PID
7、设置变量需要注意的
变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样,同时,变量的命名需要遵循以下原则:
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
中间不能有空格,可以使用下划线_
不能使用标点符号
不能使用bash里的关键字,可用help命令查看保留关键字
起变量名,请使用五个字母以上
8、脚本案例-编写自动创建用户并设置初始密码的脚本
#!/bin/bash
read -p "请输入新用户名称:" name
useradd $name
echo "123456" | passwd --stdin $name &>/tmp/test/
echo "$name 创建成功,密码是123456"
运行脚本创建tom用户
[root@bedo19c test]# sh useradd.sh
请输入新用户名称:tom
useradd.sh:行4: /tmp/test/: 是一个目录
tom 创建成功,密码是123456
[root@bedo19c ~]# id tom
uid=54322(tom) gid=54331(tom) 组=54331(tom)
使用变量方式写这个脚本
三、基本运算符
1、算数运算符
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val"
两点注意:
- 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2。
- 完整的表达式要被 ` ` 包含,这个字符是反引号在 Esc 键下边。
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
注意:
- 乘号(*)前边必须加反斜杠
\
才能实现乘法运算; - 在 MAC 中 shell 的 expr 语法是:$((表达式)),此处表达式中的 “*” 不需要转义符号
\
。
2、数值比较运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。在shell中进行比较时,结果为0代表真,为1代表假。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 解释 | 说明 | 举例 |
---|---|---|---|
-eq | equals等于 | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | no equals不等于 | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | greater than 大于 | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | less than小于 | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | greater equals大于等于 | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | less equals小于等于 | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
[root@bedo19c test]# [ 20 -gt 1 ]
[root@bedo19c test]# echo $?
0
[root@bedo19c test]# [ 20 -lt 1]
-bash: [: 缺少 `]'
[root@bedo19c test]# [ 20 -lt 1 ]
[root@bedo19c test]# echo $?
1
[root@bedo19c test]# [ 20 -eq 20 ]
[root@bedo19c test]# echo $?
0
[root@bedo19c test]# [ 20 -ge 20 ]
[root@bedo19c test]# echo $?
0
[root@bedo19c test]# [ 20 -ge 21 ]
[root@bedo19c test]# echo $?
1
3、字符串运算符
下表列出了常用的字符串运算符,假定变量 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。 |
$ | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
4、逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
5、布尔运算符
下表列出了常用的布尔运算符,假定变量 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。 |
6、文件测试运算符
操作符 | 说明 | 备注 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | block |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | char |
-d file | 检测文件是否是目录,如果是目录,则返回 true。 | directory |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | file |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | set Group ID |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | name pipe |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | Set User ID |
-r file | 检测文件是否可读,如果是,则返回 true。 | readonly |
-w file | 检测文件是否可写,如果是,则返回 true。 | writeable |
-x file | 检测文件是否可执行,如果是,则返回 true。 | excecutable |
-s file | 检测文件是否不为空(文件大小是否大于0),不为空返回 true。 | space |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | exist |
-S file | 检测文件是否 socket | socket |
-L file | 检测文件是否存在并且是一个符号链接 | link |
实例:
cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
[root@bedo19c test]# [ -e file1.sh ] ;echo $?
0
[root@bedo19c test]# [ -e file21.sh ] ;echo $?
1
[root@bedo19c test]# [ -b file1.sh ] ;echo $?
1
四、Shell流程控制
1.if else判断语句
if condition
then
command1
command2
...
commandN
fi
写成一行(适用于终端命令提示符):
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
if else 语法格式:
if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else 语法格式:
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
案例:
2.for循环
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
写成一行:
for var in item1 item2 ... itemN; do command1; command2… done;
案例
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
输出结果
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
3.while循环
while condition
do
command
done
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
案例
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
4.无限循环
while :
do
command
done
或者
while true
do
command
done
或者
for (( ; ; ))
5.until 循环
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。
until 语法格式:
until condition
do
command
done
condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。
以下实例我们使用 until 命令来输出 0 ~ 9 的数字:
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
结果
0
1
2
3
4
5
6
7
8
9