Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。Shell还是一个功能相当强大的变成语言。
查看 Linux 提供的 Shell 解释器:cat /etc/shells
,其中 sh
是软链接,指向 bash
,CentOS
默认的解析器是 bash
脚本文件格式:#!/bin/bash
开头,表示指定解析器
脚本的执行方式:
bash 脚本路径
或 sh 脚本路径
:这种方式不用赋予 x
权限脚本路径
:当前目录下必须用 ./脚本名
的方式执行,要求必须有 x
权限.
或 source
:无需 x
权限,且不会在当前 shell 中打开一个子 shell 来执行脚本内容。
$HOME
、$PWD
、$SHELL
、$USER
等变量名=变量值
,撤销变量: unset 变量名
,静态变量:readonly 变量
静态变量不能撤销。export 变量名
提升为全局变量,变量名规则:
$n
:n 为数字,$0
代表该脚本名称,$1
- $9
代表第一到第九个参数,十以上的参数需要用大括号包含,如 ${10}
$#
:获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性$*
:这个变量代表命令行中所有的参数,$*
把所有的参数看成一个整体;当被双引号包含时,相当于把所有参数拼成了一个字符串$@
:这个变量也代表命令行中所有的参数,不过 $@
把每个参数区分对待;相当于把所有参数拼成一个集合,只有当被双引号包含时才与 $*
有区别$?
:最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一个命令正确执行;如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确通过 $((运算式))
或 $[运算式]
可以获取并接收一个运算式的值
[linux@CentOS01 ~]$ a=$[1+2+3]
[linux@CentOS01 ~]$ echo $a
6
基本语法:
test condition
[ condition ]
,condition 前后必须有空格常用判断条件:
=
判断相等;用 !=
判断不等符号 | 含义 |
---|---|
-eq | 等于(equal) |
-ne | 不等于(not equal) |
-lt | 小于(less than) |
-le | 小于等于(less equal) |
-gt | 大于(greater than) |
-ge | 大于等于(greater equal) |
[ -r hello.txt ]
判断 hello.txt
有没有读权限-e
文件存在;-f
文件存在并且是常规文件;-d
文件存在并且是一个目录一般可以直接用 $?
来表示上一条条件判断结果,false 为 0,true 为 1;
还可以用 &&
或 ||
来控制多条件判断及语句执行,&&
表示前一条命令执行成功时,才执行后一条命令,||
表示上一条命令执行失败后,才执行下一条命令
if [ 条件判断式 ];then
程序
fi
或者
if [条件判断式]
then
程序
fi
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
case $变量名 in
"值1")
变量值等于值1时执行的程序
;;
"值2")
变量值等于值2时执行的程序
;;
"*")
变量值都不是上述值执行的程序
;;
esac
语法1:
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
语法2:
for 变量 in 值1 值2 值3...
do
程序
done
while [ 条件判断式 ]
do
程序
done
基本语法:read (选项) (参数)
-p
:指定读取值时的提示符-t
:指定读取值时等待的时间(秒)如果-t 不加表示一直等待basename [string / pathname] [suffix]
:取路径里的文件名称,指定了 suffix
会将对应 suffix
去掉dirname 文件绝对路径
:取文件路径的绝对路径目录,不含文件名基本语法:
[function] funcName[()]
{
Action;
[return int;]
}
如
function sum()
{
s=0;
s=$[$1+$2]
echo "$s";
}
经验技巧:
$?
系统变量获得,如果不加 return
返回,将以最后一条命令运行结果;如用 return
,后跟数值 n(0-255)正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。在 Linux 中,grep,sed,awk 等文本处理工具都支持通过正则表达式进行模式匹配
常规匹配:cat a.txt | grep abc
就会匹配所有包含 abc 的行
常用特殊字符
^
:匹配一行的开头,cat a.txt | grep ^a
匹配所有 a 开头的行$
:匹配一行的结束,cat a.txt | grep a$
匹配所有 a 结尾的行.
:匹配一个任意字符,cat a.txt | grep a.b
匹配 aab 、abb 、acb … 的所有行*
:不单独使用,和上一个字符连用,表示匹配上一个字符0次或多次\
:转义字符,如 cat a.txt | grep \$
匹配包含 $ 的行字符区间:[]
[6,8]
:匹配6或者8[6-8]
:匹配一个 6-8 间的数字[0-9]*
:匹配任意长度的数字字符串3[a-z]
:匹配一个 a-z 间的字符[a-c,e-f]
:匹配一个 a-c 或者 e-f 间的字符cut [选项参数] filename
:默认分割符是 \t
选项参数 | 功能 |
---|---|
-f | 列号,提取第几列,可用 , 隔开表示多列 |
-d | 分隔符,按照指定分隔符分割列,默认是制表符 \t |
-c | 按字符进行切割后加 n 表示取第几列,如 -c 1 |
切割 ifconfig 后打印的 IP 地址:
[linux@CentOS01 ~]$ ifconfig ens33 | grep netmask | cut -d " " -f 10
192.168.115.128
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理
基本语法:awk [选项参数] ‘/pattern1/{action1} /pattern2/{action2}...’ filename
pattern
:表示 awk 在数据中查找的内容,就是匹配模式action
:在找到匹配内容时所执行的一系列命令选项参数 | 功能 |
---|---|
-F | 指定输入文件分隔符 |
-v | 赋值一个用户定义变量 |
内置变量:
变量 | 说明 |
---|---|
FILENAME | 文件名 |
NR | 已读的记录数(行号) |
NF | 浏览记录的域的个数(切割后,列的个数) |
切割 ifconfig 后打印的 IP 地址:
[linux@CentOS01 ~]$ ifconfig ens33 | awk '/netmask/ {print $2}'
192.168.115.128
实现一个当天对指定目录归档备份的脚本,输入一个目录名称(末尾不带/),将目录下所有文件按天归档保存,并将归档日期附加在归档文件名上,放在 /root/archive
下。
这里用到了归档命令:tar
,后面可以加上 -c
选项表示归档,加上 -z
选项表示同时进行压缩,得到的文件后缀名为 .tar.gz
。如需每天执行可结合 crond 服务使用。
脚本实现如下:
#!/bin/bash
# 首先判断输入参数个数是否为 1
if [ $# -ne 1 ]
then
echo "参数个数错误!应该输入一个参数,作为归档目录名"
exit
fi
# 从参数中获取目录名称
if [ -d $1 ]
then
echo
else
echo
echo "目录不存在!"
echo
exit
fi
DIR_NAME=$(basename $1)
DIR_PATH=$(cd $(dirname $1); pwd)
# 获取当前日期
DATE=$(date +%y%m%d)
# 定义生成的归档文件名称
FILE=archive_${DIR_NAME}_$DATE.tar.gz
DEST=/root/archive/$FILE
# 开始归档目录文件
echo "开始归档..."
echo
tar -czf $DEST $DIR_PATH/$DIR_NAME
if [ $? -eq 0 ]
then
echo
echo "归档成功!"
echo "归档文件为:$DEST"
echo
else
echo "归档出现问题!"
echo
fi
exit