Shell脚本入门

Shell脚本入门

1 什么是Shell

命令都是通过Bash解释,Shell是一个命令解释器,作用解释用户输入的命令以及程序
交互式模式
	shell等待用户的输入,且执行用户输入的命令,因为shell与我们进行交互: 登陆 执行命令 退出系统等都称为交互式 退出后Shell终止
非交互式模式
	  Shell不和我们进行交互,而是读取存放在文件中的命令,并且执行它们,当读到文件的末尾,Shell终止

2 什么是Shell脚本

把命令统一在放一个文件中进行执行,称为Shell脚本
Shell脚本包含若干个命令+IF判断+FOR循环+变量+数组等等

3 Shell和Python之间的区别或者优势

Shell的优势处理操作系统底层的业务,Linux系统内部的应用都是Shell脚本完成,命令就是Shell编程的有力支撑 
可以做一键初始化操作、一键安装、一键优化、监控和报警。简单高效易用原则。
Python:开发运维工具及Web界面的管理工具,处理服务的启动停止、一键安装优化、报警也能做到,但是相对开发效率低,复杂度高	

4 Shell脚本规范

1)脚本存放固定的目录 mkdir /server/scripts -p  为了方便统一管理
2)开头需要加脚本的解释器 #!/bin/sh 指定解释器
3)附带作者及版本信息 对当前版本的说明
	#Author xxx
	#Crete time 20201010
	#cut log backup
	#QQ xxx
	#Version v1.0
4)脚本扩展名使用.sh结尾
5)注释尽量不使用中文
6)成对的符号和循环格式一次性书写完毕

5 脚本执行方式

# 执行脚本时都是在子shell中执行
# 执行Shell脚本常见的三种方式

# 1.bash直接执行
[root@shell scripts]# sh test.sh
Hello World!

# 2.使用路径方式执行 全路径和当前路径执行  必须给予可执行权限
[root@shell scripts]# chmod +x test.sh
[root@shell scripts]# ./test.sh
Hello World!
[root@shell scripts]# /server/scripts/test.sh
Hello World!

# 3.使用source或者.执行 在父shell中执行
[root@shell scripts]# source test.sh 
Hello World!
[root@shell scripts]# . test.sh
Hello World!

# 其他方式
[root@shell scripts]# cat test.sh |bash
Hello World!
[root@shell scripts]# bash < test.sh
Hello World!

6 Shell变量

# 1.什么是变量
答:定义在脚本中用来替代等号后面的一堆内容

# 2.变量的生存周期
永久的:需要修改环境变量配置文件。变量永久生效:/etc/profile
临时的:直接使用export声明变量即可,关闭shell则变量失效

# 3.临时变量的export区别
不加export:只对当前的shell生效
加export:对当前打开窗口所有的shell生效
# 4.环境变量配置文件生效的顺序
登陆Shell首先会加载/etc/profile文件,然后会执行家目录中的环境变量配置文件
按照执行顺序
	1./etc/profile
	2. ~/.bash_profile 
	3. ~/.bashrc
	4. /etc/bashrc
# 5.source和.以及bash和./test.sh的区别
  .和source相同:重新在当前shell运行一下文件中的内容
  bash:读取shell脚本中的内容,在子shell中运行
  ./test.sh:在子shell下执行shell命令,默认以bash解释器执行,需要有执行权限。

7 Shell特殊位置重要变量

$0:获取当前Shell脚本的文件名 ,如果脚本全路径执行则显示全路径.basename只获取脚本名称.
    [root@shell scripts]# cat test.sh
    #!/bin/bash
    echo $0
    [root@shell scripts]# sh test.sh
    test.sh
案例:echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"

$n:获取当前脚本的第n个参数,n为0则是脚本名称,从$1开始代表脚本的第一个参数,$9以后需要加{},如${10}

