头部声明
#!/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 <echo
-n 不换行输出
echo -n “date: “;date +%F-e 解释操作符
/a #发出警告声 /b #删除前一个字符 /t #插入一个tab符 #定义背景字体颜色 echo -e “ 33[40;37m 你好 33[0m”read
获取输入 回车代表输入结束-p #打印信息 -t #限定时间 -s #不回显 常用于输入密码 -n #定义输入字符个数grep
sed
awk
cut
uniq
sort
seqseq 1 9 #从1开始依次输出到9 seq 9 -1 0 #从9开始逐减1到0sleep
sleep 1 #暂停1秒$?
echo $? #判断上条命令是否成功 #0为ture 非0为falsetest
变量定义变量
变量名=值 变量名和等号之间不能有空格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脚本的名字数组可赋予多个值,需要读取数据时通过索引调用
语法
#数组名=(元素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为假数学运算
简单运算
只可运算整形
letlet 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 fiif-else语法
if [ condition ] then commands1 else commands2 fiif-elif语法
if [ condition1 ] then commands1 elif [ condition2 ] then commands2 else commandsX fiif进阶语法
(())运算判断if (( 100%3+1>10 ));then echo "yes" else echo "no" fi[[]]高级语法
if [[ $1 == liu* ]];then echo "yes" else echo "no" fifor循环
for in 格式for i in 1 2 3 4 5 do echo $i donefor i in `seq 1 9` do echo $i sleep 1 donec格式
for ((i=1;i<10;i++)) do echo $i donec格式多变量
for ((a=0,b=9;a<10;a++,b--)) do echo $a $b donefor无限循环
for ((;;)) do echo "Are you ok?" donewhile循环
建议 已知循环次数使用for 未知则使用while
条件为真时执行 条件为假时结束
基础语法while [ condition ] do commands donewhile行遍历
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)) doneuntil循环
与while相反 until当条件为假是执行 条件为真时结束
基础语法until [ condition ] do commands done例子1 打印1-10
i=1 until [ $i -gt 10 ] do echo $i i=$((i+1)) donecase
根据可能出现的情况写执行事件
基础语法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 ;; esacsleep
控制脚本运行时间 单位秒for ((;;)) do echo "Are you ok?" #1秒执行一次 sleep 1 donecontinue
跳过本次循环for ((i=1;i<10;i++)) do if [ $i == 5 ] then continue fi echo $i donebreak
终止循环 多层循环可自定义终止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



