基础语法命令
头部声明
#!/bin/bash
#定义脚本的执行环境
#Author:Liu Xizhen
#Create Time:2022/03/20 14:58
#Version:1.0
#Script Description:My first script
常用命令
| 管道
前一个命令的输出通过管道作为下一个命令的输入
cat /etc/passwd | grep bash
重定向
输出 全覆盖
> lxz.txt
追加输出在文件末尾
>> lxz.txt
输入
< lxz.txt
多重输入 搭配EOF实现
<<
fdisk /dev/sdb <<EOF
d
w
EOF
echo
echo
-n 不换行输出
echo -n “date: “;date +%F
-e 解释操作符
/a #发出警告声
/b #删除前一个字符
/t #插入一个tab符
#定义背景字体颜色
echo -e “\033[40;37m 你好 \033[0m”
read
获取输入 回车代表输入结束
-p #打印信息
-t #限定时间
-s #不回显 常用于输入密码
-n #定义输入字符个数
seq
seq 1 9 #从1开始依次输出到9
seq 9 -1 0 #从9开始逐减1到0
sleep
sleep 1 #暂停1秒
$?
echo $? #判断上条命令是否成功
#0为ture 非0为false
test
# test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
数值比较
-eq #等于则为真
-ne #不等于则为真
-gt #大于则为真
-ge #大于等于则为真
-lt #小于则为真
-le #小于等于则为真
字符串比较
= #等于则为真
!= #不相等则为真
-z str #字符串的长度为零则为真
-n str #字符串的长度不为零则为真
文件测试
-e filename #如果文件存在则为真
-r filename #如果文件存在且可读则为真
-w filename #如果文件存在且可写则为真
-x filename #如果文件存在且可执行则为真
-s filename #如果文件存在且至少有一个字符则为真
-d filename #如果文件存在且为目录则为真
-f filename #如果文件存在且为普通文件则为真
-c filename #如果文件存在且为字符型特殊文件则为真
-b filename #如果文件存在且为块特殊文件则为真
变量
定义变量
变量名=值 变量名和等号之间不能有空格
name=liuxizhen
命名规则
1、只能使用英文字母(最好大写)、数字和下划线,不能以数字开头
2、中间不能有空格
3、不能使用标点符号,不能使用bash里的关键字
变量分类
本地变量
用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile、.bashrc文件中
全局变量
所有用户都可以使用,保存在/etc/profile、/etc/bashrc文件中
export name=value
vi /etc/profile
#修改文件后 source /etc/profile 生效
临时变量
用户自定义变量,如脚本中的变量,关闭终端、脚本结束后失效
读取变量
$变量名
echo $liu
${变量名}
echo ${liu}
花括号可写可不写 作用为帮助解释器识别变量的边界
只读变量
readonly name
#将变量定义为只读变量 值不可修改
取消变量
unset name
#可临时取消全局变量
shell特殊变量
$* #代表所有参数 其间隔为IFS内定参数的第一个字元
$@ #与$*类似 区别于$@不参照IFS
$# #代表参数数量
$ #执行上一个命令的返回值 执行上一个背景指令的pid
$- #最近执行的foreground pipeline的选项参数
$$ #本身的Process ID
$_ #显示出最后一个执行命令
$N #shell的第N个外传参数
$0 #shell脚本的名字
Shell 的环境变量分为两种:
set:可以显示和设置shell私有变量,仅在本 shell 中有效。不同shell(bash、csh)私有变量不同。
env:可以显示和设置用户环境变量 ,仅在当前会话中有效。
另外set 变量可以通过 export 工具导入到 env 变量中:
export:显示或设置当前导出成用户变量的shell变量。
区别
两种变量不同之处在于变量的作用域不同,env 变量的作用域更大,它可以被所有shell使用。
也就是说,set 变量里包含了 env 变量,但 set 变量不一定都是 env 变量。
数组
可赋予多个值,需要读取数据时通过索引调用
语法
#数组名=(元素1 元素2 …)
array=(liu xi zhen)
#元素之间用空格隔开
读取
${数组名[索引]}
#索引即下标,默认是元素在数组中的序号,默认第一个从0开始
赋值
#一次赋一个值
array[0]=“liu”
array[1]=“xizhen”
#一次赋多个值
array=(liu xi zhen)
array=(‘cat /etc/passwd’) #将该文件的每一行作为一个元素赋值给数组
查看数组
declare -A #查看系统中被声明已创建的数组
访问数组元数
echo ${array[0]} #访问数组的第一个元素
echo ${array[@]} #访问数组所有元素 等同于echo ${array[*]}
echo ${#array[@]} #统计数组元素的个数
echo ${!array[@]} #获取数组元素的索引
echo ${array[@]:1} #从数组下标1开始输出所有元素
echo ${array[@]:1:2} #从数组下标1开始 访问两个元素
关联数组
可自定义索引 需要声明之后才可使用
声明关联数组
declare -A array
关联数组赋值
#一次一值
array[name]=“liuxizhen”
#一次多值
array=([name]=‘liuxizhen’ [age]=18)
运算
整形比较运算
#运算符 使用test 只可比较整形
-eq #等于
-gt #大于
-lt #小于
-ge #大于或等于
-le #小于或等于
-ne #不等于
test 2 -eq 3 ; echo $? #0为真 1为假
数学运算
简单运算
只可运算整形
let
let i=i+10
let "i=i+100'
[]
相当于let命令
i=$[i+10]
(())
相当于[]
i=$((i+10))
高级运算
expr
注意:变量与运算符之间必须使用空格作为分隔符
i=`expr $i + 10`
bc
支持浮点运算的高级计算器
n=`echo "scale=9; $i / 3" | bc`
文件比较与检查
test -d /dir/fle
-d #检查文件是否存在且为目录
-e #检查文件或目录是否存在
-f #检查文件是否存在且为文件
-r #检查文件是否存在且可写
-s #检查文件是否存在且不为空
-w #检查文件是否存在且可写
-x #检查文件是否存在且可执行
-O #检查文件是否存在并且被当前用户拥有
-G #检查文件是否存在且默认组为当前用户组
file1 -nt file2 #检查file1是否比file2新
file1 -ot file2 #检查file1是否比file2旧
file1 -ef file2 #检查file1、file2是否是同一个文件(硬链接)
字符串比较运算
test $user=='root' ; echo $?
== #等于
!= #不等于
-n #检查字符串的长度是否大于0
-z #检查字符串的长度是否为0
逻辑运算
&& #与
|| #或
! #非
#注意:
#与或 运算需要两个或以上条件,非 运算只能一个条件
#与 真真为真 真假为假 假假为假
#或 真真为真 真假为真 假假为假
#非 非假为真 非真为假
赋值运算
= #赋值运算符
a=10
name='liuxizhen'
流程控制
if判断
基础语法
if [ condition ]
then
commands
fi
if-else语法
if [ condition ]
then
commands1
else
commands2
fi
if-elif语法
if [ condition1 ]
then
commands1
elif [ condition2 ]
then
commands2
else
commandsX
fi
if进阶语法
(())运算判断
if (( 100%3+1>10 ));then
echo "yes"
else
echo "no"
fi
[[]]高级语法
if [[ $1 == liu* ]];then
echo "yes"
else
echo "no"
fi
for循环
for in 格式
for i in 1 2 3 4 5
do
echo $i
done
for i in `seq 1 9`
do
echo $i
sleep 1
done
c格式
for ((i=1;i<10;i++))
do
echo $i
done
c格式多变量
for ((a=0,b=9;a<10;a++,b--))
do
echo $a $b
done
for无限循环
for ((;;))
do
echo "Are you ok?"
done
while循环
建议 已知循环次数使用for 未知则使用while
条件为真时执行 条件为假时结束
基础语法
while [ condition ]
do
commands
done
while行遍历
while read line
do
commands
done<<`cat iplist`
while输出列
#IFS定义分隔符
IFS=$":"
while read f1 f2 f3 f4
do
echo "$f1 $f3"
done < /etc/passwd
例子1 字符串匹配
read -p "Please input your name: " name
while [ $name != 'liuxizhen' ]
do
echo "Fuck you! input again!"
read -p "Please input your name: " name
done
echo "I love you $name!"
例子2 嵌套if/for/while
i=0
while [ $i -lt 10 ]
do
i=$((i+1))
if [ $i -eq 5 ]
then
continue
fi
echo $i
done
例子3 99乘法表
i=1
while [ $i -lt 10 ]
do
for ((j=1;j<=$i;j++))
do
echo -n -e "$j * $i = $((i*j))\t"
done
echo
i=$((i+1))
done
until循环
与while相反 until当条件为假是执行 条件为真时结束
基础语法
until [ condition ]
do
commands
done
例子1 打印1-10
i=1
until [ $i -gt 10 ]
do
echo $i
i=$((i+1))
done
case
根据可能出现的情况写执行事件
基础语法
case $bianliang in
condition1)
commands1
;;
condition2)
commands2
;;
esac
#case 以倒写esac结束
例子1 匹配输入值
read -p "please input number: " num
case $num in
1)
echo 1
;;
2)
echo 2
;;
3)
exit 1
;;
esac
sleep
控制脚本运行时间 单位秒
for ((;;))
do
echo "Are you ok?"
#1秒执行一次
sleep 1
done
continue
跳过本次循环
for ((i=1;i<10;i++))
do
if [ $i == 5 ]
then
continue
fi
echo $i
done
break
终止循环 多层循环可自定义终止n层循环 breake n 从本循环1开始递增算第几层循环
for ((i=1;i<10;i++))
do
if [ $i == 5 ]
then
#当i=5时 终止循环 后面的不再运算
break
fi
echo $i
done
多次循环 自定义跳出层数
for ((i=1;i<10;i++))
do
echo $i
for ((;;))
do
#直接终止外层循环
break 2
done
done
函数
优点:代码模块化、调用方便、节省内存、可以改变代码执行顺序
函数默认不执行 需要调用执行
基础语法
语法一
fun_name () {
commands
return N
}
语法二
function fun_name() {
commands
return N
}
函数调用
函数调用只需函数名就可调用 注意不要加括号
function liuxizhen() {
echo "this is my first fun"
return 0
}
liuxizhen #只需函数名就可调用
函数传参
函数的传参跟shell脚本的传参类似 只需在函数后面加参数 以空格隔开
function liuxizhen() {
echo $1
echo $2
return 0
}
liuxizhen boy 21 #调用并传入两个参数
#输出结果
boy
21