shell概念
Shell是用户与Linux操作系统之间沟通的桥梁,用户可以输入命令执行,又可以利用 Shell脚本编程去运行:
Linux Shell种类非常多,常见的SHELL如下:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
不同的Shell语言的语法有所不同,一般不能交换使用,最常用的shell是Bash,也就是Bourne Again Shell。Bash由于易用和免费,在日常工作中被广泛使用,也是大多数Linux操作系统默认的Shell环境。
Shell、Shell编程、Shell脚本、Shell命令之间都有什么区别呢?简单来说Shell是一个整体的概念,Shell编程与Shell脚本统称为Shell编程,Shell命令是Shell编程底层具体的语句和实现方法。
Shell脚本编程需要如下几个事项:
- Shell脚本名称命名一般为英文、大写、小写(自动化部署 -- +时间戳 date +%F); auto-install-nginx.sh 2_autoXXXX
- 不能使用特殊符号、空格来命名;
- Shell脚本后缀以.sh结尾;
- 不建议Shell命名为纯数字,一般以脚本功能命名。
- Shell脚本内容首行需以#!/bin/bash开头; --》 指定时bash shell进行解释运行 & /usr/bin/env python -- python脚本 autu_install.py
- Shell脚本中变量名称尽量使用大写字母,字母间不能使用“-”,可以使用“_”; VERSION_NEW
- Shell脚本变量名称不能以数字、特殊符号开头
如下为第一个Shell编程脚本,脚本名称为:first_shell.sh,代码内容如下:
#!/bin/bash #This is my First shell #By author thinkmo echo “Hello World ”
First_shell.sh脚本内容详解如下:
#!/bin/bash 固定格式,定义该脚本所使用的Shell类型; #This is my First shell #号表示注释,没有任何的意义,SHELL不会解析它; #By author thinkmo 表示脚本thinkmo创建人,#号表示注解; echo “Hello World !” Shell脚本主命令,执行该脚本呈现的内容。
Shell脚本编写完毕,如果运行该脚本,运行用户需要有执行权限,可以使用chmod o+x first_shell.sh赋予可执行权限。然后./first_shell.sh执行即可,还可以直接使用命令执行: /bin/sh first_shell.sh直接运行脚本,不需要执行权限,最终脚本执行显示效果一样。
Shell编程之变量详解
Shell是非类型的解释型语言,不像C++、JAVA语言编程时需要事先声明变量,Shell给一个变量赋值,实际上就是定义了变量,在Linux支持的所有shell中,都可以用赋值符号(=)为变量赋值,Shell变量为弱类型,定义变量不需要声明类型,但在使用时需要明确变量的类型,可以使用Declare指定类型(整形int 字符型char 字符串string 浮点型float),Declare常见参数有:
== 等于
= 赋值
+/- "-"可用来指定变量的属性,"+"为取消变量所设的属性; -f 仅显示函数; r 将变量设置为只读; x 指定的变量会成为环境变量,可供shell以外的程序来使用; i 指定类型为数值,字符串或运算式。 |
Shell编程中变量分为三种,分别是系统变量、环境变量和用户变量,其中系统变量在对参数判断和命令返回值判断时使用,而环境变量则主要是在程序运行时需要设置,用户变量又称为局部变量,多使用在Shell脚本内部或者临时局部使用
shell定义变量规则
Shell变量名在定义时,首个字符必须为字母(a-z,A-Z),不能以数字开头,中间不能有空格,可以使用下划线(_),不能使用(-),也不能使用标点符号等。
例如定义变量A=thinkmo,定义这样一个变量,A为变量名,thinkmo是变量的值,变量名有格式规范,变量的值可以随意指定。变量定义完成,如需要引用变量,可以使用$A。
调取变量尽量加上花括号
xx=sdasd ${xx}kkkv 这样就能在一堆字符串中识别变量xx
如下脚本var.sh脚本内容如下:
#!/bin/bash #By author thinkmo A=123 echo “Printf variables is $A.”
SHELL编程特殊位置系统变量:
$0 当前脚本的名称; $n 当前脚本的第n个参数,n=1,2,…9; 这个就是脚本的后面比如: [root@zabbix /]# vim xx.sh 这样应该很清楚,添加$1就表示在脚本后面添加任何东西输出 #!/bin/bash Kk='systemctl restart nginx' 两个以上定义$n要加花括号{ }比如 echo $1 [root@zabbix /]# sh xx.sh baba baba $* 当前脚本的所有参数(不包括程序本身); $# 当前脚本的参数个数(不包括程序本身); [root@zabbix /]# vim xx.sh #!/bin/bash echo $1 $2 $3 $4 echo $# [root@zabbix /]# sh xx.sh 1 2 3 用于统计你输入了几个参数,但不管你脚本里定义了几个 1 2 3 4 3 [root@zabbix /]# vim xx.sh 可以用于判断参数数量是否输入正确 #!/bin/bash if [ $# -ne 2 ];then echo "Usage:请输入两个参数" exit 1 fi echo $1 $2 $3 $4 echo $# [root@zabbix /]# sh xx.sh 1 2 1 2 2 [root@zabbix /]# sh xx.sh 1 2 3 4 Usage:请输入两个参数 $? 命令或程序执行完后的状态,返回0表示执行成功;不成功非0 $$ 程序本身的PID号。 [root@zabbix /]# vim xx.sh #!/bin/bash echo $$ > /tmp/nginx.pid sleep 30 放到后台运行30s 执行一下看看 [root@zabbix /]# sh xx.sh 1 2 & 这个&号忘记了什么意思,后面再查,不加执行不了 [1] 77652 [root@zabbix /]# ps -ef|grep sh root 77652 74631 0 23:57 pts/2 00:00:00 sh xx.sh 1 2 [root@zabbix /]# kill -9 `cat /tmp/nginx.pid`
SHELL编程常见环境变量:
PATH 命令所示路径,以冒号为分割; HOME 打印用户家目录; SHELL 显示当前Shell类型; USER 打印当前用户名; ID 打印当前用户id信息; PWD 显示当前所在路径; TERM 打印当前终端类型; HOSTNAME 显示当前主机名。
关于父shell与子shell
在命令行输入一个bash就会进入一个子shell
执行一下操作
[root@zabbix /]# vim xx.sh #!/bin/bash Kk=`whoami` [root@zabbix /]# sh xx.sh 请问输出的值是什么? [root@zabbix /]# echo $Kk
答案,空行 [root@zabbix /]# echo $Kk [root@zabbix /]#
要想执行成功 [root@zabbix /]# source xx.sh [root@zabbix /]# echo $Kk root
父shell继承不了子shell,要想要父shell基础要使用source
有时候脚本执行没反应,可能就是这个原因
关于shell脚本中的符号
反引号 ` ` 执行脚本命令
单引号 ' ' 所见及所得 不对内容进行解析
如果想要在脚本中直接执行要加单引号 ' '不能用反引号,比如,
#!/bin/bash Kk='systemctl restart nginx' 如果用反引号没有任何结果
变量传参的方式
一:直接赋值
#!/bin/bash IP=10.0.0.1 echo $IP
二:在脚本外定义变量,脚本中使用
#!/bin/bash IP=$xxx echo $IP
三:read方式
#!/bin/bash read -p "给用户展示" a echo $a #!/bin/bash -t 5秒后不执行自动退出 read -t 5 -p "给用户展示" 变量名 echo $a #!/bin/bash read -t 5 -p "给用户展示" 变量名1 变量2 多个参数就这样 echo $a $b
- 案例一:
#!/bin/bash data_dir=/data/backup read -p "请输入要备份的目录: " data_dir2 tar zcf ./xx.tar.gz $data_dir $data_dir2
- 案例二:
[root@zabbix /]# vim xx.sh read -p "请输入一个IP地址: " IP ping -c 3 $IP &>/dev/null echo $? [root@zabbix /]# sh xx.sh 请输入一个IP地址: 172.16.1.7 0
使用read命令修改主机名和IP地址
[root@zabbix /]# vim xx.sh #!/bin/bash nowip=`hostname -I|awk -F "[. ]+" '{print $4}'` ethfile=/etc/sysconfig/network-scripts/ifcfg-eth0 read -p "请输入一个主机名称: " HOST hostnamectl set-hostname $HOST read -p "请输入IP地址的主机位: " IP sed -i "s#$nowip#$IP#g" $ethfile
取字符串的长度
[root@zabbix /]# Kk="wo shi ni ba" [root@zabbix /]# echo ${Kk} wo shi ni ba 计算变量的长度 方法一: [root@zabbix /]# echo ${#Kk} 12 方法二: [root@zabbix /]# echo ${Kk}|wc -L 这里是一行用L 12 方法三: [root@zabbix /]# expr length "$Kk" 12
取出长度小于3的字符串
变量的切片
[root@zabbix /]# echo ${Kk}
wo shi ni ba
[root@zabbix /]# echo ${Kk:3:3} 重1开始数,第三个字符后面取三个,第三个字符取不到
shi
[root@zabbix /]# echo ${Kk:4:2} 从1开始,第四个字符往后取两个,第四个字符取不到
hi
取出长度小于2的字符串
方法一:
[root@zabbix /]# echo ${Kk}|xargs -n1|awk '{if(length<3)print}'
wo
ni
ba
方法二:
#!/bin/bash
for i in wo shi ni ba
do
if [ ${#i} -lt 3 ];then
echo $i
fi
done
[root@zabbix /]# sh xx.sh
wo
ni
ba
变量的删除
# 从左往右删除
% 从右往左删除 要把*号放在最右边
[root@zabbix /]# url=www.hebbao.com [root@zabbix /]# echo ${url} www.hebbao.com [root@zabbix /]# echo ${url#*.} *后面根.表示删除到点符号为止 hebbao.com [root@zabbix /]# echo ${url##*.} 贪婪删除 com [root@zabbix /]# echo ${url%.*} www.hebbao [root@zabbix /]# echo ${url%%.*} www
变量的替换
[root@zabbix /]# echo $url www.hebbao.com [root@zabbix /]# echo ${url/hebbao/xxx} www.xxx.com 贪婪替换 [root@zabbix /]# echo ${url//hebbao/xxx} www.xxx.com
变量自增
a++ 就是先赋值在运算
++b 就是先运算在赋值
[root@web01 ~]# a=1 [root@web01 ~]# b=1 [root@web01 ~]# let x=a++ [root@web01 ~]# let y=++b [root@web01 ~]# echo $a 2 [root@web01 ~]# echo $b 2
示例:
[root@web01 ~]# vim i++.sh #!/bin/bash i=1 while [ $i -le 4 ] do ping -c 1 www.baidu.com &>/dev/null if [ $? = 0 ];then echo "ping tong $i" else echo "no" fi let i++ done
数值的运算
整数运算
expr,bc,$(( )),$[ ],python,awk
效率最高的是$(())
expr
[root@web01 ~]# expr 1+1 1+1 [root@web01 ~]# expr 1 + 1 2 [root@web01 ~]# expr 1 - 1 0 [root@web01 ~]# expr 1 * 1 expr: syntax error [root@web01 ~]# expr 1 \* 1 1 [root@web01 ~]# expr 1 / 1 1 [root@web01 ~]# expr 1 / 2 0
expr计算字符串的长度
[root@web01 ~]# expr length sdfeq 5 [root@zabbix /]# expr length "$Kk" 12
示例:
[root@web01 ~]# vim expr.sh #!/bin/bash while true do read -p "请输入一个整数: " x expr $x + 2 &>/dev/null if [ $? -ne 0 ];then echo "请输入一个整数: " else echo "正确" break fi done
$[ ]
[root@web01 ~]# echo $[1+1] 2 [root@web01 ~]# echo $[1-1] 0 [root@web01 ~]# echo $[1*1] 1 [root@web01 ~]# echo $[2*2] 4 [root@web01 ~]# echo $[2/2] 1
既能做整数运算的又能做小数运算的
bc,awk,python
awk
[root@web01 ~]# awk 'BEGIN{print 1+1}' 2 [root@web01 ~]# awk 'BEGIN{print 1+1.5}' 2.5 [root@web01 ~]# awk 'BEGIN{print 1-1.5}' -0.5 [root@web01 ~]# awk 'BEGIN{print 1*1.5}' 1.5 [root@web01 ~]# awk 'BEGIN{print 1/1.5}' 0.666667
不用BEGIN模块
[root@web01 ~]# echo 1.6 5.8|awk '{print $1+$2}' 7.4
习题:
用脚本实现一个加键乘除的计算器
[root@web01 ~]# vim jsq.sh #!/bin/bash read -p "xxx: " x c echo $x $c|awk '{print $1+$2}' [root@web01 ~]# sh jsq.sh xxx: 88 88 176
继续阅读

我的微信
这是我的微信扫一扫
评论