Shell脚本

Shell脚本

1、文件头

固定格式,指向系统执行的部位

#!/bin/bash

...

2、变量

2.1、系统变量

$HOME=/root

$USER=当前用户

$PWD=当前路径

$SHELL=/bin/bash

2.2、自定义变量

2.2.1、变量的定义

(1)可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写

(2)等号两侧不能有空格

(3)变量的值有空格,则用双引号或者单引号括起来

(4)export 变量名,可以把变量提升为系统变量

2.2.2、可变变量

(1)变量名=变量值

A=123

(2)赋值不能有空格,可以用unset删除变量

unset A

2.2.3、静态变量

(1)readonly 变量名=变量值

readonly B=123

(2)无法删除,不能使用unset进行删除

2.3、特殊变量

2.3.1、$n 执行文件 后缀变量

例如./xr.sh 1 2

echo "$0 $1 $2"

显示:./xr.sh 1 2

2.3.2、$# 参数个数

例如./xr.sh 1 2

echo $#

显示:2

2.3.3、$*、$@ 所有变量

(1)$*(把所有变量看成一个整体)

(2)$@ (把每一个变量区分对待)

例如 ./xr.sh 1 2

echo $*

echo $@

显示:./xr.sh 1 2

./xr.sh 1 2

2.3.4、$? 显示上一步命令执行结果

asdf qwerq(会报错,命令asdf找不到)

然后执行$?显示127(127代表命令找不到)

$? = 0 表示执行成功或者判断为true

$? = 1 表示判断为false

3、运算符

(1)expr运算,后面的运算符号之间必须要有空格

expr + - \* /
expr `expr 2 + 3` \* 5

(2)$((运算式))

$((2+3)*5)

(3)$[运算式]

$[(2+3)*5]

4、条件判断

[ condition ] 前后必须加空格,不为空则为ture

4.1、判断大小

-lt (less than) 小于

-le (less equal) 小于等于

-gt (greater than) 大于

-ge (greater equal) 大于等于

= (字符串比较) 等于

-ne (not equal) 不等于

4.2、判断文件权限

-r (read) 读权限判断

-w (write) 写权限判断

-x (execute) 执行权限判断

4.3、判断文件类型

-f (file) 是否为常规文件

-e (existence) 是否存在文件

-d (directory) 是否为目录文件

4.4、多条件判断

(1)&&表示前一条执行成功时,才执行后一条命令

(2)||表示上一条命令执行失败了,才执行后一条命令

[ condition ] && echo OK || echo notok
OK
[ condition ] && [  ] || echo notok
notok

5、写入数据到一个文件中

#!/bin/bash

# 创建一个文件
touch /home/xr/zhangsan.txt
# 将指定数据写入文件使用 echo "..." >> ...文件
echo "I am ZhnagSan , I'm 18 year old,a smart boy,thank you!" >> /home/xr/zhangsan.txt

6、流程控制(重点)

6.1、if 判断

if[ 条件判断式 ];then

​	执行

elif[ 条件判断式 ];then

​	执行

if

6.2、case 语句

case $1 in

"a")

​	执行

​	;;

"b")

​	执行

​	;;

*)

​	default执行

​	;;

esac

6.3、for 循环

for((i=0;i<$1;i++))

do

​	执行

done

6.4、while 循环

while [ 条件判断式 ]

do

​	执行

done

7、read读取控制台输入

# 七秒内输入值记录到NAME参数中
read -t 7 -p "Enter your name in 7 seconds :" NAME

echo $NAME

8、函数

8.1、系统函数

(1)basename文件名

basename /home/xr/zhangsan.txt得到zhangsan.txt

basename /home/xr/zhangsan.txt .txt得到zhangsan

(2)dirname文件绝对路径

dirname /home/xr/zhangsan.txt得到/home/xr

8.2、自定义函数

### 自定义函数

[ function ] funname[()]

{

​	Action;

​	[return int;]

}

funame

# 输入两个参数求和
function sum()
{
        sum=0;
        sum=$[$1+$2]
        echo $sum
}

read -p "input your paratemer1:" P1
read -p "input your paratemer2:" P2

sum $P1 $P2

9、Shell工具(重点)

9.1、cut

数据剪切,-d 使用间隔什么剪切,-f 剪切后取第几列

