1.数据类型
1.1.字符串类型
# 数据类型默认为字符串类型
# 要加$符合才能获取变量的值,不然就是一个字符n
[root@test ~]# n=10+30
[root@test ~]# echo n
n
[root@test ~]# echo $n
10+30
# 字符串的定义,可以使用单引号,也可以使用双引号,也可以不用引号
# 在单引号里面引用变量会识别成普通字符串
# 在双引号里面可以应用变量的值
# 挨着写就是字符串的拼接
[root@test ~]# echo test$n
test10+30
[root@test ~]# echo 'test$n'
test$n
[root@test ~]# echo "test$n"
test10+30
# 字符串的截取
[root@test ~]# str1="abcdefghijkl"
[root@test ~]# echo ${str1:0:4} # 截取前四个
abcd
[root@test ~]# echo ${str1:0-9} # 截取后九个
defghijkl
[root@test ~]# echo ${str1:1} # 从第二个开始截取到最后一个,索引从0开始
bcdefghijkl
[root@test ~]# echo ${str1:0-9:4} # 从倒数第九个字符开始截取4个字符
defg
[root@test ~]# line=`head -n1 /etc/passwd` # 把passwd文件第一行赋值给line变量
[root@test ~]# echo $line
root:x:0:0:root:/root:/bin/bash
[root@test ~]# line=$(head -n1 /etc/passwd)
[root@test ~]# echo $line
root:x:0:0:root:/root:/bin/bash
[root@test ~]# echo ${line#*:} # 从左向右截取第一个:后的字符
x:0:0:root:/root:/bin/bash
[root@test ~]# echo ${line##*:} # 从左向右截取最后一个:后的字符
/bin/bash
[root@test ~]# echo ${line%:*} # 从右向左截取第一个:后的字符
root:x:0:0:root:/root
[root@test ~]# echo ${line%%:*} # 从右向左截取最后一个:后的字符
root
[root@test ~]# echo ${#line} # 字符串长度
31
1.2.数值类型
数值的运算:
[root@test ~]# a=10
[root@test ~]# b=20
第一种:$(( 表达式 ))
[root@test ~]# echo $(($a+$b))
30
第二种:$[ 表达式 ]
[root@test ~]# echo $[$a+$b]
30
第三种:expr 表达式
[root@test ~]# expr $a + $b
30
第四种:交给bc计算 -- bc可以对整数和小数进行计算,前面三种都不能进行小数运算
[root@test ~]# echo $a + $b |bc
30
[root@test ~]# echo 10.1 + 20.9|bc
31.0
1.3.数组类型
一维数组定义: 使用圆括号,中间以空格作为分隔符
[root@test ~]# lst=(aa bb cc dd ee ff)
# 默认输出索引为0的值
[root@test ~]# echo $lst
aa
# 输出所有值
[root@test ~]# echo ${lst[*]}
aa bb cc dd ee ff
[root@test ~]# echo ${lst[@]}
aa bb cc dd ee ff
# 切片0-2 前闭后开区间 跟字符串切片类型
[root@test ~]# echo ${lst[@]:0:2}
aa bb
# 输出元素个数
[root@test ~]# echo ${#lst[@]}
6
# 修改数组
[root@test ~]# lst[2]="xx"
[root@test ~]# echo ${lst[@]}
aa bb xx dd ee ff
# 删除元素,只是元素,空间还在,赋值即可显示。
[root@test ~]# unset lst[2]
[root@test ~]# echo ${lst[@]}
aa bb dd ee ff
[root@test ~]# echo ${#lst[@]}
5
# 输出索引
[root@test ~]# echo ${!lst[@]}
0 1 3 4 5
[root@test ~]# lst[2]=666
[root@test ~]# echo ${lst[@]}
aa bb 666 dd ee ff
2. read命令
[root@test shell-test]# read -p "please input an number:" num1
please input an number:100
[root@test shell-test]# echo $num1
100
[root@test shell-test]# read -p "please input an number:" num1 num2 num3
please input an number:100 200 300
[root@test shell-test]# echo $num1
100
[root@test shell-test]# echo $num2
200
[root@test shell-test]# echo $num3
300
# 没有赋值的就是空
[root@test shell-test]# read -p "please input an number:" num1 num2 num3
please input an number:100
[root@test shell-test]# echo $num1
100
[root@test shell-test]# echo $num2
[root@test shell-test]# echo $num3
# read命令, 你输多少最后都能接收,跟位置变量不一样,位置变量是固定的
[root@test shell-test]# read -p "please input an number:" num1 num2 num3
please input an number:100 200 300 400 500
[root@test shell-test]# echo $num1
100
[root@test shell-test]# echo $num2
200
[root@test shell-test]# echo $num3
300 400 500
3. 结构语句
3.1.常用判断
常用判断:
[ -d FILE ] 如果 FILE 存在且是一个目录则返回为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则返回为真。
字符串判断:
[ -z STRING ] 如果STRING的长度为零则返回为真,即空是真
[ -n STRING ] 如果STRING的长度非零则返回为真,即非空是真
[ STRING1 ] 如果字符串不为空则返回为真,与-n类似
[ STRING1 == STRING2 ] 如果两个字符串相同则返回为真
[ STRING1 != STRING2 ] 如果字符串不相同则返回为真
[ STRING1 < STRING2 ] 如果 “STRING1”字典排序在“STRING2”前面则返回为真。
[ STRING1 > STRING2 ] 如果 “STRING1”字典排序在“STRING2”后面则返回为真。
整数值判断
[ INT1 -eq INT2 ] INT1和INT2两数相等返回为真 ,=
[ INT1 -ne INT2 ] INT1和INT2两数不等返回为真 ,<>
[ INT1 -gt INT2 ] INT1大于INT2返回为真 ,>
[ INT1 -ge INT2 ] INT1大于等于INT2返回为真,>=
[ INT1 -lt INT2 ] INT1小于INT2返回为真 ,<
[ INT1 -le INT2 ] INT1小于等于INT2返回为真,<=
逻辑判断 EXPR 判断语句
[ ! EXPR ] 逻辑非,如果 EXPR 是false则返回为真。
[ EXPR1 -a EXPR2 ] 逻辑与,如果 EXPR1 and EXPR2 全真则返回为真。
[ EXPR1 -o EXPR2 ] 逻辑或,如果 EXPR1 或者 EXPR2 为真则返回为真。
[ ] || [ ] 用OR来合并两个条件
[ ] && [ ] 用AND来合并两个条件
3.2.判断语句
if 条件
then
执行语句
fi
if 条件
then
执行语句
else
执行语句
fi
if [ command ];then
符合该条件执行的语句
elif [ command ];then
符合该条件执行的语句
else
符合该条件执行的语句
fi
3.3.循环语句
语法一:
for 变量 in 值1 值2
do
循环执行语句
done
语法二:
#for ((i=0;i<3;i++))
for ((初始化变量; 结束循环的条件; 运算))
do
循环执行的语句
done
while循环
while read line # 读文件,一行一行读
do
循环执行语句
done <md.txt 读取文件名
while 条件:
do
循环执行语句
done
也支持break ,continue
[root@test shell-test]# cat md.sh
#!/bin/bash
while read grade class student
do
if [ $grade != "年级" ];then
for i in $student
do
echo "$i同学是$grade$class的"
done
fi
done <md.txt
[root@test shell-test]# cat md.txt
年级 班级 学生
大一 信科1班 张三 李四
研1 农信2班 天天 向上 王二 刘四
大二 信科2班 小美
[root@test shell-test]# bash md.sh
张三同学是大一信科1班的
李四同学是大一信科1班的
天天同学是研1农信2班的
向上同学是研1农信2班的
王二同学是研1农信2班的
刘四同学是研1农信2班的
小美同学是大二信科2班的
这个代码也行
#!/bin/bash
tail -n +2 md.txt|while read grade class student
do
for i in $student
do
echo "${i}同学是${grade}${class}的"
done
done
3.4. case 语句
case $变量名 in
条件1)
执行语句一
;;
条件2)
执行语句二
;;
esac
[root@test shell-test]# cat user.sh
#!/bin/bash
while true
do
echo "1.新增用户"
echo "2.删除用户"
echo "3.退出!"
read -p "请输入你的选择:" options
case $options in
1)
read -p "请输入用户名:" username
id $username &>/dev/null && echo "用户已存在" || (useradd $username; echo "用户新建成功")
;;
2)
read -p "请输入用户名:" username
id $username &>/dev/null && userdel -r $username && echo "用户删除成功" || echo "没有这个用户"
;;
3)
echo "退出!"
exit
;;
*)
echo "选择错误!"
;;
esac
done
[root@test shell-test]# bash user.sh
1.新增用户
2.删除用户
3.退出!
请输入你的选择:1
请输入用户名:gala8
用户新建成功
1.新增用户
2.删除用户
3.退出!
请输入你的选择:2
请输入用户名:gala8
用户删除成功
1.新增用户
2.删除用户
3.退出!
请输入你的选择:1'^H
选择错误!
1.新增用户
2.删除用户
3.退出!
请输入你的选择:1
请输入用户名:gala
用户已存在
1.新增用户
2.删除用户
3.退出!
请输入你的选择:3
退出!