shell脚本基础
变量
什么是变量?
变量可以通过变量名访问,变量通常是可以变化的量
变量名称注意事项
只能包含字母、数字、下划线,并且不能以数字开头
[root@localhost ~]# a_3=4
[root@localhost ~]# echo $a_3
4
[root@localhost ~]# 3_a=4
-bash: 3_a=4: 未找到命令
不应该跟系统中已有的环境变量重名,尽量不要全部使用大写,尽量不要用“_”下划线开头
//系统角色都是大写字母组成
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
做到见名知义
[root@localhost ~]# IU_1=28
[root@localhost ~]# echo $IU_1
28
不能使用程序中的保留字,例如if、for等
变量类型
字符型
- 含义:字符串类型
数值型
-
整型:整数
-
浮点型:包含小数
布尔型
- true:条件为真
- false:条件为假
变量操作
//设置变量
[root@localhost ~]# a=10
//引用变量
[root@localhost ~]# echo $a
10
//撤销变量
[root@localhost ~]# unset a
[root@localhost ~]# echo $a
[root@localhost ~]#
//变量和单引号、双引号的关系
[root@localhost ~]# a=10
[root@localhost ~]# echo "$a"
10
[root@localhost ~]# echo '$a'
$a
[root@localhost ~]#
bash变量类型
本地变量
本地变量,作用域为当前shell进程。对当前shell外的其它shell进程,包括当前shell的父shell、子shell进程均无效,只能当前有效
[root@localhost ~]# yum -y install psmisc
[root@localhost ~]# iu=100
[root@localhost ~]# echo $iu
100
[root@localhost ~]# pstree
├─sshd───sshd───sshd───bash───pstree
[root@localhost ~]# bash
[root@localhost ~]# pstree
├─sshd───sshd───sshd───bash───bash───pstree
[root@localhost ~]# echo $iu
[root@localhost ~]#
环境变量
作用域为当前shell进程及其子进程
[root@localhost ~]# export iu=100
[root@localhost ~]# echo $jjyy
100
[root@localhost ~]# pstree
├─sshd───sshd───sshd───bash───bash───pstree
[root@localhost ~]# bash
[root@localhost ~]# pstree
├─sshd───sshd───sshd───bash───bash───bash───pstree
[root@localhost ~]# bash
[root@localhost ~]# echo $jjyy
100
[root@localhost ~]# pstree
├─sshd───sshd───sshd───bash───bash───bash───bash───pstree
常用:指定路径
echo 'ecport PATH=/usr/local/apache/bin:$PATH' > /etc/profile.d/httpd.sh
source /etc/profile.d/httpd.sh 重新读取使其生效
功能说明:以树状图显示运行的程序。
语法:pstree [-acGhlnpuUV][-H <程序识别码>][<程序识别码>/<用户名称>]
补充说明:pstree指令用ASCII字符显示树状结构,清楚地表达程序间的相互关系。如果不指定程序识别码或用户名称,则会把系统启动时的第一个程序视为基层,并显示之后的所有程序。若指定用户名称,便会以隶属该用户的第一个程序当作基层,然后显示该用户的所有程序。
参数:
-a 显示每个程序的完整指令,包含路径,参数或是常驻服务的标示。
-c 不使用精简标示法。
-G 使用VT100终端机的列绘图字符。
-h 列出树状图时,特别标明现在执行的程序。
-H <程序识别码> 此参数的效果和指定”-h”参数类似,但特别标明指定的程序。
-l 采用长列格式显示树状图。
-n 用程序识别码排序。预设是以程序名称来排序。
-p 显示程序识别码。
-u 显示用户名称。
-U 使用UTF-8列绘图字符。
-V 显示版本信息。
位置变量
用来引用脚本的参数
[root@localhost ~]# vim test.sh
[root@localhost ~]# chmod +x test.sh
[root@localhost ~]# sed -n '1,2p' test.sh
#!/bin/bash
echo $1 $3 $4 $2
[root@localhost ~]# ./test.sh 9 8 7 5
9 7 5 8
位置变量使用完以后退出,后面的参数向前推进
shift [num]
特殊变量
$#:是传给脚本的参数的个数
[root@localhost ~]# vim test.sh
[root@localhost ~]# sed -n '1,2p' test.sh
#!/bin/bash
echo $#
[root@localhost ~]# ./test.sh 1 1 1
3
$0:是脚本本身的名字
[root@localhost ~]# vim test.sh
[root@localhost ~]# sed -n '1,2p' test.sh
#!/bin/bash
echo $0
[root@localhost ~]# ./test.sh 1 1 1
./test.sh
$@:是传给脚本的所有参数的列表
//@和*的区别:单独个体存放,一个一个取
[root@localhost ~]# vim test.sh
[root@localhost ~]# sed -n '1,2p' test.sh
#!/bin/bash
echo $@
[root@localhost ~]# ./test.sh 1 2 5 6 9 8 7 1
1 2 5 6 9 8 7 1
$*:是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
//@和*的区别:当初一个整体存放,在一个一个取
[root@localhost ~]# vim test.sh
[root@localhost ~]# sed -n '1,2p' test.sh
#!/bin/bash
echo $*
[root@localhost ~]# ./test.sh 1 2 5 6 9 8 7 1
1 2 5 6 9 8 7 1
-
$! :是shell最后运行的后台Process的PID
-
$$:是脚本运行的当前进程ID号
-
$?:是显示上条命令的退出状态,0表示没有错误,其他表示有错误
[root@localhost ~]# vim test.sh
[root@localhost ~]# sed -n '1,3p' test.sh
#!/bin/bash
ls
ls shaoyaobang
[root@localhost ~]# sed -n '1,4p' test.sh
#!/bin/bash
ls
ls shaoyaobang
echo $?
[root@localhost ~]# ./test.sh
anaconda-ks.cfg haproxy test.sh
ls: 无法访问'shaoyaobang': 没有那个文件或目录
2
[root@localhost ~]# echo $?
0
bash内建环境变量
PATH:系统里面所有命令查找的位置
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]#
SHELL:当前用的shell是什么,可以修改配置文件修改当前shell
[root@localhost ~]# echo $SHELL
/bin/bash
[root@localhost ~]# usermod -s /bin/sh root
[root@localhost ~]# echo $SHELL
/bin/sh
UID:当前用户的uid
[root@localhost ~]# echo $UID
0
[root@localhost ~]# id root
uid=0(root) gid=0(root) 组=0(root)
HISTSIZE:命令历史的长度
[root@localhost ~]# echo $HISTSIZE
1000
[root@localhost ~]#
HOME:当前用户的家目录
[root@localhost ~]# echo $HOME
/root
[root@localhost ~]#
PWD:当前所在的位置
[root@localhost etc]# echo $PWD
/etc
[root@localhost etc]#
HISTFILE:命令历史报存到那个文件去了
[root@localhost etc]# echo $HISTFILE
/root/.bash_history
[root@localhost etc]#
PS1:定义命令提示符的样式
[root@localhost etc]# echo $PS1
[\u@\h \W]\$
[root@localhost etc]# PS1='\W'
etcPS1='[\u@\h \W]\$'
[root@localhost etc]#
只读变量(常量)
不能修改值,不能销毁,只能等shell进程终止时随之消亡
[root@localhost etc]#readonly uu=666
[root@localhost etc]#echo $uu
666
[root@localhost etc]#uu=777
bash: uu: 只读变量
[root@localhost etc]#unset uu
bash: unset: uu: 无法取消设定: 只读 variable
脚本基础
脚本的含义
按实际需要,结合命令流程控制机制实现的源程序。说白点就是命令的堆砌。
程序返回值
- 程序执行以后有两类返回值:
- 程序执行的结果
- 程序状态返回代码(0-255)
- 0:正确执行
- 1-255:错误执行,1、2、127系统预留,有特殊意义
脚本测试
bash -n scriptname:检查脚本是否有语法错误
[root@localhost ~]#vim test.sh
[root@localhost ~]#cat test.sh
#!/bin/bash
sl dahdagda
ls /etc/sysconfig/network-scripts
if jsdkasl
[root@localhost ~]#bash -n test.sh
test.sh:行5: 语法错误: 未预期的文件结尾
bash -x scriptname:单步执行,检查脚本错在哪里(排查)
[root@localhost ~]#bash -x test.sh
1. sl dahdagda
test.sh:行2: sl: 未找到命令
2. ls /etc/sysconfig/network-scripts
ifcfg-ens160
test.sh:行5: 语法错误: 未预期的文件结尾
写脚本注意事项
- 禁止将未成功执行过的代码直接写入脚本
- 脚本中的命令一定要写绝对路径
shell算数运算
let C= $ A+$B :let 算术运算表达式
[root@localhost ~]# cat boat.sh #加法
#!/bin/bash
let a=$1+$2
echo $a
[root@localhost ~]# bash boat.sh 1 2
3
[root@localhost~]# cat boat.sh #减法
#!/bin/bash
let a=$1-$2
echo $a
[root@localhost~]# bash boat.sh 9 1
8
[root@localhost ~]# cat boat.sh #乘法
#!/bin/bash
let a=$1*$2
echo $a
[root@localhost ~]# bash boat.sh 1 5
5
[root@localhost ~]#
[root@localhost ~]# bash boat.sh
2.50
[root@localhost ~]# cat boat.sh
#!/bin/bash
echo 'scale=2;5/2' | bc #scale保留几位小数,bc需要下载
C=$ [$ A+$ B] :$ [算术运算表达式]
[root@localhost ~]#a=$((33+4)) # +/-/*/(/)
[root@localhost ~]#echo $a
37
C=expr $A + $B :expr 算术运算表达式,表达式中各操作数及运算符之间要有空隔,而且要使用命令引用
[root@localhost ~]#vim test.sh
[root@localhost ~]#cat test.sh
#!/bin/bash
a=`expr $1 + $2`
echo $a
[root@localhost ~]#./test.sh
expr: syntax error: missing argument after “+”
[root@localhost ~]#./test.sh 2 3
5
命令的逻辑关系
-
逻辑与:&& 两个条件必须都为真,输出才为真
- 第一个条件为假时,第二个条件不用再判断,最终结果已经有
- 第一个条件为真时,第二个条件必须得判断
-
逻辑或:|| 两个条件有一个为真,输出才为真
- 前一个命令的结果为真时,第二个命令就不执行
- 前一个命令的结果为假时,第二个命令必须执行