cut -d "剪切符号" -f 选择剪切完的第几个 跟文件地址

# 取第一个
 cut -d " " -f 1 ./cut.log

# 取第二个第三个
cut -d " " -f 2,3 ./cut.log

# 取第三个及以后的数据
cut -d " " -f 3- ./cut.log

# 配合过滤使用
cat cut.log | grep wang | cut -d " " -f 1
wang

# 取系统环境路径的第二个:之后的所有路径
 echo $PATH | cut -d : -f 3-
 /usr/local/sbin:/usr/sbin:/home/vagrant/.local/bin:/home/vagrant/bin
 
# 取ip地址
 ifconfig eth1 | grep "inet " | cut -d " " -f 10
 192.168.56.10

9.2、sed

对文本数据输出缓冲流进行处理

sed -e 多命令处理 ""

# a 新增(create)
[root@10 xr]# sed "2a abc" sed.txt
zhang san
li si
abc
wang wu
zhao liu
wa wa
wo  wo
# d 删除(delete)
[root@10 xr]# sed "2d" sed.txt
zhang san
wang wu
zhao liu
wa wa
wo  wo
[root@10 xr]# sed "/wo/d" sed.txt
zhang san
li si
wang wu
zhao liu
wa wa
# s 替换(transfrom) + g 全局替换(global)
[root@10 xr]# sed "s/wo/ni/" sed.txt
zhang san
li si
wang wu
zhao liu
wa wa
ni  wo
[root@10 xr]# sed "s/wo/ni/g" sed.txt
zhang san
li si
wang wu
zhao liu
wa wa
ni  ni
# -e 多命令执行
[root@10 xr]# sed -e "s/wo/ni/g" -e "2d" -e "3a abc" sed.txt
zhang san
wang wu
abc
zhao liu
wa wa
ni  ni

9.3、awk

文本分析工具

awk -F "指定输入文件折分隔符" -v "赋值一个用户定义变量" ‘操作’ "指定文件"

# awk '/正则表达式/ {print 打印内容 FILENAME文件名 NR行号 NF列号}'
# 打印passwd文件中的root开头的第七列数据
[root@10 xr]# awk -F : '/^root/ {print $7}' passwd
/bin/bash
# 打印root开头,第一列和第七列的数据,以逗号分隔
[root@10 xr]# awk -F : '/^root/ {print $1","$7}' passwd
root,/bin/bash
# 打印文件中的数据,行头加数据,行尾加数据 中间的以user:开头,输出第一列第七列数据,并以逗号分隔
[root@10 xr]# awk -F : 'BEGIN{print "ImStart,shell"} {print "user:"$1","$7} END{print "ImEND,/bin/bash"}' passwd
ImStart,shell
user:root,/bin/bash
user:bin,/sbin/nologin
user:daemon,/sbin/nologin
user:adm,/sbin/nologin
user:lp,/sbin/nologin
user:sync,/bin/sync
user:shutdown,/sbin/shutdown
user:halt,/sbin/halt
user:mail,/sbin/nologin
user:operator,/sbin/nologin
user:games,/sbin/nologin
user:ftp,/sbin/nologin
user:nobody,/sbin/nologin
user:systemd-network,/sbin/nologin
user:dbus,/sbin/nologin
user:polkitd,/sbin/nologin
user:rpc,/sbin/nologin
user:tss,/sbin/nologin
user:rpcuser,/sbin/nologin
user:nfsnobody,/sbin/nologin
user:sshd,/sbin/nologin
user:postfix,/sbin/nologin
user:chrony,/sbin/nologin
user:vagrant,/bin/bash
ImEND,/bin/bash
# 输出第三列的行号并加一
[root@10 xr]# awk -F : -v i=1 '{print $3+i}' passwd
1
2
3
4
5
6
7
8
9
12
13
15
100
193
# FILENAMWE 文件名  NR 行号  NF 列号
[root@10 xr]# awk -F : '{print FILENAME NR NF}' passwd
passwd17
passwd27
passwd37
passwd47
passwd57
passwd67
passwd77
passwd87
passwd97
passwd107
passwd117
passwd127
passwd137
passwd147
passwd157
passwd167
passwd177
passwd187
passwd197
passwd207
passwd217
passwd227
passwd237
passwd247
# 切取ip地址
[root@10 xr]# ifconfig eth1 | grep "inet " | awk -F " " '{print $2}'
192.168.56.10
# 空行行号打印
[root@10 xr]# awk '/^$/ {print NR}' sed.txt
7
[root@10 xr]# cat sed.txt
zhang san
li si
wang wu
zhao liu
wa wa
wo  wo

