shell 的重要性-首篇
01. 学习shell的重要性
shell脚本语言是实现linux系统自动化管理的重要且必要的工具,因此需要熟练掌握shell脚本语言,
可以提升工作效率 解决工作中重复的劳动
学习shell需要具备哪些条件
1. vi/vim编辑器的熟练使用,ssh终端及.vimrc的设备等等需要搞熟练
2. 命令基础:liunx150个常用命令的熟练使用,这个见前文的课程讲解及课后作业
3. 常见linux网络服务部署排错 如:crond nfs rsync inotify lanmp sersync ssh等
4. linux正则表达式以及三剑客要熟练
grep命令: 实现过滤功能
-c 统计匹配的行总数信息
-r 进行递归匹配
zgrep 可以过滤压缩的文件信息
sed命令: 进行替换操作(文件进行编辑)
awk命令: 进行取列信息的操作 进行数据的统计工作(awk数组???)
学习shell方法技巧
最初状态: 学会看 模仿去写
高级状态: 自己去写(企业shell面试题) 自己去多说
\02. shell脚本概念介绍
shell是一个命令解释器,操作在系统的外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统 的输出结果,输出到屏幕返回给用户。
这种对话方式可以使交互的方式(从键盘输入,立即得到shell的回应),或非交互脚本方式
shell脚本编写规范
\01. 要编写解释器信息
#!/bin/bash --> #!/bin/sh
其它语言的开头标识内容:
#!/bin/sh
#!/bin/bash
#!/usr/bin/awk
#!/bin/sed
#!/usr/bin/tcl
#!/usr/bin/expect
#!/usr/bin/perl
#!/usr/bin/env python
\02. 注意编写注释信息
\03. 都要有变量信息
\04. 逻辑语句(循环 判断 函数信息)
shell脚本的执行通常可以采用以下3中方式
1) bash scripts-name 或 sh scripts-name(推荐使用)
当脚本文件本身没有可执行权限(即文件x位为-号)时常使用的方法,这里推荐用bash执行,
或者文件开头没有指定解释。
2) path/scripts-name 或 ./scripts-name(当前路径下执行脚本)
需要先将脚本文件的权限改为可执行(即文件加x位),
具体方法:chomd u+x scripts-name 或chmod 755 scripts-name
然后通过脚本路径就可以直接执行脚本了。
3) source scripts-name 或 . scripts-name(可以把脚本中变量函数带入到当前的shell)
依次执行指定shell脚本文件中的所有语句。这些语句将作为当前父shell脚本进程的一部分运行。
因此可以将自身脚本中的变量的值或函数等的返回值传递到当前的父shell脚本中使用。
系统应用中:
# source function library
. /etc/rc.d/init.d/functions
if [ $USER == "root" ];then
action "user is root" /bin/false
else
echo user is no root
fi
========================================================================
技巧补充: 复制脚本信息时, 有可能显示格式不正确
ctrl+v --- 选中多行 --- 按等于号 --- 会自动调整显示格式
========================================================================
\03. 变量作用说明
什么是变量:
方程式x=1 y=x+1,即x y为变量,1和x+1是变量的内容
变量就是用一个固定的字符串(也可能是字符数字等的组合),替代更多更复杂的内容,
这个内容里可能还包含变量和路径,字符串等其 它的内容。
使用变量的大好处就是方便,当然很多时候在编程中使用变量也是必须的,否则无法完成开发工作。
有字符串信息, 经常被使用时
name=oldgirl
变量类型说明:
a. 全局变量(环境变量)
系统默认定义好的,由大写字母组成,哪里都可以使用
自定义全局变量方法:
1) 变量名尽量为大写
2) 定义变量时, 需要使用export命令
①export 变量名=value
②变量名=value;export 变量名
③declare -x 变量名=value
3) 查看全局变量方法 env
$HOME 用户登录时进入的目录
$UID 当前用户的UID(用户标识)相当于id-u
$PWD 当前工作目录的绝对路径名
$SHELL 当前shell
$USER 当前用户
4) unset
5) 永久生效全局变量信息, 需要将变量定义在/etc/profile
b. 局部变量(自定义变量)
在创建脚本使用的变量(函数使用 脚本本身)
只能在创建他们的Shell函数或Shell脚本中使用
如何定义局部变量:
a. 将命令信息定义成变量
date_info=$(date +%F)
date_info=date +%F
PS: 有些比较长的命令, 当命令中出现多个管道信息时, 尽量不要设置成变量
b. 将字符串信息定义成变量
1) 字符串作为变量名使用时: 字母 数字 下划线; 名称只能以字母和下滑线开头
2) 字符串作为变量值使用时: 字母 数字 下划线
3) 字符串作为变量值时, 需要配合引号使用:
双引号: 可以解析变量值的信息(也可以不加双引号, 一样效果)
单引号: 所见即所得
不加引号:所见即所得,如果出现空格,不会将它当成变量解析
反引号: 可以将命令信息进行解析; 解析的命令必须存在于环境变量中, 或者命令信息书写成全路径(与$()同义)
定义变量时命名规范:
变量名称要有意义: 可以使用驼峰语法 每个单词首字母大写
如何调用变量信息
\1. echo $变量名称
2. 利用let定义变量运算信息
[root@web01 scripts]# let oldgirl=$oldboy+1
[root@web01 scripts]# echo $oldgirl
124
\3. 利用declare定义变量运算???
[root@web01 scripts]# declare -i oldgirl="$oldboy + 1"
[root@web01 scripts]# echo $oldgirl
457
c. 特殊变量(位置变量)
$0 --- 显示脚本文件名称信息
[root@web01 scripts]# dirname /server/scripts/test02.sh
/server/scripts
[root@web01 scripts]# basename /server/scripts/test02.sh
test02.sh
企业应用:
grep "$0" /etc/init.d/sshd
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
$n --- 定义脚本传参的参数信息 (每个参数之间以空格分割; 以引号进行汇聚)
注意说明: 传参个数大于9时, 定义传参信息方法
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
企业应用:
case "$1" in
start)
rh_status_q && exit 0
start
;;
$# --- 获得传参的个数信息
企业应用:
/etc/init.d/functions: if [ "$#" -eq 0 ]; then
if [ $# -ne 2 ];then
echo "Usage: $0 {start|stop}"
exit 1
fi
$* --- 显示传参的参数信息 以整体方式进行获取
$@ --- 显示传参的参数信息 以个体方式进行获取
set命令 设置参数信息
效果演示:
[root@web01 scripts]# set -- "I am" handsome oldboy
[root@web01 scripts]# for n in "$*"; do echo $n;done
I am handsome oldboy
[root@web01 scripts]# for n in "$@"; do echo $n;done
I am
handsome
oldboy
d. 特殊变量(进程状态)
$? --- 显示返回值信息(0表示上一个命令操作成功了 非0表示失败了)
企业应用:
/etc/init.d/smartd: status)
/etc/init.d/smartd: status $prog
/etc/init.d/smartd: RETVAL=$?
$$ --- 记录脚本执行时进程号信息
企业应用:
echo $$ >/tmp/test02.pid
runlevel=$(set -- $(runlevel);eval "echo $$#" )
$! --- 记录上一个脚本执行的PID
[root@web01 scripts]# sh test02.sh &
[1] 26453
[root@web01 scripts]# 26453
[1]+ Done sh test02.sh
[root@web01 scripts]# echo $!
26453
$_ --- 在此之前执行的命令或脚本的后一个参数
[root@web01 scripts]# sh test02.sh 1 2 3 4 5 6 7 8
26459
[root@web01 scripts]# echo $_
8
e. 变量扩展(字符串变量)
${parameter} --- 避免金庸新著 ${oldboy}aabb
${#parameter} --- 显示字符串中字符数量
[root@web01 scripts]# oldboy="I am oldboy"
[root@web01 scripts]# echo ${#oldboy}
11
企业面试题: I am oldboy I am 33
实际案例应用脚本
I am oldboy linux welcome to our training.
取小于6的字符串
for n in I am oldboy linux welcome to our training.
do
if [ ${#n} -lt 6 ]
then
echo $n
fi
done
说明:利用变量字符串功能,控制取出相应字符串数量的字
${parameter:offset} --- $parameter中, 从offset位置之后进行取值, 一直到结尾
[root@web01 scripts]# oldboy="abc123ABC123abc"
[root@web01 scripts]# echo ${oldboy:1}
bc123ABC123abc
[root@web01 scripts]# echo ${oldboy:3}
123ABC123abc
${string:position:length} ---在$string中,从位置$position之后开始提取长度为$length的子串
[root@web01 scripts]# oldboy="abc123ABC123abc"
[root@web01 scripts]# echo ${oldboy:3:3}
123
${parameter#word} ---从字符串开始进行匹配word字符串信息, 删除最短匹配的子串word信息
${parameter##word} ---从字符串开始进行匹配word字符串信息, 删除最长匹配的子串word信息
[root@web01 scripts]# oldboy="abcefgabcefg"
[root@web01 scripts]# echo ${oldboy#a*c}
efgabcefg
[root@web01 scripts]# echo ${oldboy##a*c}
efg
${parameter%word} ---从字符串结尾进行匹配word字符串信息, 删除最短匹配的子串word信息
[root@web01 scripts]# echo ${oldboy%efg}
abcefgabc
[root@web01 scripts]# echo ${oldboy%%efg}
abcefgabc
${parameter/string/replace} --- 替换变量中字符串内容, 使用replace字符串替换第一个匹配的string字符串信息
${parameter//string/replace} --- 替换变量中字符串内容, 使用replace字符串替换所有匹配的string字符串信息
[root@web01 scripts]# echo ${oldboy/abc/cba}
cbaefgabcefg
[root@web01 scripts]# oldboy="abcefgabcefg"
[root@web01 scripts]# echo ${oldboy//abc/cba}
cbaefgcbaefg
f. 变量扩展(变量替换)
$(value:-word) ---当变量未定义或者值为空时,返回值为word内容,否则返回变量的值。
[root@web01 scripts]# oldboy=
[root@web01 scripts]# echo ${oldboy}
[root@web01 scripts]# echo ${oldboy:-laowang}
laowang
$(value:=word) ---若变量未定义或者值为空时,在返回word的值的同时将word赋值给value
[root@web01 scripts]# oldboy=
[root@web01 scripts]# echo ${oldboy:=laowang}
laowang
[root@web01 scripts]# oldboy=xiaogang
[root@web01 scripts]# echo ${oldboy:-laowang}
xiaogang
[root@web01 scripts]# echo ${oldboy:=laowang}
xiaogang
[root@web01 scripts]# oldboy=
[root@web01 scripts]# echo ${oldboy:-laowang}
laowang
[root@web01 scripts]# echo $oldboy
[root@web01 scripts]# echo ${oldboy:=laowang}
laowang
[root@web01 scripts]# echo $oldboy
laowang
$(value:?"word") ---定义一个变量如果存在时,输出变量值; 定义变量不存在时,利用bash显示指定报错信息
[root@web01 scripts]# echo ${oldboy:?error_info}
-bash: oldboy: error_info
[root@web01 scripts]# oldboy=123
[root@web01 scripts]# echo ${oldboy:?error_info}
123
$(value:+word) ---未定义value的数值,即没有变量值,无输出;
定义了value的变量信息,即有变量值存储在,可以输出1用于表示有变量存在
[root@web01 scripts]# echo $oldboy
[root@web01 scripts]# echo ${oldboy:+1}
[root@web01 scripts]# echo ${oldboy:+0}
[root@web01 scripts]# oldboy=123456
[root@web01 scripts]# echo ${oldboy:+0}
0
[root@web01 scripts]# echo ${oldboy:+abc}
abc
#编写测试IP地址是否能ping通的脚本
[root@shell shell]# vim read-3.sh #!/bin/bash
#1.请用户输入一个ip地址
read -p "请输入一个你要测试连接的ip地址:" Ip
#2.进行测试该用户输入的ip地址是否连通
ping -W1 -c1 $Ip &>/dev/null
#3.判断上条命令的执行结果
if [ $? -eq 0 ];then
echo -e "\033[32m 该$Ip地址是通的 \033[0m"
else
echo -e "\033[31m 该$Ip地址是不通的 \033[0m"
fi
#echo命令输出颜色。
echo -e "\033[30m 黑色字 \033[0m"
echo -e "\033[31m 红色字 \033[0m"
echo -e "\033[32m 绿色字 \033[0m"
echo -e "\033[33m 黄色字 \033[0m"
echo -e "\033[34m 蓝色字 \033[0m"
echo -e "\033[35m 紫色字 \033[0m"
echo -e "\033[36m 天蓝字 \033[0m"
echo -e "\033[37m 白色字 \033[0m"

浙公网安备 33010602011771号