shell编程与运维
一、Shell脚本概述
通过shell中的各种命令,开发者和运维人员可以对服务器进行维护工作。 但每次都手动输入命令,工作效率太低,而且很容易出错,尤其是需要维护大量服务器时。 为了能够对服务器批量执行操作,我们可以将需要执行的命令写入文件,批量执行,这种文件便是shell脚本。 shell脚本一般是以.sh 结尾的文本文件,当然,也可以省略扩展名。
二、Shell脚本首行
脚本文件第一行通过注释的方式指明执行脚本的程序。 在shell中,#开头的文本是注释,但第一句 #! 开头的这句比较特殊,它会告诉shell应该使用哪个程序来执行当前脚本。 常见方式有:
- #!/bin/sh
- #!/bin/bash
- #!/usr/bin/env bash
Python脚本的第一句一般是 #!/usr/bin/env python
三、第一个脚本
- 创建cpu-count.sh文件
- 将下面文本写入cup-count.sh中
#!/bin/bash
echo "hello"
echo "I am whoami !"
echo "I love Linux"
echo "The Cpu in my PC has `cat /proc/cpuinfo grep -c processor` cores"
exit 0
- 执行 chmod a+x cpu-count.sh 对脚本授予可执行权限
- 输入 ./cpu-count.sh 执行脚本
- 查看脚本的退出状态:echo $?
- Linux 中的所有程序执行结束后都有状态码
- 状态码为 零 表示正常,状态码为 正整数 代表异常退出
四、变量
- 定义
变量的定义与其他语言差距不大,需要注意的是赋值前后没有空格。
a=123456
b=xyz
- 使用
使用变量时,变量名前面加上 $ 符
echo "--$a--\n===$b==="
printf "---$a---\n===$b===\n"
- 注意 引号 的差别
echo "--$a--\n===$b==="
echo '--$a--\n===$b==='
-
定义当前Shell下的全局变量
- 定义:export ABC=9328324892498892489
- 定义完后,在终端里用source加载脚本:source ./test.sh
-
常用的系统环境变量
- $PATH:可执行文件目录
- $PWD:当前目录
- $HOME:家目录
- $USER:当前用户名
- $UID:当前用户的uid
五、获取用户输入
read -p "请输入一个数字:" num
echo "你输入的是:$num"
六、脚本里的引号
在shell里支持三种引号,他们的使用场景以及效果会有差异。
echo `ls -a /home/chris`
- 双引号:它里面的大部分内容会原样显示,但是如果是一个变量,这个变量会被解析。
name=zhangsan
echo "大家好,我是$name"
- 单引号:它里面的内容会完全原样输出,就算是有变量,也不会被解析。
name=zhangsan
echo '大家好,我是%name'
七、脚本里的$
- ${var}用来获取一个变量的值,一般情况下,大括号可以省略不写。
name=zhangsan
echo ${name}
echo $name
$# 代表传入参数的个数
$@ 代表传入参数的列表
$0 代表脚本文件的名字
$1 代表传入的第一个参数,$2,$3...以此类推
$* 以字符串方式显示所有传入的参数
$$ 脚本运行的进程ID
$? 显示最后命令的退出状况,0表示没有错误
- $(cmd)用来执行括号里脚本命令,相当于使用反引号。
echo $(ls /home/chris/Desktop)
- $((expression))用来计算数学表达式expression的值。
echo $((1+1))
八、分支语句:if
分支控制语句完整格式为:
if command;then
commands
elif command;then
commands
else
commands
fi
- if 语句检查判断的依据实际上是,后面所跟的命令的状态码:0为true,其他值为false
if ls /xxx;then
echo 'exists xxx'
else
echo 'not exist xxx'
fi
-
条件测试命令:[ … ]
- shell提供了一种专门用做条件测试的语句 [ … ]
- 这一对方括号本质上是一个命令,里面的条件是其参数,所以 [ 的后面和 ] 的前面必须有空格,否则会报错。
- 它可以进行三种比较
- 用法:
if [ condition ];then
commands
fi
-
条件列表
- 数值比较
Condition | 说明 |
---|
n1 -eq n2 | 检查n1是否与n2相等 | n1 -ge n2 | 检查n1是否大于或等于n2 | n1 -gt n2 | 检查n1是否大于n2 | n1 -le n2 | 检查n1是否小于n2 | n1 -lt n2 | 检查n1是否小于n2 | n1 -ne n2 | 检查n1是否不等于n2 | if [ 3 -gt 2 ];then
echo '3>2'
else
echo '3<2'
fi
- 字符串比较
Condition | 说明 |
---|
str1 = str2 | 检查str1是否和str2相同(注意:等号两边要加空格) | str1 != str2 | 检查str1是否和str2不同 | str1 < str2 | 检查str1是否小于str2(需要使用[[]]) | str1 > str2 | 检查str1是否大于str2(需要使用[[]]) | -n str1 | 检查str1的长度是否为非0(变量需要添加双引号) | -z str1 | 检查str1的长度是否为0 | read -p '输入一段内容' x
read -p '输入一段内容' y
if [ $x = $y ];then
echo '$x等于$y'
else
echo '$x不等于$y'
fi
read -p '输入一段内容' x
read -p '输入一段内容' y
if [ $x != $y ];then
echo '$x不等于$y'
else
echo '$x等于$y'
fi
read -p '输入一段内容' x
read -p '输入一段内容' y
if [[$x>$y ]];then
echo '$x大于$y'
else
echo '$x不大于$y'
fi
- 文件比较
Condition | 说明 |
---|
-d file | 检查file是否存在并且是一个目录 | -e file | 检查file是否存在 | -f file | 检查file是否存在并且是一个文件 | -r file | 检查file是否存在并且可读 | -w file | 检查file是否存在并且可写 | -x file | 检查file是否存在并且可执行 | -s file | 检查file是否存在并且非空 | -O file | 检查file是否存在并且属于当前用户所有 | -G file | 检查file是否存在并且所属组与当前用户相同 | file1 -nt file2 | 检查file1是否比file2新 | file1 -ot file2 | 检查file1是否比file2旧 | read -p '输入一个路径' path
if [ -d $path ];then
echo $path是一个文件夹
else
echo $path不是一个文件夹
fi
九、case语句
case "$var" in
exp1)
command1
;;
exp2)
command2
;;
exp3)
command3
;;
*)
command4
;;
esac
示例:
read -p "请输入数字" num
case $num in
0)
echo "星期日"
;;
1)
echo "星期一"
;;
2)
echo "星期二"
;;
3)
echo "星期三"
;;
4)
echo "星期四"
;;
5)
echo "星期五"
;;
6)
echo "星期六"
;;
esac
十、循环语句:for
Shell中的循环结构有三种:for 、while 和 until,这里重点介绍 for 循环。
- for循环的基本格式:
for 变量 in 系列
do
要执行的命令
done
-
练习:打印1到10的偶数
for i in `seq 1 10`
do
if [ $[ $i % 2 ] == 0 ];then
echo "偶数是$i"
fi
done
for i in `seq 1 10`
do
if [ $(($i%2)) -eq 0 ];then
echo "偶数是$i"
fi
done
-
- seq start end 语句用来产生一个数字系列
-
- $[ num1 +num2 ] 语句用来进行基础的数学运算
-
- [[ … ]] 语句用更方便的进行比较判断
- C语言风格的for循环
for ((i=0;i<10;i++))
do
echo "num is $i"
done
十一、函数
- 函数定义
定义是 function 不是必须的,可以省略
function foo(){
echo '-----------------------'
echo "Hello $1,nice to meet you!"
echo '-----------------------'
}
- 函数的使用
- 在终端或者脚本中直接输入函数名即可,不需要小括号
- 传参也只需将参数加到函数名后面,以空格做间隔,像正常使用命令那样
foo arg1 arg2 arg3 ...
- 函数的参数
bar(){
echo "执行者是 $0"
echo "参数数量是 $#"
echo "全部的参数 $@"
}
十二、数组
数组中科院存放多个值。Bash Shell只支持一维数组(不支持多维数组),初始化时不需要定义数组大小。与大部分编程语言类似,数组元素的下标由0开始。
Shell数组用括号来表示,元素用“空格”符号分割开,语法格式如下:
array_name=(value1 ... valuen)
示例:
arr=(hello good "yes" a 12)
同时;也可以直接使用下标来定义一个数组。
nums[0]=1
nums[1]="good"
nums[2]=yes
使用下标可以直接修改数组里的数据。
names=(hello 12 34 good 8)
echo ${names[0]}
echo ${names[1]}
echo ${names[*]}
echo ${names[@]}
echo ${#names[*]}
echo ${#names[@]}
for n in ${name[*]}
do
echo $n
done
for ((x=0;x<${#names[@]};x++))
do
echo $x
done
|