Shell脚本快速入门
一、shell概述与解析器
1、shell概述:
shell是一个命令行解释器,他接收应用程序/用户命令,然后调用操作系统内核。
2、Shell解释器
cat /etc/shells
常见的六种shell解析器
/bin/sh 【常用】
/bin/bash 【常用】【默认的SHELL解析器】 echo $SHELL
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
二、Shell脚本入门
1、脚本格式:
以#!/bin/bash开头 (指定shell脚本解析器)
2、创建并执行一个shell脚本
创建:
touch helloworld.sh
内容:
#!/bin/bash
echo "helloworld lee"
执行:
sh helloworld.sh
或
bash helloworld.sh
或
./helloworld.sh 【需要给执行权限 chmod 777 helloworld.sh】
3、多命令处理案例
在 /home/myscript/notes/目录下创建lee.txt,并增加"I LOVE REN"
#!/bin/bash
cd /home/myscript/notes
touch lee.txt
echo "I LOVE REN" >> lee.txt
注意
> 会覆盖目标的原有内容,当文件存在时,会先删除原文件,再重新创建文件,然后把内容写入该文件,否则直接创建文件。
>> 会在目标原有内容后追加内容,当文件存在时直接在文件末尾进行内容追加,不会删除原文件,否则直接创建文件。
三、Shell中的变量
1、系统变量
##常用的系统变量
$HOME $PWD $SHELL $USER 等
2、自定义变量
基本语法:
##定义变量:
语法: 变量=值 【等号左右不能有空格】
例:A=1
echo $A
##撤销变量
语法: unset 变量
例: unset A
##静态变量:
语法:readonly 变量 【注意:不能unset】
例:readonly B=2
echo $B
【此时不能使用 unset B,只有机器重启的时候才会丢失】
规则:
1> 字母、数字、下划线组成
2> 不能以数字开头
3> 环境变量名建议大写
4> 等号两侧不能有空格
5> 变量默认类型都是字符串类型,无法直接进行数值运算
6> 变量的值如果有空格,用单引号或双引号括起来
将变量提升为全局变量,供所有Shell程序使用
export A
然后helloworld.sh 中就可以使用 echo $A了
3、特殊变量
$n
功能描述:
n为数字,$0代表当前脚本名称,$1-$9代表第一个到第九个参数,十以上的参数需要用大括号包含:${10}
例:
创建文件:
touch parameters_1.sh
内容如下:
#!/bin/bash
echo "$0 $1 $2"
运行:
sh parameters_1.sh 参数1 参数2
结果:
parameters_1.sh 参数1 参数2
$#
功能描述:
获取所有输入参数的个数,常用于循环 (不包含 默认的参数$0 文件名称)
例:
创建文件:
touch parameters_2.sh
内容如下:
#!/bin/bash
echo "$0 $1 $2"
echo $#
运行:
sh parameters_2.sh 参数1 参数2
结果:
parameters_2.sh 参数1 参数2
2
$ 和 $@*
功能描述
$*
这个变量代表命令行中所有的参数,$*把所有的参数看成了一个整体
$@
这个变量也代表命令行的所有参数,$@把所有参数区别对待
例:
创建文件:
touch parameters_3.sh
内容如下:
#!/bin/bash
echo "$0 $1 $2"
echo $#
echo $*
echo $@
运行:
sh parameters_3.sh 参数1 参数2
结果:
parameters_3.sh 参数1 参数2
2
参数1 参数2
参数1 参数2
$?
功能描述:
上一次执行命令的返回状态,如果这个变量的值为0,证明上一个命令执行正确,否则不正确
四、运算符
基本语法:
1> "$((运算式))" 或 "$[运算式]"
2> expr + 加 - 减 \* 乘 / 除 % 取余
【注意:expr运算符间必须要有空格】
例:
expr 2 + 3 【表达式:2+3】
$[2+3]
expr `expr 2 + 3` \* 4 【表达式 (2+3)* 4】
$[(2+3)*4]
五、条件判断
基本语法
[ condition ]
【注意:condition前后要有空格】
【注意:条件非空即为true,否则为false】
常用的判断条件:
1> 两个整数间比较
= 字符串比较 -lt 小于 -le 小于等于
-eq 等于 -gt 大于 -ge 大于等于
-ne 不等于
2> 按照文件权限进行判断
-r 读权限 -w写权限 -x执行权限
3>按文件类型进行判断
-e 文件存在
-f 普通文件
-d 目录文件
4>多条件判断
&& 表示前一个命令执行成功时,才执行后一条命令 【与】
|| 表示前一个命令执行失败后,才执行后一条命令 【或】
六、流程控制(重点)
1、if判断
##基础语法:
if [ condition ];then
程序1
elif [ condition ];then
程序2
fi
或者
if [ condition ]
then
程序1
elif [ condition ]
then
程序2
fi
【注意 if 后要有空格】
例子
#!/bin/bash
if [ $1 -le 2 ];then
echo "this number less or equal than 2"
elif [ $1 -gt 2 ];then
echo "this number greater than 2"
fi
2、case语句
##基础语法:
case $变量名 in
"值1")
程序1--如果变量值等于值1,执行此处
;;
"值2")
程序2--如果变量值等于值2,执行此处
;;
*)
程序3--如果变量值都不是以上的值,执行此处
;;
esac
注意:
【case行尾 必须为单次 in,每个模式匹配必须以 右括号) 结束】
【双分号;;表示命令序列结束,相当于Java中的break】
【最后的*)表示默认模式,相当于Java中的default】
例子:
#!/bin/bash
case $1 in
1)
echo "parameter is 1"
;;
2)
echo "parameter is 2"
;;
*)
echo "parameter is other"
;;
esac
3、for循环
##基础语法1:
for (( 初始值;循环控制条件;变量变化 ))
do
程序1
done
##基础语法2:【比如打印所有输入的参数】【$* $@】
for 变量 in 值1 值2 值3...
do
程序1
done
例子:
#!/bin/bash
s=0
for(( i=1;i<=100;i++ ))
do
s=$[$s+$i]
done
echo $s
for i in $*
do
echo "1---I LOVE $i"
done
for i in $@
do
echo "2---I LOVE $i"
done
for j in "$*"
do
echo "3---I LOVE $j"
done
for j in "$@"
do
echo "4---I LOVE $j"
done
4、while循环
##基础语法:
while [ 条件判断表达式 ]
do
程序1
done
例子:
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
s=$[ $s + $i ]
i=$[ $i + 1 ]
done
echo $s
七、read读取控制台输入
基本语法
read(选项)(参数)(变量)
选项:
-p 指定读取值时的提示符
-t 指定读取值时等待的时间(秒)
参数:
变量:指定读取值的变量名
例子:
#!/bin/bash
read -t 7 -p "PLEASE ENTER YOU NAME :" USER_NAME
echo "YOU ENTER THE NAME IS $USER_NAME"
八、函数
1、系统函数
1.1、basename 【返回文件名】
##basename基础语法:
basename [string/pathname][suffix]
##功能描述
basename命令会删除所有的前缀包括最后一个('/')字符,然后将字符串显示出来
例子
basename /root/myscript/batch.sh
结果:batch.sh
basename /root/myscript/batch.sh .sh
结果:batch
1.2、dirname 【返回文件路径】
##dirname基础语法
dirname 文件绝对路径
##功能描述
从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
例子:
dirname /root/myscript/batch.sh
结果:/root/myscript
2、自定义函数
##基础语法
[ function ] funname[()]
{
Action;
[return int;]
}
funname
【注意:中括号表示可写可不写】
##经验技巧
1>必须在调用之前,先声明函数,shell脚本是逐行运行的。
2>函数返回值,只能通过$?系统变量活的,可以显示加:return 返回,如果不加,将最后一条命令运行
结果作为返回值。return后跟数值n(0-255)
例子:
#!/bin/bash
function sum()
{
s=0;
s=$[$1+$2]
echo $s
}
read -p "PLEASE ENTER THE FIRST NUMBER : " P1
read -p "PLEASE ENTER THE SECOND NUMBER : " P2
sum $P1 $P2
九、shell工具(重点)
1、cut
cut负责剪切数据用的,cut命令从文件的每一行剪切字节、字符和字段并将这些字节、字符、字段输出
##基本语法:
cut [选项参数] filename
-f 列号,提取第几列。 n表示第N列,n-表示n列和之后的所有列
-d 分隔符,按照指定的分隔符分割列
例子1:
切出cut.txt第一列
touch cut.txt
内容:
I REN LEE
LOVE LOVE LOVE
REN LEE LEE+REN
执行:
cut -d " " -f 1 cut.txt [剪切cut.txt的第一列,以" "切割]
结果:
I
LOVE
REN
例子2:
切出cut.txt中包含+号的行内容
cat cut.txt|grep "+"
结果:
REN LEE LEE+REN
切出cut.txt中包含+号的所在行的,+号之后的内容
cat cut.txt|grep "+"|cut -d "+" -f 2
结果:
REN
例子3:
切出$PATH第二个冒号之后所有的内容
echo $PATH
结果:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/software/jdk8/bin:/root/bin
echo $PATH|cut -d : -f 3- 【3-表示第3列之后的所有】
结果:/usr/sbin:/usr/bin:/opt/software/jdk8/bin:/root/bin
补充知识:
grep 文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查,打印匹配到的行.
语法:
grep [options][pattern] file
命令 参数 匹配模式 文件数据
-i 忽略大小写
-o 仅显示匹配到的字符串本身
-c 统计匹配的行数
-v 显示不能被匹配到的行(排除匹配结果)
-E 支持使用扩展的正则表达式元字符
-q 静默模式,不输出任何内容
正则 ^以xxx开头 $以xxx结尾 ^$代表空行
2、sed
sed是流编辑器,一次处理一行,将当前处理的行存储在临时缓冲区中,称为"模式空间".
接着使用sed命令处理缓冲区中的内容,处理完成后,把缓冲区中的内容送往屏幕。接着处理下一行直至文件末尾。(文件内容不会改变)
##基础语法
sed[参数选项] 'commmand' filename
##选项参数
-e直接在指令模式上进行sed的动作编辑
##命令功能描述
a 新增(a的后面拼接字符串,在下一行显示)
d 删除
s 查找并替换
例子:
第二行后增加mei nv
命令:cat sed.txt
结果:
dong shen
guan zhen
wo wo
lai lai
le le
命令:sed "2a mei nv" sed.txt
结果:
dong shen
guan zhen
mei nv
wo wo
lai lai
le le
删除wo所在的行
命令:sed "/wo/d" sed.txt
结果:
dong shen
guan zhen
lai lai
le le
将wo替换成ni
命令:sed "s/wo/ni/" sed.txt 【没有g,只替换第一个】
结果:
dong shen
guan zhen
ni wo
lai lai
le le
命令:sed "s/wo/ni/g" sed.txt 【有g,全局替换】
结果:
dong shen
guan zhen
ni ni
lai lai
le le
第2行添加 mei mei 第3行添加 nv nv wo替换成ni 删除 le
命令:sed -e "2a mei mei" -e "2a nv nv" -e "s/wo/ni/g" -e "/le/d" sed.txt
结果:
dong shen
guan zhen
mei mei
nv nv
ni ni
lai lai
3、awk
awk文本分析工具,将文本逐行读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理
##基本语法
awk[选项参数] 'pattern1{action1} pattern2{action2}...' filename
pattern:标识awk再数据总查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令
##选项参数:
-F 指定输入文件的分隔符
-v 赋值一个用户定义变量
例子1:
cp /etc/passwd .
##查询passwd文件的 以root开头的 用:分割的第七列内容
命令:
awk -F : '/^root/ {print $7}' passwd
结果:
/bin/bash
例子2:
##查询passwd文件的 以root开头的 用:分割的第一列和第七列内容,并以,逗号分割
命令:
awk -F : '/^root/ {print $1 "," $7}' passwd
结果:
root,/bin/bash
例子3:
##只显示passwd的第1列和第7列,以逗号分割,且在所有行前面添加列名user,shell
##且在最后一行添加“lee,/bin/zuishuai”
命令:
awk -F : 'BEGIN{print "user,shell"} {print $1","$7 } END{print
"lee,/bin/zuishuai"}' passwd
结果:
user,shell
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
halt,/sbin/halt
mail,/sbin/nologin
operator,/sbin/nologin
games,/sbin/nologin
ftp,/sbin/nologin
nobody,/sbin/nologin
systemd-network,/sbin/nologin
dbus,/sbin/nologin
polkitd,/sbin/nologin
sshd,/sbin/nologin
postfix,/sbin/nologin
lee,/bin/bash
grafana,/sbin/nologin
lee,/bin/zuishuai
注意:BEGIN在所有数据读取之前执行;
END在所有数据执行之后执行
例子4:
##passwd 第三列所有值都加1
命令:
awk -F : -v i=1 '{print $3+i}' passwd
【注意 action中 使用变量i不能用$i】
结果:
1
2
3
4
5
6
7
8
9
12
13
15
100
193
82
1000
75
90
1001
999
其他awk内置变量:
FILENAME 文件名
NR 已读的记录数
NF 浏览记录的域的个数(切割后,列的个数)
4、sort
sort将文件进行排序,并将排序结果标准输出
##基础语法
sort(选项)(参数)
##选项
-n 依照数值的大小排序
-r 以相反的顺序来排序
-t 设置排序时所用的分割符
-k 指定需要排序的列
例子:
touch sort.txt
内容:
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
以冒号分割,根据第二列数值大小进行倒叙排序
命令:
sort -t : -nrk 2 sort.txt
结果:
xz:50:2.3
bb:40:5.4
ss:30:1.6
bd:20:4.2
cls:10:3.5