la  la  la la

9.4、sort

文件排序,结果输出

sort -n(数值大小排序) -r(以相反的顺序排序) -t(设置排序所用的分割字符) -k(指定需要排序的列)

# sort -t "指定排序分隔符" -n(数值大小排序)r(以相反顺序排序)k(指定排序的列) num(指定列数)
[root@10 xr]# cat sort.sh
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
# 第二行升序排序
[root@10 xr]# sort -t : -nk 2 sort.sh
cls:10:3.5
bd:20:4.2
ss:30:1.6
bb:40:5.4
xz:50:2.3
# 第二行降序排序
[root@10 xr]# sort -t : -nrk 2 sort.sh
xz:50:2.3
bb:40:5.4
ss:30:1.6
bd:20:4.2
cls:10:3.5
# 第三行升序排序
[root@10 xr]# sort -t : -nk 3 sort.sh
ss:30:1.6
xz:50:2.3
cls:10:3.5
bd:20:4.2
bb:40:5.4
# 第三行降序排序
[root@10 xr]# sort -t : -nrk 3 sort.sh
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6

10、练习

10.1、京东

问题1:使用Linux命令查询file1中空行所在的行号

[root@10 xr]# awk '/^$/ {print NR}' file.txt
7

问题2:有文件testq2.txt内容如下:

​ 张三 40

​ 李四 50

​ 王五 60

使用Linux命令计算第二列的和并输出

[root@10 xr]# cat testq2.txt | awk -F " " '{sum+=$2} END{print sum}'
150

10.2、搜狐&讯网

问题1:Shell脚本里如何检查一个文件是否存在?如果不存在该如何处理?

[root@10 xr]# ./testfile.sh /home/xr
目录存在
[root@10 xr]# ./testfile.sh /home/xr/xr.sh
文件存在
[root@10 xr]# ./testfile.sh /home/xr/xr6.sh
既不是文件也不是目录
[root@10 xr]# ./testfile.sh /home/xr/xr6
既不是文件也不是目录
[root@10 xr]# cat testfile.sh
#!/bin/bash

if [ -f $1 ];then
        echo "文件存在"
elif [ -d $1 ];then
        echo "目录存在"
else
        echo "既不是文件也不是目录"
fi

10.3、新浪

问题1:用shell写一个脚本,对文本中无序的一列数字排序

[root@10 xr]# cat testnumber.txt
9
8
7
6
5
4
3
2
10
1
# 降序
[root@10 xr]# sort -nrk 1 testnumber.txt
10
9
8
7
6
5
4
3
2
1
# 升序
[root@10 xr]# sort -nk 1 testnumber.txt
1
2
3
4
5
6
7
8
9
10
# 升序 求和
[root@10 xr]# sort -n testnumber.txt | awk '{a+=$0;print$0} END{print "sum="a}'
1
2
3
4
5
6
7
8
9
10
sum=55
# 降序 求和
[root@10 xr]# sort -nr testnumber.txt | awk '{a+=$0;print$0} END{print "sum="a}'
10
9
8
7
6
5
4
3
2
1
sum=55

10.4、金和网络

问题1:请用shell脚本写处查找当前文件夹(/home/xr)下所有的文本文件内容中包含有字符“wo”的文件名称

# grep 
# -i(忽略大小写进行匹配) 
# -v(反向查找,只打印不匹配的行) 
# -r(递归查找子目录中的文件) 
# -l(只打印匹配的文件名) 
# -c(只打印匹配的行数)
[root@10 xr]# grep -r "wo" /home/xr | cut -d ":" -f 1
/home/xr/xr.sh
/home/xr/leap.log
/home/xr/leap.log
/home/xr/leap.log
/home/xr/leap.log
/home/xr/sed.txt
/home/xr/passwd
[root@10 xr]# grep -r "wo" -l /home/xr
/home/xr/xr.sh
/home/xr/leap.log
/home/xr/sed.txt
/home/xr/passwd
posted @ 2024-03-13 17:12  Shinoburedo  阅读(5)  评论(0编辑  收藏  举报