Linux04 Shell编程一
认识Shell脚本
概念
- Shell脚本是包含一系列命令的文本文件。
- Shell读取此文件并执行命令。
- 翻译命令环境的位置:
/bin/bash(Bash解释器的位置) |/bin/sh(Shell解释器的位置)。
应用场景
- 重复性操作。
- 批量事务处理。
- 自动化运维。
- 定时任务执行。
示例
- 在多台服务器上定期备份文件(1+4)。
- 编写脚本扫描某个目录中的文件并进行特定操作(2)。
- 编写脚本来自动监测服务器性能、清理临时文件、更新软件包、管理用户账户等(3)。
如何实现个性化安装?
- 先构建一个安装的脚本
install.sh。 install.sh指定的虚拟机名称(如果没有指定虚拟机则对全部虚拟机执行)。
vim
安装
yum -y install vim-enhanced.x86_64
将缩进设置为4位
vim /etc/vimrc
:set tabstop=4
:set softtabstop=4
:set shiftwidth=4
编写脚本
#!/bin/bash # #!用于告诉系统脚本需要什么解释器来执行
echo "Hello world"
运行Shell脚本
同步与异步的区别
- 异步指程序的执行不按照严格的顺序,通常用于多任务处理。此处适用于在后台运行的长时间任务。
- 同步指程序的执行需按照严格的顺序,此处适用于影响当前环境的配置任务。
异步执行
/bin/sh test.sh
/bin/bash test.sh
./test.sh # 在test.sh先在第一行写!/bin/bash + chmod u+x test.sh
- 当频繁执行一个脚本时,授予其执行权限并用./执行。
同步执行
source test.sh # 在当前bash环境下执行,不需要授权
变量
定义变量
varA=Hello|"Hello"- 判断值是否需要使用
""括起来:- 简单值或数字时不需要:
varA=Hello varB=42 - 值包含空格或特殊字符,变量替换时需要:
varA="Hello World"varA="$varB"
- 简单值或数字时不需要:
- 不需要声明变量,等号前后不能有空格,变量用完之后需要撤销变量。
- 变量的命名按照驼峰原则。
撤销变量
unset varA
将命令结果分配给变量
varA=`ls -l`
变量拼接
echo "info : $a"
${}
$表示提取。{}用来锁定变量名边界,若边界无需锁定可缺省。${MYTEST}直接使用环境变量。
作用域
- 全局变量:当前的整个Shell会话中有效。
- 局部变量:只能在函数内部使用。
- 环境变量:可以在其它Shell中使用。如系统级:
$PATH,用户级:$JAVA_HOME。
类别
- 系统变量
- 自定义变量
输出Java的环境变量
echo $PATH | awk '{split($0,a,":"); for(i in a){if(match(a[i],"jdk")) print(a[i])}}'
位置变量$n
$0用于获取当前脚本文件名称。$1~$9获取第1输入参数到第9输入参数。${10}获取第10输入参数。
预定义变量
$#命令行参数或位置参数的数量。如./test.sh arg1 arg2 arg3 => test.sh内 echo $# => 3。$?最近一次执行的命令或shell脚本的返回值(0表示没有错误,其他任何值表明有错误 不写默认为0)。$*|$@表示所有的位置参数。- `$$` 变量是shell脚本里面的进程ID。 ```bash # var_test.sh # 参数数量 argCount=$# # 所有变量 allArgs=$* # 当前脚本执行时进程号 proNo=$$
序(编)号参数
if [ "$1" ];then
echo -e "INFO : ${argCount}\t$proNo"
echo "ARGS : $allArgs"
exit 0
else
exit 1
fi
### read读取控制台输入
```bash
read [选项][参数]
-p 后面跟提示信息,即在输入前打印提示信息
-t 后面跟秒数,定义输入字符的等待时间
read -t 30 -p "Please enter your name in 30 seconds:" NAME
echo $NAME
表示用户在30秒内需要输入名字,名字会存储在NAME变量中,并会将他们的名字打印。
Shell算术表达式和算术运算符
表达式
let c=a+bc=$[a+b]c=$((a+b))
特殊:c=$[(1+3)/(2+3)] ✔ let c = (1+3)/(2+3) ❌
②和③都不存在以上的let错误。
如果a='5', b=2, let c=a+b之后c的结果为7。
如果c="$a+$b",实现了字符串拼接。
运算符
+ - * / % = == !=+= -=( let ++a|((++a))|((a=a+1)) )
Shell条件表达式
[ 条件表达式 ]如[ $a == 5 ]三个以上逻辑表达式会报警告。- 条件成立时,返回true,否则返回false。
=~通常用于正则匹配,[]不可用,[[]]可用。- 示例:判断压缩包的后缀名
if [[ !"$pack" =~ ^.*jdk.*(tar\.gz|tgz)$ ]]; then
Shell关系运算符
关系运算符只支持数字,返回true或false。
-eqequal to-nenot equal to-gtgreater than-ltless than-leless than or equal to-gtgreater than-gegreater than or equal to
示例:[ -1 -eq 1 ] => false
Shell逻辑运算符
&&||用于[]外或[[ ]]内-a-o用于[]内- 示例:
[1 -eq 2 -a 2 -gt 1][[1 -eq 2 && 2 -lt 3]]或者[1 -eq 2] && [2 -lt 3]
Shell字符串运算符
==!=-n: 不为空时为真-z: 为空时为真
Shell文件操作符
-d判断是否为目录-e判断目录或文件是否存在-f判断是否为文件-r-w-x判断读写执行权限是否存在
Shell三元运算符语法
- 逻辑表达式
&& echo yes || echo no=> 返回true则输出yes,返回false则输出no
流程控制 - if判断
if [ command ];then
# 符合该条件执行的语句
elif [ command ];then
# 符合该条件执行的语句
else
# 符合该条件执行的语句
fi
流程控制 - case
case多分支条件判断
- 模式匹配
[A-Z]一个大写字母[a-z]一个小写字母[0-9]一个数字?一个任意字符*一个任意字符串
- 注意:大小写分开识别,必须大写在前,小写在后,否则统一识别为小写。
case $1 in
"1")
echo "你输入的数字是1"
;;
"2")
echo "你输入的数字是2"
;;
*)
echo "你输入的数字是其他"
;;
esac
循环语句 - for循环
for 变量 in 值1 值2 值3 ... | 字符串 | {
1..100(..2)} # (步长为2)从1到100
do
...
done
示例:
for arg in "$@"
do
echo "arg : $arg"
done
STRING = "Hello world henry"
for var in $STRING
do
echo "var:$var"
done
for((初始值;循环控制条件;变量变化))
do
...
done
示例:
for((i=1;i<=10;i++))
do
echo $[$i*3+1]
done
循环语句 - while循环
while [ 条件表达式 ]
do
...
done
continuebreak同Java
示例:
i=1
sum=0
while [ $i -le 10 ]
do
sum=`$[sum+i]`
((++i))
done
echo "sum=$sum,i=$i"
补充
seq用于生成从一个数到另一个数之间的所有整数。- 示例:
seq 1 5或seq 5生成数字1到5。
数据类型
字符串
henry不支持有空格的情况varA=henry''只输出原文,不输出变量varA='henry pola'""输出原文和变量varB="steven $varA"- ````输出命令执行的结果
布尔
[ true ] && echo yes || echo no该命令用于判断条件表达式结果为真or假- 逻辑短路:
&&只有在前一个值为真值的时候,才会执行后一个命令;||只有在前一个值返回假值的时候,才会执行后一个命令。
练习
打印九九乘法表
for循环
for i in { 1..9} do for j in `seq $i` do echo -en "$[j]*$[i]=$[i*j]\t" done echo donewhile循环
i=1 while [ $i -le 9 ] do j=1 while [ $j -le $i ] do echo -n -e "$i*$j=$[i*j]\t" let j++ done let i++ echo " " done
后台运行Shell脚本
- 对守护进程而言,只需在后面加上
&就能使其在后台自动运行。但对于非守护进程而言,则需要加上nohup命令使其能够在后台运行。 让程序后台运行
nohup /root/test.sh &让程序后台运行,并存储运行输出到指定文件
nohup COMMAND | SHELL_SCRIPT > out.file 2>&1 &Shell exit命令
exit用来退出当前Shell进程,并返回一个退出状态。exit命令可以接受一个整数值作为参数,代表退出状态;如果不指定,默认状态值是 0exit退出状态只能是一个介于 0~255 之间的整数(可以通过指定状态区分不同类型的错误),其中只有 0 表示成功,其它值都表示失败echo $?输出退出状态
Shell RANDOM变量
- shell有一个环境变量
RANDOM,范围是0--32767 产生0-25范围的数:
$[RANDOM%26]产生1-68范围的数:
$[RANDOM%68+1]
编写shell 脚本
- 要求统计
/var/log目录下有多少个文件,并显示这些文件名
Shell数组
- 数组中可存放多个值,初始化时不需要定义数组大小
- 数组元素的下标由0开始
Shell 数组用括号来表示,元素用"空格"符号分割开来
ARRAY_NAME=(VALUE1 ... VALUEN)获取数组元素
${MY_ARRAY[0]}获取数组中所有数组元素
${MY_ARRAY[@]}
Shell函数
- 函数定义
①function fun()
②fun() 小括号不带任何参数
函数调用
FUNC_NAME ARG1 ARG2...
- Shell并不指明定义与调用的顺序。
- 返回值:为0-255之间的证书,可以显式加
return返回,缺省默认为0,等同于exit - 返回值扩展:通过
var=\func args...`将函数内所有输出内容存到变量var` - 一个function最多只能有一个
return - 例:设计一个计算所有参数总和的函数
function getsum(){ local sum=0 for n in $@ do ((sum+=n)) done return $sum } getsum 10 20 55 15 #调用函数并传递参数 echo $?
TMOUT 超时设定
TMOUT=5# 设置用户输入的超时限制为5秒read -p "请输入数值:" num# 显示提示并等待用户输入- 如果用户输入成功,显示输入的数值
if [ $? -eq 0 ];then echo "你输入的数值为: $num" else echo "输入超时:5秒" fiping发送网络请求 -c [数量]表示发送对应数量的请求-W [时间长度]表示指定了等待主机响应的最长时间- 例:
ping -c 1 -W 1 &>/dev/null