Shell 脚本快速入门

179 阅读5分钟

写在前面

本文介绍了关于linux Shell脚本的相关知识,其需要一定的linux基础,小白可以参考linux 快速入门这篇文章,有了linux基础才能更好理解本文,大佬随意。

Shell 快速入门

什么是Shell

Shell命令行解释器,它能够接受程序或用户命令,然后调用操作系统内核执行该命令,最后将命令返回给用户。

捕获34.PNG 注意: shell是命令行解释器的统称,并不是一个具体的命令行解释器,linux中具体的解释器默认是bash

image.png

shell 脚本

shell 脚本,通俗地可以理解为一个自定义的命令行,linux执行了该命令行,就会完成一些用户自定义的操作(在Shell当中,空格表示隔断,因此不能随意地打空格)

shell 脚本的编写

Shell脚本文件的后缀名为.sh ,且文件开头 第一行必须是#!/bin/bash,以此表明该脚本的具体命令行解释器是什么,方便其他人使用(约定俗成的规矩)

除了上面约定俗成的规矩以外,shell脚本文件需要书写的内容全是linux相关的基础命令(直接写)

捕获36.PNG

shell 脚本的执行

脚本执行有两种方法

  1. 方法一: sh + 脚本文件的相对路径或者 bash + 脚本文件的相对路径

捕获37.PNG image.png

  1. 方法二: 给对应的脚本文件(.sh)添加执行权限chmod +x 脚本.sh此时,只需要输入脚本文件的所在路径就可以运行了

捕获39.PNG

修改脚本路径

每次我们执行自定义的脚本时,总是要依赖其路径来执行,那么我们能不能像执行普通的linux命令(linux命令本质就是脚本)一样,在任何目录下都可以直接执行呢?答案是可以的,我们可以通过修改脚本路径来实现。

  1. 进入 ~目录 当中,用vim 打开.bashrc文件 输入命令vim ./.bashrc

捕获42.PNG

2.在文件末尾添加上以下命令,其中~/桌面/my_shell 为自定义脚本文件所在的目录(用户自定义)

捕获43.PNG

  1. 输入以下命令source ~/.bashrc或者重新打开终端,至此,自定义脚本便可以在任意目录下直接调用(只需要输入脚本文件的文件名)

捕获44.PNG

注意: 以上修改只对当前用户有效,即Shell脚本命令只能当前用户使用,不影响其他用户

规定: 所有的自定义脚本文件放在同一个目录下,方便管理

读取控制台输入

格式为 :read -t 时间 -p 输入时的提示内容 变量名 等待控制台输入

  • -t 指定读取输入内容时的等待时间,超过了这个时间,就不再等待输入,若没有-t,则表示会一直等待
  • -p 指定读取输入内容时的提示内容

变量

  • 输入命令 $变量名 获取指定变量的值(中间无空格)
  • 输入命令 echo "hello world" 打印内容到终端

常用系统变量

常用系统变量有:HOME,PWD,SHELL,USER

  • 输入命令 set 查看所有系统变量

自定义变量

  • 定义变量或者变量赋值 变量名=变量值 (中间无空格)
  • 撤销变量 unset 变量名
  • 声明静态变量 readonly 变量名 (注意:该变量不能被unset)

Shell 当中所有的变量默认都是字符串类型,若字符串当中有空格,那么整个字符串应该用单引号或双引号括起来

  • 输入命令export 变量名 将指定的变量设置为全局变量,这样在其他的Shell脚本文件当中就可以直接使用该变量

特殊变量

$n 外部传参

通过$n在脚本文件内部接受外部参数,n表示数字,$0表示脚本名称,$1~$9 表示命令行执行脚本时,脚本路径后面跟着的九个外部参数,如果参数超过了九个,要大括号包含,如$[10]表示第10个外部参数

image.png

所有的linux命令本质上就是脚本,其格式是脚本名 外部参数1 外部参数2 ……,如上图,ls就是脚本名称(脚本路径),-l就是外部参数1

$#
  • 通过$#在脚本文件内部接受外部参数的个数,常作为脚本文件内部的循环条件
$*$@
  • $* 这个变量代表命令行中的所有外部参数,但是当$*加上双引号时, 它会将所有外部参数看作一个整体
  • $@ 这个变量代表命令行中的所有外部参数,不过当$#加上双引号时 它会将各个外部参数自动分割开(可以用作for循环)

for 变量 in "$@";  #会根据外部参数个数来循环
do
    程序
done

for 变量 in "$#";  #只会循环一次
do
    程序
done
$?
  • $? 这个变量用来判断上一条命令是否执行成功,若执行成功,返回0,否则返回非0

运算符

  • 输入命令 变量名=$[运算式] 获取运算式的运算结果并存入对应变量当中

条件判断

  • 输入命令 test 条件或者[ 条件 ],如果条件为真,则命令执行成功,若条件为假,则命令执行失败(通常该命令要结合$?命令一起来使用)

