一丶概念
shell既是应用程序又是脚本语言,并且是解释型语言,不需要编译,解释一条执行一条。
shell脚本编程:将shell命令结合一些按照一定逻辑集合到一起,写一个.sh文件,实现一个或多个功能,这个脚本不用编译直接执行
创建shell脚本文件的步骤:
1. 创建一个脚本文件 touch xxx.sh
2. 将脚本权限修改为可执行 chmod 777 xxx.sh
3. 编辑内容 vi xxx.sh(可以在vscode中编辑脚本内容),第一行必须为#!/bin/bash,意思是必须用/bin/bash来执行
4. 执行脚本 ./xxx.sh 或者 bash xxx.sh
二丶shell变量
1.用户自定义变量
2.环境变量
使用命令查看系统环境变量:printenv 或者 env
export 变量名=值 临时终端有效
永久生效只需要将这个命令放到 家目录下 .bashrc 文件中,当前用户永久有效
若放到/etc/bash.bashrc 这个中间中就是所有用户永久有效
HOME: /etc/passwd文件中列出的用户主目录
PATH :shell搜索路径,就是是一系列目录,当执行命令时,linux就在这些目录下查找。
3.命令变量和命令行参数
$0或者${0}是命令行的第一个参数,也就是包含脚本名的参数./xx.sh
$1,$2...就是剩下的第二个第三个命令行参数了,以此类推
$# 所有命令行参数的个数(除了第一个命令行参数)
$@或者$* 所有命令行参数(除了第一个命令行参数)
4.预定义变量
$$ 正在执行进程的ID号
三丶功能语句
1.说明性语句
以 # 开始到该行结束,不被解释执行
#!/bin/bash 告诉操作系统使用哪种类型的shell执行此脚本文件
2.功能性语句
(1).read
功能:read从标准输入读入一行,并且赋值给后面的变量
格式:read V1 V2 V3
把读入行中的第一个单词赋值给V1变量,第二个单词赋值给V2,以此类推,把其余所有单词赋值给最后一个变量。
read -p "提示语句" 变量列表: 可以将提示语句输出,同时输入变量
(2).expr
算术运算命令expr 主要用于进行简单的整数运算,包括 +、-、*、/、% 等操作
注意:
1) 运算符左右两侧必须有空格
2) *和()必须加转义字符,\*、\( \)
3) expr语句可以直接输出运算结果
如:expr \( 12 + 3 \) \* 2
NUM=`expr \( 12 + 3 \) \* 2`:将运算结果赋值给变量
(3).test
字符串测试:
s1 = s2 测试两个字符串的内容是否完全一样
s1 != s2 测试两个字符串的内容是否有差异
-z s1 测试s1 字符串的长度是否为0
-n s1 测试s1 字符串的长度是否不为0
#s1 = s2 测试两字符串的内容是否一样
test "hello" = "world"
echo $? # 1 相等为真,不相等为假
#s1 != s2 测试字符串的内容是否有差异
test "hello" != "hello"
echo $? # 1 相等为假,不相等为真
#-z s1 测试s1字符串长度是否为0
test -z ""
echo $? # 0 字符串的长度为0,则为真
test -z "hello"
echo $? # 1 字符串有长度,则为假
#-n s1 测试s1字符串的长度是否不为空 (空的时候为假,反之为真)
test -n ""
echo $? # 1 字符串长度为空,则为假
test -n "hello"
echo $? # 0 字符串有长度,则为真
整数的测试:
a -eq b 测试a 与b 是否相等 equal
a -ne b 测试a 与b 是否不相等 not equal
a -gt b 测试a 是否大于b greater than
a -ge b 测试a 是否大于等于b greater equal
a -lt b 测试a 是否小于b litter than
a -le b 测试a 是否小于等于b litter equal
#a -eq b 测试a和b是否相等的 # equal
read A B
test $A -eq $B
echo $? # 如果两个数相等则为真,反之为假
#a -ne b 测试a和b是否不相等 # no equal
read A B
test $A -ne $B
echo $? # 如果两个数不相等则为真,反之为假
#a -gt b 测试a是否大于b # greater than
read A B
test $A -gt $B
echo $? # 如果a大于b则为真,反之为假
#a -ge b 测试a是否大于等于b # greater equal than
read A B
test $A -ge $B
echo $? # 如果a大于等于b则为真,反之为假
#a -lt b 测试a是否小于b # less then
read A B
test $A -lt $B
echo $? # 如果a小于b则为真,反之为假
#a -le b 测试a是否小于等于b # less equal then
read A B
test $A -le $B
echo $? # 如果a小于等于b则为真,反之为假
文件属性测试:
-d name 测试name 是否为一个目录
-f name 测试name 是否为普通文件
-e name 测试文件是否存在
#-d name 测试name是否是一个目录
test -d 路径
echo $? # 如果name是目录则为真,反之为假
#-f name 测试name是否是一个普通文件
test -f 路径
echo $? # 如果name是普通文件则为真,反之为假
#-e name 测试文件是否存在
test -e 路径
echo $? # 如果文件或者目录存在则为真,反之为假
3.结构性语句
(1).if语句
基本结构: if 条件
then
命令表1
else
命令表2
fi
多路分支结构:if 条件1
then
命令表1
elif 条件2
then
命令表2
fi
注意:如果表达式为真, 则执行命令表中的命令; 否则退出if语句, 即执行fi后面的语句。if和fi是条件语句的语句括号, 必须成对使用;命令表中的命令可以是一条, 也可以是若干条。
嵌套结构:if 条件1
then
if 条件2
then
命令表1
fi
else
命令表2
fi
补充操作符:
-o 或运算 例如 [ $a -lt 20 -o $b -gt 100 ] 返回 true
-a 与运算 例如 [ $a -lt 20 -a $b -gt 100 ] 返回 false
! 非运算 例如 [ ! false ] 返回 true
&& 逻辑与 例如 [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑或 例如 [[ $a -lt 100 || $b -gt 100 ]] 返回 true
| 位或 例如 echo $[2|2]
&位与 例如 echo $[2&1]
(2).case语句
case 变量 in
模式1)
命令表1
;;
模式2)
命令表2
;;
*)
命令表n
;;
esac
(3).for循环
do
命令表
done
执行顺序:
变量依次取单词表中的各个单词,每次只取一个单词,就执行一次循环体中的命令,循环次数是由单词表中的单词数量决定,命令表中命令可以是一条。也可以是由分号或者换行符分开的多条
(1)for i in 1 2 3 4 do....done : 变量i从单词表中取值
(2)for i in {1..10} do...done: 变量i从1-10个数中取值
for I in {1..10} do ... done
(4)for ((i = 0; i < 10; i++)) do...done:书写格式类似c语言
(4).while循环
do
命令表
done
while语句首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。
(5).循环控制语句
continue n: 结束n层的本次循环,继续下一次循环
#!/bin/bash
for ((i=0;i<5;i++))
do
for ((j=0;j<5;j++))
do
if [ $j -eq 3 ]
then
#break 1 ,跳出内层循环
#break 2 ,跳出内层循环后跳出外层循环
#continue 1 ,跳出一次内层循环,继续下一次循环
continue 2 #跳出两次内层循环,继续下一次循环
fi
echo "$i : $j"
done
done
四丶数组
1 数组的赋值
(2) arr=($1 $2 $3...)
(3) read a b c
arr=($a $b $c)
(4) read -a arr
2.数组的调用
arr[i]=10 #对数组元素重新赋值
${arr[@]} #遍历数组
${#arr[@]} #数组元素的个数
冒泡排序
五丶函数
1.函数定义方式
{
命令表
}
(2) function 函数名()
{
命令表
}
2.函数调用
#!/bin/bash
fun ()
{
echo "hello world"
}
function add()
{
((NUM=$1 + $2))
echo $NUM
}
fun
add 1 2