1 shell基础
1.1 运维&shell[了解]
1.1.1 运维基础
运维定位
技术岗位
工作范围
项目全生命周期
运维&shell
运维的目标: 自动化运维 --> 方式(工具+脚本)
脚本:
shell脚本
其他脚本
1.1.2 shell简介
shell定位
shell 命令解释器
shell分类
图形
命令行
windows cmd.exe
linux bash
查看方式:
echo $SHELL 系统默认shell
cat /etc/shells 系统支持的shell种类
使用方式
手工
逐行输入命令,逐行确认执行
[root@sswang ~]# echo $SHELL
/bin/bash
[root@sswang ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
脚本
可执行命令在一个文件中的组合
[root@sswang ~]# mkdir /data/scripts -p
[root@sswang ~]# cd /data/scripts/
[root@sswang scripts]# ls
[root@sswang scripts]# vim test.sh
[root@sswang scripts]# cat test.sh
#!/bin/bash
# 测试脚本
echo $SHELL
cat /etc/shells
[root@sswang scripts]# /bin/bash test.sh
/bin/bash
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
1.2 shell脚本[记忆]
1.2.1 创建脚本
创建方式
任意一种编辑文件的工具都可以
vim
脚本命名
有意义
脚本内容
命令:可执行成功的命令
执行:从上到下按顺序执行
注释
单行注释
#开头的内容
注意:
第一行的#除外
多行注释
:<<字符 注释内容 字符
[root@shell scripts]# cat zhushi.sh
#!/bin/bash
# 测试脚本
echo $SHELL
:<
第 2 章 核心知识[应用]
2.1 表达式
2.1.1 测试语句
应用场景
判断条件是否成立
语句格式
test 条件表达式
[ 条件表达式 ] 优先推荐
注意:
[] 和 条件表达式 有空格隔开
示例:
test 1 = 1
echo $?
test 1 = 2
echo $?
test 1 = 1
echo $?
test 1 = 2
echo $?
[ 1 = 1 ]
echo $?
[ 1 = 2 ]
echo $?
[ 1 = 3 ]
echo ?$
[ 1 = 3 ]
echo $?
[ 1 = 3]
[ 1 = 3] ]
echo $?
2.1.2 条件表达式
逻辑表达式
&& 前面动,后面也动,前面不动,后不动 同林鸟
|| 前面动,后面不动,前面不动,后动 对着干
示例:
[root@shell scripts]# [ 1 = 2 ] && echo "条件不成立"
[root@shell scripts]# [ 1 = 2 ] || echo "条件不成立"
条件不成立
[root@shell scripts]# [ 1 = 1 ] && echo "条件不成立"
条件不成立
[root@shell scripts]# [ 1 = 1 ] || echo "条件不成立"
[root@shell scripts]#
文件表达式
-f 判断输入内容是否是一个文件
-d 判断输入内容是否是一个目录
-x 判断输入内容是否可执行
示例:
[ -f get_name1.sh ] && cat get_name1.sh
[ -f get_name2.sh ] && cat get_name1.sh
ls
[ -d backup ] && mv *.sh backup
ls
[ -d backup ] || mkdir backup
ls
[ -x get_name1.sh ] && ./get_name1.sh
[ -x get_name1.sh ] || chmod +x get_name1.sh
ll
数值表达式
-gt -lt -eq -ne -le -ge
注意:
生产中,ne 和eq 使用的频率比较高
示例:
[ 2 -eq 1 ]
echo $?
[ 2 -eq 2 ]
echo $?
[ 2 -ne 1 ]
echo $?
[ 2 -ne 2 ]
echo $?
[ 2 -lt 21 ]
echo $?
[ 2 -gt 21 ]
echo $?
字符串表达式
字符串内容是否一致
一致 ==
不一致 !=
注意:
可以对具体的字符串进行比较
也可以对变量名的字符串进行比较
示例:
[ aaa == bbb ]
echo $?
[ aaa != bbb ]
echo $?
a=abcd
b=defg
[ $a == $b ]
echo $?
[ $a != $b ]
echo $?
2.1.3 计算表达式
使用场景
计算场景
计算格式
整数场景:
$((计算表达式))
let 计算表达式
注意:
对于let来说,计算表达式必须是一个整体,不能有空格
计算实践
echo $((1 + 3))
echo $((1 + 4))
echo $((1 + 44))
echo $((1 + 44e))
a=3
echo $((a*3))
echo $((a*4))
a=$((a+4))
echo $a
a=$((a+4))
echo $a
i=4
let j=3+4
echo $j
let j=i+5
echo $j
let j = i +5
拓展:
小数的计算:bc
2.1.4 数组操作
数组简介
一列数字组合
组成:
数组名 元素内容 下标值
定义格式
array_name=(value1 ... valuen)
注意:
元素内容必须下()范围中
元素彼此间使用空格隔开
array_name[0]=value0
信息查看
查看内容
echo ${array_name[index]}
查询下标
echo ${!array_name[index]} @ *
获取长度
单元素长度 echo ${#array_name[index]}
数组元素个数echo ${#array_name[@|#]}
示例:
array_name=(value0 value1 value2 value3)
echo ${array_name[1]}
echo ${array_name[2]}
echo ${array_name[@]}
echo ${array_name[*]}
echo ${!array_name[@]}
echo ${!array_name[2]}
echo ${!array_name[value1]}
echo ${!array_name[value0]}
${#array_name[index]}
${#array_name[2]}
echo ${#array_name[2]}
echo ${!array_name[*]}
echo ${#array_name[*]}
echo ${#array_name[1]}
unset array_name
array1=(a b c d)
array2=( b d e f g )
echo ${array1[0]}
echo ${array1[2]}
echo ${array2[2]}
echo ${array2[@]}
echo ${array2[*]}
echo ${!array1[@]}
echo ${#array1[@]}
echo ${#array2[@]}
echo ${#array2[1]}
array3[2]=nihao
array3[1]=dd
echo ${#array3[@]}
echo ${#array3[2]}
echo ${array3[2]}
array3[12]=dd
echo ${array3[12]}
增删改
增加 array_name[index]=value
查看:
整体 echo ${array3[index]}
部分 echo ${array3[index]:起始位置:获取长度}
更改
整体 array_name[index]=value
模拟替换${array3[index]/原内容/修改后内容}
注意:因为是模拟,所以内容不会变
删除:
单个元素 unset array_name[index]
整体 unset array_name
示例:
array3[12]=dddksafjldsajfklsaj
echo ${array3[12]}
echo ${array3[12]:9:4}
array3[12]=gaile
echo ${array3[12]}
echo ${array3[12]/ai/haha}
echo ${array3[12]}
unset array3[12]
echo ${array3[12]}
echo $#{array3[@}
echo ${#array3[@}
echo ${#array1[]}
echo ${#array2[]}
echo ${#array2[@]}
unset array2
echo ${#array2[@]}
2.2 linux常见符号
2.2.1 重定向
作用:
数据的传输
种类;
> 覆盖形式
>> 追加的形式
示例:
echo nihao > file.txt
ls
cat file.txt
echo nihao1 > file.txt
cat file.txt
echo nihao2 >> file.txt
cat file.txt
echo nihao2 >> file.txt
cat file.txt
2.2.2 管道符 |
作用:信息的传输
特点:从左向右
示例:
ls | grep test
env | grep SHELL
2.2.3 其他符号
后台展示
&
信息符号
2>&1
特殊设备
/dev/null
示例:
sleep 6 &
ls
sleep 16 &
ps aux | grep sleep
ls
echo $?
kdsafljdsklajflsd
echo $?
echo $SHELL
echo $SHELL 1 >> zhengque
cat zhushi.sh
cat zhengque
echo $SHELL 1>> ok
cat ok
jdklsafj 2>> nook
cat nook
ls
vim cuowu.sh
cat cuowu.sh
/bin/bash cuowu.sh
/bin/bash cuowu.sh 1>> ceshi-ok 2>> ceshi-nook
cat ceshi-ok
cat ceshi-nook
/bin/bash cuowu.sh >> ceshi-all 2>&1
cat ceshi-all
ls /dev/null
ls /dev/zero
ls >> /dev/null
/bin/bash cuowu.sh >> /dev/null 2>&1
python manage.py runserver >> /dev/null 2>&1 &
2.3 简单流程控制
2.3.1 if语句
单分支
if [ 条件 ]
then
指令
fi
场景:一个条件一个结果
关键点:
1 框架格式
2 首尾关键字相反
示例:
#!/bin/bash
# 单if语句示例
if [ $1 == "nan" ]
then
echo "您的性别是:男"
fi
双分支
if [ 条件 ]
then
指令1
else
指令2
fi
流程:
条件成立,执行指令1
条件不成立,执行指令2
示例:
#!/bin/bash
# 双if语句示例
if [ $1 == "nan" ]
then
echo "您的性别是:男"
else
echo "您的性别是:女"
fi
多分支
if [ 条件 ]
then
指令1
elif [ 条件2 ]
then
指令2
else
指令3
fi
特点:
在双分支if语句的基础上,多了一个elif-then语句
场景:n个条件n+1个结果
示例:
#!/bin/bash
# 多if语句
if [ "$1" == "nan" ]
then
echo "您的性别是男"
elif [ "$1" == "nv" ]
then
echo "您的性别是女"
else
echo "您的性别,我不知道"
fi
多分支应用
#!/bin/bash
# 多if语句的服务使用场景
arg="$1"
if [ "${arg}" == "start" ]
then
echo "服务启动中..."
elif [ "${arg}" == "stop" ]
then
echo "服务关闭中..."
elif [ "${arg}" == "restart" ]
then
echo "服务重启中..."
else
echo "脚本 $0 的使用方式: /bin/bash $0 [ start|stop|restart ]"
fi
2.3.2 case语句
格式:$
case 变量名 in
值1)
指令1
;;
...
值n)
指令n
;;
esac
关键点:
1 框架: case-esac
2 选项: )
3 语句: ;;
示例:
#!/bin/bash
# case语句示例
arg="$1"
case "${arg}" in
"start")
echo "服务启动中..."
;;
"stop")
echo "服务关闭中..."
;;
"restart")
echo "服务重启中..."
;;
*)
echo "脚本 $0 的使用方式: /bin/bash $0 [ start|stop|restart ]"
;;
esac
拓展:
* 两侧不允许出现双引号
* 不允许是第一个匹配选项
case语句是linux下所有服务默认的流程控制语句
2.3.3 循环语句
for语句
场景: 有范围数量的循环
格式:$
for 值 in 列表
do
执行语句
done
示例:
#!/bin/bash
# for 循环语句
for i in $(ls /data/scripts)
do
echo "/data/scripts 的文件有 ${i}"
done
while语句
场景:死循环,
特点:只要条件成立,就一直循环下去
格式:$
while 条件
do
执行语句
done
示例:
#!/bin/bash
# while死循环
a=1
while [ ${a} -lt 5 ]
do
echo "${a}"
let a=a+1
sleep 1
done
until语句
场景:死循环,
特点:只要条件不成立,就一直循环下去
格式:
until 条件
do
执行语句
done
示例:
#!/bin/bash
# until死循环
a=1
until [ ${a} -eq 5 ]
do
echo "${a}"
a=$((a+1))
sleep 0.5
done
2.3.4 循环退出
退出简介
场景:在某些循环场景下,我们需要临时跳出循环,做一些其他动作
break示例
跳出整个循环
#!/bin/bash
# break退出演示
# 根据用户输入内容,进行判断,死循环
while :
do
echo -n "输入您的数字,最好在 1~5 之间:"
read anum
case "${anum}" in
1|2|3|4|5)
echo "您输入的数字是${anum}"
;;
*)
echo "您输入的数字不在范围中,我们要终止"
break
;;
esac
done
break n示例
跳出嵌套循环
#!/bin/bash
# 退出嵌套循环示例
for var1 in {1..5}
do
for var2 in {0..4}
do
if [ $var1 -eq 3 -a $var2 -eq 2 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
continue示例
作用: 跳出当前匹配到的循环,继续执行下一个循环
#!/bin/bash
# continue退出演示
# 根据用户输入内容,进行判断,死循环
while :
do
echo -n "输入您的数字,最好在 1~5 之间:"
read anum
case "${anum}" in
1|2|3|4|5)
echo "您输入的数字是${anum}"
;;
*)
continue
echo "您输入的数字不在范围中,我们要终止"
;;
esac
done
exit示例
作用:退出所有循环,无论你有多少层循环,简单来说,就是退出当前程序。
示例1 -- break 1
#!/bin/bash
# 退出嵌套循环示例
for var1 in {1..5}
do
for var2 in {0..4}
do
if [ $var1 -eq 3 -a $var2 -eq 2 ]
then
break 1
else
echo "$var1 $var2"
fi
done
done
示例2 -- exit
#!/bin/bash
# 退出所有嵌套循环示例
for var1 in {1..5}
do
for var2 in {0..4}
do
if [ $var1 -eq 3 -a $var2 -eq 2 ]
then
exit
else
echo "$var1 $var2"
fi
done
done
2.4 复杂流程控制
2.4.1 函数基础知识
函数定义
实现特定功能可执行命令组合
函数样式
简单函数定义和调用
定义函数:
函数名(){
函数体
}
调用函数:
函数名
关键点:
必须先定义,然后再调用
只定义或者只调用都没有任何意义。
示例:
#!/bin/bash
# 简单函数定义和调用
# 定义函数
dayin(){
echo "你好,我们是 aaa"
}
# 调用函数
dayin
传参函数定义和调用
定义格式:
函数名(){
函数体 $n
}
调用函数:
函数名 参数
关键点:
1 函数传参与脚本传参类似
2 函数的参数调用,使用位置参数变量
3 合理的使用本地变量,避免参数传参歧义
示例:
[root@shell scripts]# cat arg-func.sh
#!/bin/bash
# 传参函数定义和调用
# 定义函数
dayin(){
xingming="$1"
echo "您好,我们是 ${xingming}"
}
# 调用函数
dayin aaa
dayin bbb
dayin ccc
[root@shell scripts]# /bin/bash arg-func.sh
您好,我们是 aaa
您好,我们是 bbb
您好,我们是 ccc
脚本传参函数调用
脚本传参数
/bin/bash 脚本名 参数
函数体调用参数:
函数名(){
函数体 $1
}
函数名 $1
关键点:
脚本传参数,函数的调用方式
示例:
#!/bin/bash
# 脚本传参函数调用
# 定义函数
dayin(){
xingming="$1"
echo "您好,我们是 ${xingming}"
}
# 调用函数
dayin $1
脚本传参函数调用(生产用)
关键点:
只要是涉及到传参,我们都采用本地变量的方式接受,不将其直接放到命令中,避免误解
技巧--本地变量的活学活用
示例:
#!/bin/bash
# 脚本传参函数调用--生产用
# 定义本地变量
ARG="$1"
# 定义函数
dayin(){
xingming="$1"
echo "您好,我们是 ${xingming}"
}
# 调用函数
dayin "${ARG}"
2.4.2 函数实践
2.5 常见命令详解
2.5.1 grep命令详解
命令格式
grep [参数] [关键字] <文件名>
命令实践
-c 计数
-n 行号
-v 取反
示例:
grep -c aaa grep.txt
grep -c nihao grep.txt
grep -cn nihao grep.txt
grep -n nihao grep.txt
grep -v nihao grep.txt
grep -vn nihao grep.txt
命令拓展:
-r 递归查找
-i 忽略大小写敏感
egrep 基于正则符号进行精确过滤
示例:
grep -nr aaa /data/*
grep -nr AAA /data/*
grep -nri AAA /data/*
cd /data/scripts/
ls
cat grep.txt
egrep 'AAA|bbb' grep.txt
egrep -n 'AAA|bbb' grep.txt
egrep -n '^N' grep.txt
2.5.2 sed命令详解
格式详解
sed [参数] '<匹配条件> [动作]' [文件名]
参数:
-n 取消默认输出
-i 对文件进行立即编辑
无 模拟对文件编辑
匹配条件:
数值
内容
匹配符号: / # @ !
动作:
p 打印
s 替换
查看实践
格式: sed '行号p' 文件名
sed '/内容/p' 文件名
sed '3p' sed.txt
sed -n '3p' sed.txt
sed -n '2,3p' sed.txt
sed -n '/SED4/p' sed.txt
替换实践
格式:
sed -i '行号s#原内容#替换后内容#列号' [文件名]
sed -i 's#原内容#替换后内容#g' [文件名]
关键点;
行号不写表示所有行,
列号不写,表示匹配到的第一个
列号是g,表示指定行所有的匹配内容
示例:
sed 's#sed#SED#' sed.txt
cat sed.txt
sed -i 's#sed#SED#' sed.txt
cat sed.txt
sed -i '2s#sed#SED#2' sed.txt
cat sed.txt
sed -i 's#sed#SED#g' sed.txt
cat sed.txt
增加实践
指定行的下一行增加
sed '行号a\新内容' 文件名
sed '/内容/a\新内容' 文件名
示例:
cat -n sed.txt
sed -i '2a\add-1' sed.txt
cat -n sed.txt
sed -i '1,3a\add-3' sed.txt
cat -n sed.txt
sed -i '/SED1/a\add-sed1' sed.txt
cat -n sed.txt
指定行的当行增加
sed '行号i\新内容' 文件名
sed '/内容/i\新内容' 文件名
示例:
cat -n sed.txt
sed -i '1i\insert-1' sed.txt
cat -n sed.txt
sed -i '6,8i\insert-1' sed.txt
cat -n sed.txt
sed -i '/SED5/i\insert-sed5' sed.txt
cat -n sed.txt
删除实践
删除格式
sed '行号d' 文件名
sed '/内容/d' 文件名
示例:
cat -n sed.txt
sed -i '8d' sed.txt
cat -n sed.txt
sed -i '7,11d' sed.txt
cat -n sed.txt
sed -i '/add-3/d' sed.txt
cat -n sed.txt
sed -i '/SED/d' sed.txt
cat -n sed.txt
2.5.3 awk命令详解
格式详解
基本命令格式:
awk [参数] '[ 动作]' [文件名]
动作:
'{print $n}'
$0 带表当前行所有内容
$n 代表当前行的第几列内容
多列内容的表示,彼此间使用逗号隔开
'/内容/' 基于内容进行查看的效果
内置变量:
NR 行号相关的内置变量
简单实践
信息查看
awk '{print }' awk.txt
awk '{print $0 }' awk.txt
awk '{print $1 }' awk.txt
awk '{print $3 }' awk.txt
awk '{print $1,$3 }' awk.txt
awk '{print $1$3 }' awk.txt
awk '{print $4$2 }' awk.txt
awk '{print $4,$2 }' awk.txt
awk '{print $4,$2 }' awk.txt
awk '{print NR,$4,$2 }' awk.txt
awk 'NR==1 {print NR,$4,$2 }' awk.txt
awk '/awk/' awk.txt
参数实践
-F 指定文件的列分隔符
-f 指定内容输出的文件格式
-v 指定awk的一个变量
awk -F ':' '{print $1}' passwd.txt
awk -F ':' '{print $1,$7}' passwd.txt
cat passwd.txt
vim filename
cat filename
awk -f filename passwd.txt
vim filename
cat filename
awk -f filename passwd.txt
awk -v vari=100 '{print vari}'
echo | awk -v vari=100 '{print vari}'
echo | awk '{print v1,v2}' v1=1000,v3=300
echo | awk '{print v1,v2}' v1=1000,v2=300
echo | awk '{print v1,v2}' v1=1000 v2=300
格式进阶
BEGIN{ 命令 } 初始代码块,主要和变量相关
/pattern/{ 命令 } 匹配、执行代码块
END{ 命令 } 结束代码块,主要和信息输出相关
示例:
awk -F ':' '{print $1,$7}' passwd.txt
awk -F ':' 'BEGIN{OFS='|'} {print $1,$7}' passwd.txt
awk -F ':' 'BEGIN{OFS="|"} {print $1,$7}' passwd.txt
awk -F ':' 'BEGIN{print "序号 用户 登录bash"} {print NR,$1,$7} END{print "---结束了----"} ' passwd.txt
进阶实践
if语句示例:
位置: '{ if语句 print语句 }'
条件: (( 条件1 && 条件2 ))
示例:
ls -l | awk '{ if (($5>=200)) print "文件名称: " $9 "\t" "文件大 小:" $5 "B" }'
ls -l | awk '{ if (($5>=200 && /^-/)) print "文件名称: " $9 "\t" "文件大 小:" $5 "B" }'
for语句示例:
位置:'{ for语句 print语句 }'
条件: for( 循环表达式 )
示例:
echo 'abcdefg' | awk -F '' '{ for(i=1;i<=NF;i++) print $i}'
echo 'abcdefg' | awk -F '' '{ for(i=NF;i>=1;i--) print $i}'
2.5.4 find命令详解
格式详解
find [路径] [参数] [关键字] [动作]
参数:
-name
-type
-mtime
-path
-prune
动作:
-print 默认属性,打印信息
-ls 列出文件详细属性
-exec 命令 \; 对过滤的文件进行下一步操作
注意:
{} 就相当于过滤出来的文件
操作类似于 | xargs 命令
所有的参数,可以综合起来使用。
find / -name "ok"
find /data -name "ok"
find /data -name "o*"
find /data -type f
find /data -type d
find /data -type f -name "*fu*"
ls
stat ok
find /data -mtime -5
find /data -mtime +5
find /tmp -mtime +5
stat /tmp/.Test-unix
find /tmp -mtime +5 -print
ls
find /data/scripts -path "/data/scripts/backup" -prune
find /data/scripts -path "/data/scripts/backup" -prune -o -print
ls
mkdir backup2
mv ok nook backup2/
ls
find . \( -path ./backup -o -path ./backup2 \) -prune -o -print
命令实践
find . -perm 640
find . -perm 640 -print
find . -perm 640 -ls
find . -perm 640 -exec mv {} {}.bak \;
find . -perm 640 -ls
ls
find . -name "passwd*" -ls
find . -name "passwd*" -exec cp {} {}.bak \;
ls
find . -name "*txt.bak" -exec cp {} {}.bak \;
find . -name "*txt.bak"
find . -name "*txt.bak" -exec rm -f {} \;
ls
find . -name "*bak.bak"
find . -name "*bak.bak" | xargs rm -f
find . -name "*bak.bak"
强烈掌握:
-exec
xargs