Shell 脚本概述
通过 Shell 中的各种命令, 开发者和运维人员可以对服务器进行维护工作。
但每次都手动输入命令, 工作效率太低, 而且很容易出错, 尤其是需要维护大量服务器时。
为了能够对服务器批量执行操作, 我们可以将需要执行的命令写入文件, 批量执行, 这种文件便是 Shell 脚本。
Shell 脚本一般是以 .sh 结尾的文本文件, 当然, 也可以省略扩展名
Shell 脚本首行 Shebang
脚本文件第一行通过注释的方式指明执行脚本的程序。
在 Shell 脚本中, # 开头的文本是注释, 但第一句 #! 开头的这句话比较特殊, 他会告诉 Shell 应该使用哪个程序来执行当前脚本。
常见方式有:
#!/bin/sh 开头的文件,程序在执行的时候会调用/bin/sh,也就是bash解释器
#!/bin/bash
#!/usr/bin/env bash
Python 脚本的第一句一般是 #!/usr/bin/env python 开头的文件,代表指定python解释器去执行
第一个脚本
echo:用来输出内容
#!/bin/bash
echo "hello"
echo "当前登录`whoami`"
echo `ls`
echo 'dyk'
exit 0
执行脚本
bash 文件名.sh
bash firstshell.sh
source ./文件名.sh
source ./firstshell.sh
./文件名.sh
但是首先文件必须要有可执行权限
chmod a+x firstshell.sh
./firstshell.sh
变量
注意赋值前后没有空格
变量名规则
名称定义要做到见名知意,切按照规则来,切不得引用保留关键字(help检查保留字)
只能包含数字、字母、下划线
不能以数字开头
不能用标点符号
变量名严格区分大小写
即 不能像 a = 123
a=123
b=xyz
echo "$a"
echo "$b"
$使用
使用变量时, 变量名前面加上 $ 符
${变量名}
取变量的值
${var}用来获取一个变量的值,一般情况下,大括号可以省略不写
#!/bin/bauh
a=123
b=xyz
echo "$a"
echo $a
echo ${a} #大括号取值
注意 引号 的差别
#!/bin/bauh
a=123
b=xyz
echo "$a"
echo '$b'
运行结果
123
$b
$(命令)
可以执行命令
#!/bin/bauh
echo $(whoami) #等价于反引号
$((表达式))
计算表达式
#!/bin/bauh
echo $((1+1))
运行结果 2
特殊的值
值 | 作用 |
---|---|
$0 | 表示脚本文件的名字 |
$1 - $n | 表示第一个到第n个参数 |
$* | 表示所有参数 |
$@ | 表示所有参数 |
$# | 表示参数的个数 |
$? | 表示脚本执行的结果 ,0表示执行完成正常退出 |
Linux 中的所有程序执行结束后都有状态码
状态码为 零 表示正常, 状态码为 正整数 代表异常退出
#!/bin/bauh
echo $0
echo $1
echo $2
echo $*
echo $@
echo $#
echo $?
运行结果
bash firstshell.sh dyk 666
firstshell.sh 脚本名称
dyk 参数一
666 参数二
dyk 666 所有参数
dyk 666
2 参数个数
0 正常执行
定义当前Shell下的全局变量
#!/bin/bauh
export a=999
在终端里用 source 加载脚本
source ./firstshell.sh
echo ${a}
结果999
常用的系统环境变量
$PATH: 可执行文件目录
$PWD: 当前目录
$HOME: 家目录
$USER: 当前用户名
$UID: 当前用户的 uid
获取用户输入
#!/bin/bauh
read -p "请输入要输入的内容" msg
echo "您输入的是" $msg
脚本里的引号
在shell里支持三种引号,它们的使用场景以及效果会有差异。
反引号:里面的内容会被解析成为脚本
echo `ls -a` # 打印 当前目录下的所有文件和文件夹
双引号:它里面的大部分内容会别原样显示,但是如果是一个变量,这个变量会被解析
name=dyk
echo "我是$name" #我是dyk
单引号:它里面的内容会完全原样输出,就算是有变量,也不会被解析
name=dyk
echo '我是$name' #我是$name
分支语句: if
分支控制语句完整格式为:
if command;then
commands
elif command;then
commands
else
commands
fi
if 语句检查判断的依据实际上是, 后面所跟的命令的状态码: 0 为 true, 其他值 为 false
#!/bin/bauh
if ls -la;then
echo "ok"
else
echo "no"
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 |
字符串比较
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 |
文件比较
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旧 |
case语句
case "$var" in
exp1)
command1
;;
exp2)
command2
;;
exp3)
command3
;;
*)
comman4
;;
esac
#!/bin/bash
read -p "请输入数字" num
case $num in
0)
echo 星期日
;;
1)
echo 星期一
;;
2)
echo 星期二
;;
3)
echo 星期三
;;
4)
echo 星期四
;;
5)
echo 星期五
;;
6)
echo 星期六
;;
*)
echo 其他
;;
esac
循环语句: for
for 循环的基本格式:
for 变量 in 序列
do
要执行的命令
done
打印1到10
#!/bin/bauh
for i in `seq 1 10`
do
echo $i
done
#!/bin/bauh
for ((i=1;i<=10;i++))
do
echo $i
done
seq START END 语句用来产生一个数字序列
$[ NUM1 + NUM2 ] 语句用来进行基本的数学运算
[[ … ]] 语句用来更方便的进行比较判断