捕获45.PNG

  1. 两个整数比较大小如下:

格式[ 整数1 -lt 整数2 ] (-lt表示小于)

捕获46.PNG

  1. 判断文件或目录对应当前用户而言是否具有某个权限如下:

格式[ -w或r或x 文件路径或文件名 ]

捕获47.PNG

  1. 判断文件或目录是否存在,若存在,则是否为文件或者目录

格式为:[ -e或f或d 文件路径或文件名 ]

捕获48.PNG

  1. 多条件的与或判断(逻辑运算)

格式为:[ 条件 ] && echo "OK" || echo "not OK"

流程控制

if判断

单分支格式为:

if [ 条件判断 ]
then
    程序
fi

多分支格式为:

if [ 条件判断 ]
then
    程序
elif [ 条件判断 ]
then
    程序
else
    程序
fi

case语句

格式为:

case $变量名 in
"值1")
    程序1
;;
"值2")
    程序2
;;
*)    #星号表示默认值
    默认程序
;;
esac

for循环

格式1为:

for ((初始值;循环控制条件;变量变化))
do
    程序
done

格式2为:

for 变量 in 值1 值2 值3……;
do
    程序
done

while 循环

格式为:

while [ 条件 ]
do
    程序
done

函数

系统函数

  1. 处理绝对路径下文件名的函数:

格式1为:basename 文件的绝对路径 返回文件名

格式2为:basename 文件的绝对路径 文件后缀名 返回去掉后缀名的文件名

  1. 获取文件对应的工作目录(工作目录=绝对路径-文件名)

格式1为:dirname 文件的绝对路径 返回文件对应的工作目录

自定义函数

Shell脚本是逐行执行的,因此在调用函数之前,都要先声明函数

自定义函数的返回值只能是0~255,其中0表示函数正常执行,且返回值只能通过系统变量$? 来获得,若无返回值,则同样输出0~255,此时0表示该自定义函数中最后一条命令执行成功

定义格式为:

[ function ] 函数名()
{

    程序
    return 0;
}
# 函数的参数只能通过外部参数来传递

read -p "please input:" n1;  #等待控制台输入
read -p "please input:" n2;


# 函数调用
函数名 n1 n2     #直接写在Shell脚本文件中


#若要使用函数的结果,则需要自己设置变量,到函数中去接收其最终的结果

Shell 工具(重点)

cut(常用)

cut 命令从文件的每一列剪切字节,字符,字段并将这些剪切下的内容进行输出。

格式为: cut -d " " -f 2 文件名 输出文件对应列的内容(空格作为分隔符,输出文件内容的第二列)

  • -d + 分隔符 通过分隔符来对列进行划分
  • -f + 列号(从1开始算),列与列之间通过分隔符来划分
  • -c 按字符(每列的内容)进行分割,后 +n 表示第几列,如: -c 2(无分隔符概念)
cat 文件名 | grep 行内容 |  cut -d " " -f 2-  

#首先通过cat 获取整个文件的内容, 在通过 grep  筛选出对应的行,
#再在指定行当中选定从第2列开始以后的所有内容

指令1 | 指令2 当中 | 表示管道符,其能够将前面指令运行的结果传递给后面的指令(作为后面指令的输入)

awk

格式为 awk -F ":" '/^root/{print $n}' 文件名

-F 后面是 分隔符, '/查找的行内容/{查找后要执行的操作}'

上述指令作用:将冒号作为分割符,查找以root开头的内容,查找完成后,打印第n列的内容

awk -F ":" 'BEGIN{print "内容"}/^root/{print $n1 "," $n2}END{print "内容"}' 文件名

# 根据查询到的指定内容,打印第n1列和第n2列,并以逗号隔开
# 同时在打印结果的开头和结尾各自添加内容
awk -v 变量名=变量值 -F ":" '/^root/{print $n+变量名}' 文件名

#最终打印结果=第n列的每个值均加了变量值并输出

注意: 在print内部,双引号""表示用户自定义的字符串,无双引号就表示是变量

awk 内置变量

这些内置变量可以直接在print后面调用,不需要事先声明

  • FILENAME 文件名
  • NR 当前所在行的行号
  • NF 分隔过后,列的个数

awk在查找完指定内容后,进行打印时,会逐行依次打印

Shell的正则表达式

  • ^xxx 匹配到所有以xxx开头的内容,如:grep ^a 匹配到所有以a开头的内容
  • xxx$ 匹配到所有以xxx结尾的内容,如:grep a$ 匹配到所有以a结尾的内容
  • . 匹配任意一个字符
  • 字符* 匹配到该字符连续出现0次或者多次
  • [6,8] 匹配到6或者8
  • [a-w]匹配到a~w中的任意一个
  • \字符 转义字符,如\$匹配到 $

image.png