$#:获取shell脚本所有传参的总个数
    案例: 判断输入的参数
    [ $# -ne 2 ] && exit

$*:获取shell脚本所有传参的参数,如果不加双引号则和$@相同,在循环语句中如果加上双引号,则表示将所有的参数视为单个字符串
$@:获取shell脚本所有传参的参数,如果不加双引号则和$*相同,在循环语句中如果加上双引号,则表示将所有的参数视为独立字符串
    [root@shell scripts]# for i in "$*";do echo $i;done
    I am lizhenya teacher
    [root@shell scripts]# for i in "$@";do echo $i;done 
    I am
    lizhenya
    teacher
		
$?:获取执行上一条命令的执行状态结果,返回值0为成功 非0失败
    [root@shell scripts]# cat test.sh 
    #!/bin/bash
    ping -c1 -W1 www.bxxxaidu.com &>/dev/null
    [ $? -eq 0 ] && echo "ping www.baidu.com 的通" || echo "ping不通"
    
$$:获取当前脚本的PID
	echo $$ > /tmp/test_sh.pid
        
$!:获取上一个后台工作脚本进行的PID
	echo $!
        
$_ :获取脚本最后的一个参数 类似于ESC .

8 脚本的传参方式

  • 直接传参
[root@shell /server/scripts]# cat test.sh 
#!/bin/bash
ping -c1 -W1 $1 &>/dev/null
[ $? -eq 0 ] && echo "ping $1 is ok" || echo "ping $1 is error"
  • 变量赋值
[root@shell scripts]# cat test.sh
#!/bin/bash
url=$1
ping -c1 -W1 $url &>/dev/null
[ $? -eq 0 ] && echo "ping $url is ok" || echo "ping $url is error"
  • read读入
[root@shell scripts]# cat test.sh
#!/bin/bash
read -p "Please input url: " url
ping -c1 -W1 $url &>/dev/null
[ $? -eq 0 ] && echo "ping $url is ok" || echo "ping $url is error"

9 变量的子串

  • 子串的切片
[root@shell ~]# name="I am teacher"
# 取出am的三种方法

(1)awk
[root@shell ~]# echo $name|awk '{print $2}'
am

(2)cut
[root@shell ~]# echo $name|cut -c 3-4
am

(3)子串切片
[root@shell ~]# echo ${name:2:2}
am
[root@shell ~]# echo ${name:2:4}
am t
  • 统计变量的长度
# 1.wc -L
[root@shell ~]# echo $name|wc -L
12

# 2.
[root@shell ~]# echo ${#name}
12

# 3.awk
[root@shell ~]# echo $name|awk '{print length}'
12
    
# 4.expr
[root@shell ~]# expr length "$name"
12
    
# 面试题:cong取出单词长度小于3的字符串
name="I am linux teacher I am 18"
# 1.使用awk配合xargs
$ echo $name | xargs -n1|awk '{if(length<3)print}'

# 2.使用for循环
[root@shell ~]# cat test_len.sh 
#!/bin/bash
for i in I am linux teacher I am 18
do
	[ ${#i} -lt 3 ] && echo $i
done

# 3.awk结合for循环和if判断
$ echo $name|awk '{for(i=1;i<=NF;i++)if(length($i)<3)print $i}'
  • 变量的删除
# 删除变量url=www.sina.com.cn中的www的方法有几种?
# 方法1
$ sed -r 's#www.(.*)#\1#'

# 方法2
$ echo www.sina.com.cn|grep 's.*$' -o

# 方法3
$ echo $url|sed 's#www.##g'

# 方法4
$ echo ${url:4}

# 方法5 
$ echo $url|cut -c 5-15

#定义变量
url=www.sina.com.cn

# 从左往右删除
[root@shell ~]# echo $url
www.sina.com.cn
[root@shell ~]# echo ${url#*.}
sina.com.cn
[root@shell ~]# echo ${url#*.*.}
com.cn
[root@shell ~]# echo ${url#*.*.*.}
cn
[root@shell ~]# echo ${url#*.s}
ina.com.cn

[root@shell ~]# echo ${url}
www.sina.com.cn
[root@shell ~]# echo ${url#*s}
ina.com.cn
[root@shell ~]# echo ${url}   
www.sina.com.cn
[root@shell ~]# echo ${url#*c}
om.cn
[root@shell ~]# echo ${url##*c}
n

# 从右往左删除
[root@shell ~]# echo $url
www.sina.com.cn
[root@shell ~]# echo ${url%.*}
www.sina.com
[root@shell ~]# echo ${url%.*.*}
www.sina
[root@shell ~]# echo ${url%.*.*.*}
www

[root@shell ~]# echo ${url}
www.sina.com.cn
[root@shell ~]# echo ${url%.*}
www.sina.com
[root@shell ~]# echo ${url%.*.*}
www.sina
[root@shell ~]# echo ${url%%.*} 
www

小结:
变量从前往后删除 #   贪婪匹配 ##
变量从后往前删除 %   贪婪匹配 %%
  • 变量的替换
# 变量内容替换 //  贪婪匹配 ///

[root@shell ~]# echo $url
www.sina.com.cn
[root@shell ~]# echo $url|sed 's#sina#baidu#g'
www.baidu.com.cn

[root@shell ~]# echo ${url/sina/baidu}
www.baidu.com.cn
[root@shell ~]# echo ${url}
www.sina.com.cn
[root@shell ~]# echo ${url/w/a}
aww.sina.com.cn
[root@shell ~]# echo ${url//w/a}
aaa.sina.com.cn