此篇献给跟我一样宅在家努力的小伙伴们😋此次立下目标:一个月内熟练掌握Shell。学习Shell前需具备一定的对 Linux系统 的基础,没有基础的话学习起来比较吃力。后面我会陆续出一些关于我近期学习Shell的笔记与问题,欢迎一起讨论学习~
一、GNU/bash shell 特点
这里其实就是一些我们在使用 Linux系统 的小技巧,掌握后可以大大的提高我们在工作中的运维效率。
1. Tab键 命令和文件自动补齐
2. 命令历史记忆功能
上下键、!number、!string、!$、!!
3. 别名功能 alias
语 法:alias[别名]=[指令名称]
取消别名的方法是在命令前加 \ ,比如 \mkdir
4. 快捷键
Ctrl+A:将命令行光标移动至命令行首
Ctrl+E:将命令行光标移动至命令行末
Ctrl+Z:命令后台运行
Ctrl+R:搜索历史命令(执行命令直接按下回车键,编辑命令按下左右方向键)
Ctrl+D:终端输入或退出当前Shell
5. 输入输出重定向
> 重定向输出
#注意此操作会覆盖 file 文件原有的数据
echo "123" > file
>> 重定向输出,向文件追加数据
#此操作会在 file 文件末尾添加 123
echo "123" > file
&> 混合重定向(标准输出1,错误输出2)
#/dev/null相当于windows的回收站,所有写入它的内容都会永远丢失
command &> /dev/null
2>&1
首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出的行为,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。
command > file 2>&1
6. 管道 | tee
| tee 不会截取数据流
#此命令无任何返回值
date > date_1.txt
#此命令会返回date命令的值
date |tee date_2.txt
7. 通配符(元字符)
* 匹配任意多个字符
? 匹配任意一个字符
[] 匹配括号中任意一个字符
() 在子shell中执行
(cd /boot;ls)
(umask 077;touch file_zcoder)
{} 集合
#创建test1-3
touch test{1,2,3}
\ 转义字符,让元字符回归本意
“\t” 等于一个 Tab键
“\n” 等于一个 回车键
8. echo 或 printf 颜色输出文本
提示:30-37前景色 40-47背景色
#his is a red text.文本颜色输出
echo -e "\e[1;34mThis is a red text.\e[0m"
printf '\e[1;34mThis is a red text.\e[0m'
咳咳,感觉有点颜色了🤪
#结束文本颜色输出
echo -e "\e[0m"
-e 用来开启echo中的转义,\e 或 \033来输出符号
设置颜色的格式: \e[前景色;背景色;高亮m输出字符 \e[0m
echo -e '\033[31;44;1mThis is print\033[0m'
echo -e '\e[31;44;1mThis is print\e[0m'
背景色:0 透明(使用终端颜色), 40 黑, 41 红, 42 绿, 43 黄, 44 蓝 45 紫, 46 青绿,47白(灰)
前景色: 30 黑 31 红, 32绿, 33 黄, 34 蓝, 35 紫, 36 青绿, 37 白(灰)
高亮度:高亮是1,不高亮是0。注意m后面紧跟字符串。
如果你的CRT无法显示颜色,可参考这篇博客:
https://blog.youkuaiyun.com/the_Sunshine_of_King/article/details/82810931
二、变量
在每种编程语言中,变量都扮演了一个重要的角色。在Linux shell脚本编程中,我们使用两种类型的变量:系统定义的变量和用户定义的变量。shell脚本中的变量是用来调用一个数值或者字符值的手段。运维人员,在编写Shell脚本时常常会将用户定义的各种变量放在一个脚本中运行,例如:OpenStack的自动化部署脚本,一个脚本声明所有组件的变量,运维人员在部署时只需根据客户需求修改变量脚本即可。
1. 预定义变量
$0 : 脚本名
$* :所有参数
$@:所有参数
$#:参数的个数
$$:当前进程的PID
$! :上一个后台进程的PID
$? :上一个命令的返回值,0表示命令执行成功
$* 和 $@ 的区别:
当 $* 和 $@ 不被双引号" “包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。
但是当它们被双引号” "包含时,就会有区别了: “$*”:会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。
“$@”:仍然将每个参数都看作一份数据,彼此之间是独立的。
参考文章——http://c.biancheng.net/view/807.html
小 实 验一:
测试本机IP地址是否能ping通,并判断用户是否输入参数。
实现代码:
#!/usr/bin/bash
#2020-02-29
#Determine if the user enters a parameter
#Author zcoder
#########################################
#Determine if the user enters a parameter
#Commond basename\dirname
if [ $# -eq 0 ]; then
echo "usage: input `basename $0` parameter file"
exit 1
fi
#Determine if the parameter is a file
if [ ! -f $1 ]; then
echo "It is not a file!"
exit 1
fi
#ping the host ip
for ip in `cat $1`
do
ping -c1 $ip &> /dev/null
if [ $? -eq 0 ]; then
echo "$ip is up..."
else
echo "$ip is down..."
fi
done
测试:
[root@zh-docker ~]# chmod +x test.sh
[root@zh-docker ~]# ./test.sh ip.txt
127.0.0.1 is up...
192.168.56.101 is up...
10.0.2.15 is up...
[root@zh-docker ~]# ./test.sh 10.10.10.10
It is not a file!
2. 变量的赋值方式
显示赋值
变量名=变量值
示 例:
ip=192.168.56.101
school="China"
today=`date+%F`
date2=$(date+%F)
read从键盘读入变量值
read命令 -p(提示语句) -n(字符个数) -t(等待时间) -s(不回显)
read 变量名
read -p "提示信息:" 变量名
#-t选项指定read命令等待输入的秒数。当计时满时,read命令返回一个非零退出状态;
read -t 5 -p "提示信息:" 变量名
#-n选项用于限定最多可以有多少字符可以作为有效读入。
read -n 2 变量名
`` 等价于 $() 属于命令替换,反引号中的shell命令会被先执行
‘’ 单引号强引用,不能引用变量
“” 双引号弱引用,可引用变量
2. 变量的运算
整数运算
方法一:expr
+ # 加
- # 减
\* # 乘
/ # 除
% # 求余
[root@zh-docker ~]# num1=3
[root@zh-docker ~]# num2=4
[root@zh-docker ~]# expr 1+2
1+2
[root@zh-docker ~]# expr $num1+$num2
3+4
[root@zh-docker ~]# expr 1 + 2
3
[root@zh-docker ~]# expr $num1 + $num2
7
[root@zh-docker ~]# expr $num1 \* $num2
12
注意: 在使用 expr 命令时 运算符号必须用空格隔开
方法二:$(())
+ # 加
- # 减
* # 乘
/ # 除
% # 求余
[root@zh-docker ~]# echo $(($num1**$num2))
81
[root@zh-docker ~]# echo $(($num1*$num2))
12
[root@zh-docker ~]# echo $(($num1+$num2))
7
方法三:$[]
+ # 加
- # 减
* # 乘
/ # 除
% # 求余
[root@zh-docker ~]# echo $[$num1+$num2]
7
[root@zh-docker ~]# echo $[$num1*$num2]
12
[root@zh-docker ~]# echo $[$num1**$num2]
81
方法四:let (脚本中常用的整数运算)
+ # 加
- # 减
* # 乘
/ # 除
% # 求余
[root@zh-docker ~]# let sum=2*3;echo $sum
6
[root@zh-docker ~]# let i++;echo $i
1
[root@zh-docker ~]# let ++k;echo $k
1
小 实 验二:
输出当前内存使用百分比。
实现代码:
#!/usr/bin/bash
#2020-02-29
#Current memory usage percentage
#Author zcoder
###################################
Mem_total=$(free -m |grep "Mem" |awk '{ print $2 }')
Mem_use=`free -m |grep "Mem" |awk '{ print $3 }'`
Mem_percent=$[$Mem_use*100/$Mem_total]
echo "Current memory usage percentage: $Mem_percent%"
测试:
# chmod +x test.sh
# ./test.sh
Current memory usage percentage: 36%
小数运算
方法一:使用命令bc
Centos7 默认没有bc命令,需要手动下载
yum install -y bc
scale:表示小数精度
[root@zh-docker ~]# echo "6/4" |bc
1
[root@zh-docker ~]# echo "scale=3;6/4" |bc
1.500
方法二:使用命令awk
[root@zh-docker ~]# awk 'BEGIN{print 1/2}'
0.5
方法三:使用命令python
[root@zh-docker ~]# echo "print 5.0/2" |python
2.5
[root@zh-docker ~]# echo "print 5/2" |python
2
3、变量“内容”的删除
#变量名 获取变量的长度
[root@zh-docker ~]# url=www.baidu.com
[root@zh-docker ~]# echo ${#url}
13
变量名#*匹配字符 从前往后,最短匹配
[root@zh-docker ~]# echo ${url#*.}
baidu.com
[root@zh-docker ~]# echo ${url#*b}
aidu.com
变量名##*匹配字符 从前往后,最长匹配
[root@zh-docker ~]# echo ${url##*.}
com
[root@zh-docker ~]# echo ${url##*b}
aidu.com
变量名%匹配字符* 从后往前,最短匹配
变量名%%匹配字符* 从后往前,最长匹配
[root@zh-docker ~]# echo ${url%.*}
www.baidu
[root@zh-docker ~]# echo ${url%%.*}
www
4. 变量“内容”的替换
变量名/变量名中的字符/替换的字符
[root@zh-docker ~]# url=www.baidu.com
[root@zh-docker ~]# echo ${url/com/cn}
www.baidu.cn
5. 变量的替代
变量名-另一个变量值:
“变量名”没有被赋值时会使用“新的变量值”替代
变量名被赋值时(包括 空值):不会被替代
[root@zh-docker ~]# echo ${url-www.youkuaiyun.com}
www.baidu.com
[root@zh-docker ~]# unset url
[root@zh-docker ~]# echo ${url-www.youkuaiyun.com}
www.youkuaiyun.com
[root@zh-docker ~]# url=
[root@zh-docker ~]# echo ${url-www.youkuaiyun.com}
6. ++i和i++的区别:
对变量的值并没有影响,
let x=i++ 先赋值,再运算
let y=++j 先运算,再赋值