首页 > 系统相关 >shell脚本

shell脚本

时间:2023-08-13 23:01:05浏览次数:27  
标签:脚本 shell gy echo sh localhost root bash

shell脚本

面向过程语言

  • 做一件事情,排出个步骤,第一步干什么,第二步干什么,如果出现情况A,做什么处理,如果出现了情况B,做什么处理

  • 问题规模小,可以步骤化,按部就班处理

  • 以指令为中心,数据服务于指令

  • C,shell

面向对象语言

  • 将编程看成是一个事物,对外界来说,事物是直接使用的,不用关心事物内部的情况。而编程就是设置事物能够完成功能。

  • 一种认识世界、分析世界的方法论。将万事万物抽象为各种对象

  • 类是抽象的概念,是万事万物的抽象,是一类事物的共同特征的集合

  • 对象是类的具象,是一个实体

  • 问题规模大,复杂系统

  • 以数据为中心,指令服务于数据

1.shell脚本基础

1.1 shell的作用

Linux 系统中的 Shell 是一个特殊的应用程序,它介于操作系统内核与用户之间,充当 了一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执 行的操作传递给内核执行,并输出执行结果。 常见的 Shell 解释器程序有很多种,使用不同的 Shell 时,其内部指令、命令行提示符 等方面会存在一些区别。通过/etc/shells 文件可以了解当前系统所支持的 Shell 脚本种类。

 

查看本机的shell信息

[root@localhost ~]# cat /etc/shells    //查看当前系统支持的shell
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
[root@localhost ~]#

image-20230809182910113

linux中常见的shell

  • bash:基于gun的框架下发展的shell

  • csh:类似c语言的shell

  • tcsh:整合了csh提供了更多功能

  • sh:已经被bash替换

  • nologin:让用户无法登录

bash (/bin/bash)是目前大多数Linux 版本采用的默认shell

1.2 什么是shell脚本?及构成

  • 就是将命令按顺序一一列出,最后自动执行

  • 执行需要权限,也可以直接使用绝对路径

  • 脚本其实不复杂,通用脚本环境改变后依然可以使用的脚本

构成

  1. 脚本申明(解释器):第一行开头“#!/bin/bash”,表示此行以下的代码语句是通过/bin/bash程序来解释执行。#!/bin/bash为默认的解释器还有其他类型的解释器,#!/bin/python #!/bin/expect

  2. 注释信息:以#开头的语句表示为注释信息

  3. 可执行语句:比如echo命令用于输出“ ”之间的字符串

1.3脚本执行逻辑及执行方式

脚本执行逻辑

  1. 顺序执行:程序按从上到下顺序执行

  2. 选择执行:程序执行过程中,根据条件的不同,进行选择不同分支继续执行

  3. 循环执行:程序执行过程中需要重复执行多次某段语句

执行方式

  1. 指定路径去执行文件(需要有执行权限)

[root@localhost ~]# chmod +x gy.sh        加权限
指定相对路径.gy.sh  
指定绝对路径/root/gy.sh  
[root@localhost ~]# vim gy.sh
[root@localhost ~]# cat gy.sh
#!/bin/bash
ls /opt
[root@localhost ~]# . gy.sh
-bash: ./gy.sh: 权限不够
[root@localhost ~]# pwd gy.sh
/root
[root@localhost ~]# /root/gy.sh
-bash: /root/gy.sh: 权限不够
[root@localhost ~]# ll gy.sh
-rw-r--r--. 1 root root 20 8月   9 18:42 gy.sh
[root@localhost ~]# chmod +x gy.sh
[root@localhost ~]# ll gy.sh
-rwxr-xr-x. 1 root root 20 8月   9 18:42 gy.sh
[root@localhost ~]# ./gy.sh
passwd rh
[root@localhost ~]# /root/gy.sh
passwd rh
[root@localhost ~]#

image-20230809185420422

2.指定解释器去执行(不需要权限)

[root@localhost ~]# bash gy.sh
passwd rh

指定了使用 bash去执行脚本不需要权限

image-20230809185658111

2.1用bash去执行脚本 会新开一个bash去执行执行完后后自动退出

[root@localhost ~]# vim gy.sh
[root@localhost ~]# cat gy.sh
#!/bin/bash
ping 192.168.1.100
cd /etc
ls /opt
[root@localhost ~]# bash gy.sh
PING 192.168.1.100 (192.168.1.100) 56(84) bytes of data.
From 192.168.1.200 icmp_seq=2 Destination Host Unreachable
From 192.168.1.200 icmp_seq=3 Destination Host Unreachable
From 192.168.1.200 icmp_seq=4 Destination Host Unreachable

#后面还有很多linux默认长ping

这时候打开一个新的页面 发现有三个bash一个本来的bash,一个编译脚本的bash,一个是新开页面的bash
[root@localhost ~]# pstree -p |grep bash
          |-sshd(1098)-+-sshd(56381)---bash(56387)---bash(57314)---p
          |           |-sshd(57397)---bash(57404)-+-grep(57456)
结束长ping
在新开页面查看
现在剩两个bash
[root@localhost ~]# pstree -p |grep bash
          |-sshd(1098)-+-sshd(56381)---bash(56387)
          |           |-sshd(57397)---bash(57404)-+-grep(57459)

关闭新开页面
还剩一个bash
[root@localhost ~]# pstree -p |grep bash
          |-sshd(1098)-+-sshd(56381)---bash(56387)-+-grep(57754)

image-20230809192548293

image-20230809194958984

image-20230809195036439

image-20230809195047756

 

image-20230809195057801

image-20230809195112708

 

source 相对,绝对 会影响你的当前目录

会影响你的当前目录
. /root/gy.sh
source /root/gy.sh  


[root@localhost mnt]# cat /root/gy.sh
#!/bin/bash
cd /etc
ls /opt

[root@localhost mnt]# . /root/gy.sh
当前的目录位于: mnt
passwd rh
[root@localhost etc]# cd -
执行后位于:etc

[root@localhost mnt]# source /root/gy.sh
当前的目录位于: mnt
passwd rh
[root@localhost etc]#
执行后位于:etc

image-20230809191459548

 

image-20230809191525813

 

image-20230809191546823

1.4 脚本错误调试

1.命令错误

命令出错不会影响接下来的命令继续

[root@localhost ~]# cat gy.sh
#!/bin/bash
cb /etc
ls /opt
[root@localhost ~]# ./gy.sh
./gy.sh:行2: cb: 未找到命令
passwd rh

#还是执行了ls /opt 这条命令
[root@localhost ~]# cd /opt/
[root@localhost opt]# ls
passwd rh

image-20230810121719842

 

image-20230810121953214

 

2.语法错误

会影响接下来的命令继续

image-20230810131417752

image-20230813141358718

 

image-20230813144550838

image-20230813144722121

  1. 逻辑错误

    只能自己去筛查

查代码的正确

bash -n 脚本名称 (不在当前目录下加绝对路径)     检查语法错误
-n (noexec 或 no ecxecution 简称) - 指示 Shell 读取所有命令然而不执行它们,这个选项激活语法检查模式。
bash -x 脚本名称 (不在当前目录下加绝对路径)     逻辑错误
-x (xtrace 或 execution trace 简称) - 告诉 Shell 在终端显示所有执行的命令和它们的参数。 这个选项是启用 Shell 跟踪模式。

bash -x

image-20230813144211832

image-20230813144237208

bash -n

这里不存在语法错误

image-20230813144341940

总结:脚本错误常见的有三种区别

  1. 语法错误,会导致后续的命令不继续执行,可以用bash -n 检查错误,提示的出错行数不一定是准确的

  2. 命令错误,默认后续的命令还会继续执行,用bash -n 无法检查出来 ,可以使用 bash -x 进行观察

  3. 逻辑错误:只能使用 bash -x 进行

2 重定向与管道符

2.1重定向

类型 设备文件 文件描述编号 默认设备标准输入 /dev/stdin 0 键盘

标准输出 /dev/stdout 1 显示器

标准错误输出 /dev/stderr 2 显示器

 

交互式硬件设备

  • 标准输入:从该设备接收用户输入的数据

  • 标准输出:通过该设备向用户输出数据

  • 标准错误:通过该设备报告执行出错信息

重定向的意思就是 ,不通过标准输出到屏幕上,输出到你指定的位置

类型操作符用途
重定向输入 < 从指定的文件读取数据,而不是从键盘输入
重定向输出 1> 将输出结果保存到指定的文件(覆盖原有内容)
>> 将输出结果追加到指定的文件尾部  
标准错误输出 2> 将错误信息保存到指定的文件(覆盖原有内容)
2>> 标准错误输出结果追加到指定的文件尾部  
混合输出 &>无论对错都可以重定向 将标准输出、标准错误的内容保存到同一个文件中

重定向输入<

[root@localhost ~]# cat cs
2*3
[root@localhost ~]# bc < cs
6

重定向输出 1>

[root@localhost ~]# cat ml
123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123
[root@localhost ~]# cat ml 1>cs
[root@localhost ~]# cat cs
123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123

image-20230813150137419

>>

[root@localhost ~]# cat ml
123
[root@localhost ~]# cat cs
456
[root@localhost ~]# cat cs >> ml
[root@localhost ~]# cat ml
123
456

image-20230813150517886

标准错误输出2>

[root@localhost ~]# ls xxx
ls: 无法访问xxx: 没有那个文件或目录
[root@localhost ~]# ls xxx 2> cs
[root@localhost ~]# cat cs
ls: 无法访问xxx: 没有那个文件或目录
[root@localhost ~]#

image-20230813150715027

2>>

[root@localhost ~]# cat ml
123
456
[root@localhost ~]# ls xxx 2>> ml
[root@localhost ~]# cat ml
123
456
ls: 无法访问xxx: 没有那个文件或目录

image-20230813150909155

混合输出&>无论对错都可以重定向

[root@localhost ~]# ls xxx /opt &> cs
[root@localhost ~]# cat cs
ls: 无法访问xxx: 没有那个文件或目录
/opt:
rh
[root@localhost ~]# ls /opt/
rh

image-20230813151439099

2.2 多行重定向

Here Document 概述 使用 I/O 重定向的方式将命令列表提供给交互式程序或命令,比如 ftp、cat 或 read 命令。 HereDocument是标准输入的一种替代品, 可以帮助脚本开发人员不必使用临时文件来构建输入信息, 而是直接就地生产出一个文件并用作命令的标准输入。

[root@localhost ~]# wc -l <<EOF
> 123
> 123
> EOF
2

image-20230813193656331

[root@localhost ~]#cat > ky15.txt
#需要回车才会写入
hhh
111
ky15

image-20230813193906382

 

[root@localhost ~]# cat >gy.txt <<EOF
> 333
> 444
> 555
> EOF
[root@localhost ~]# cat gy.txt
333
444
555
[root@localhost ~]# cat >>gy.txt <<EOF
333
444
555
EOF
[root@localhost ~]# cat gy.txt
333
444
555
333
444
555

image-20230813194812933

image-20230813194826062

#####修改密码
[root@localhost data]#passwd zhangsan <<EOF

> 123123
> 123123
> EOF
> 更改用户 zhangsan 的密码 。
> 新的 密码:无效的密码: 密码少于 8 个字符
> 重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。

image-20230813200640668

###变量赋值
[root@localhost ~]# read a <<EOF
> 1
> 2
> EOF
[root@localhost ~]# echo $a
1
[root@localhost ~]# read a <<EOF
<2
EOF

[root@localhost ~]# echo $a
<2

image-20230813201810311

 

2.3管道符

管道符 |

将左侧的命令输出结果,作为右侧命令的输入(处理对象)可以 叠加使用

[root@localhost ~]# cp /etc/passwd /opt/
[root@localhost ~]# ls /opt/
passwd  rh
[root@localhost ~]# ls /opt/ |wc
      2       2      10

image-20230813201427824

[root@localhost opt]# echo "123123" |passwd --stdin zhangsan
更改用户 zhangsan 的密码 。
passwd:所有的身份验证令牌已经成功更新

image-20230813202056255

3 变量

变量来源于数学,是计算机语言中能储存计算结果或能表示值的抽象概念。

保存将来会变化的数据,即使数据变化,直接调用变量即可,各种 Shell 环境中都使用到了“变量”的概念。Shell 变量用来存放系统和用户需要使用的特定参数(值),而且这些参数可以根据用户的设定或系统环境的变化而相应变化。通过使用变量,Shell 程序能够提供更加灵活的功能,适应性更强。

3.1变量基础

常见 Shell 变量的类型包括:

自定义变量:由用户自己定义,修改和使用
环境变量:由系统维护,用于设置工作环境
只读变量:只可以读取不可以更改
位置变量:通过命令行给脚本传递参数
预定义变量:Bash中内置的一类变量,不能修改    有些规定好的变量 放在那里让你使用

系统内置变量:PATH,UID,HOSTNAME,USER

3.1.1 命名要求

  • 区分大小写

  • 不能使程序中的保留字和内置变量:如:if, for,hostname 命令 a=

  • 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反

  • 不要使用内置的变量,使用英文尽量使用词义通俗易懂,PATH

name='value' 
变量名=变量值
直接字串:name='root'
变量引用:name="$USER"
命令引用:name=`COMMAND` 或者 name=$(COMMAND)
注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除
变量引用:
$name
${name}
弱引用和强引用
"$name " 弱引用,其中的变量引用会被替换为变量值
'$name ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
[root@localhost ~]# name=gy
[root@localhost ~]# echo $name
gy

image-20230813202509574

[root@localhost ~]# ylc=123
[root@localhost ~]# echo $name$ylc
gy123

image-20230813203653866

[root@localhost ~]# echo ls
ls
[root@localhost ~]# echo $(ls)
anaconda-ks.cfg cs gy.sh gy.txt initial-setup-ks.cfg ml sysconf(1).sh
[root@localhost ~]# echo `ls`
anaconda-ks.cfg cs gy.sh gy.txt initial-setup-ks.cfg ml sysconf(1).sh

image-20230813203904399

1.赋值时使用双引号(" ")可以直接调用变量

2.赋值时使用单引号(' ')$只会被认为是字符$ 不会调用变量

3.赋值时使用(``反撇在tab上面)命令替换,提取命令执行后的输出结 果 和$( ) 用法相同

4.{}可以分隔变量值

变量追加值

格式

变量名+=追加值

[root@localhost ~]# echo $name
gy
[root@localhost ~]# name+=:123
[root@localhost ~]# echo $name
gy:123

image-20230813204240063

3.1.2 read -p

从键盘输入的内容变成变量

方法1
[root@localhost ~]# read -p "现在的时间是:" time
现在的时间是:10
[root@localhost ~]# echo $time
10
[root@localhost ~]# read -p "现在的时间是:" time
现在的时间是:12
[root@localhost ~]# echo $time
12
[root@localhost ~]#

image-20230813204827804

方法2
[root@localhost opt]# vim 1.sh
#!/bin/bash
echo -n "请输入你的信息"
read info
echo $info
[root@localhost ~]# bash 1.sh
请输入你的信息2
2
[root@localhost ~]#

image-20230813213831662

3.1.3 变量作用范围

默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。

可以通过内部命令export将指定的变量为全局变量,使用户定义的变量在所子shell环境中可以继续使用

方法:

方法:

  1. 格式1:export 变量名

  2. 格式2:export 变量名=变量值

可以使用pstree 查看shell的环境

输入bash进入子shell

ctrl+D组合exit 退出子shell

举例:

[root@localhost opt]# abc=123
[root@localhost opt]# echo $abc 
123
[root@localhost opt]# bash
[root@localhost opt]# echo $abc
为空
[root@localhost opt]# exit
exit
[root@localhost opt]# echo $abc
123
[root@localhost opt]# export abc
#export  变量名      定义全局变量
[root@localhost opt]# bash
[root@localhost opt]# echo $abc
123

image-20230813214218312

3.1.4 整数的运算

expr只能进行整数的运算

格式: expr 变量1 运算符 变量2 [运算符 变量3]

运算符:

加法 +

减法 -

乘法 \ *

除法 /

取余 (取模)%

let

在Linux中,let是一个用于执行算术操作的命令。它可以用于将一个算术表达式的结果赋值给一个变量。let命令通常用于在shell脚本中进行简单的数学计算。

下面是一个示例,演示如何使用let命令将两个变量相加并将结果赋值给一个新变量:

#!/bin/bash

# 定义两个变量
num1=5
num2=10

# 使用let命令执行加法操作,并将结果赋值给sum变量
let "sum = num1 + num2"

# 输出结果
echo "Sum: $sum"

 

当运行上述脚本时,它将计算5 + 10的结果,并将结果赋值给变量sum。最后,脚本将输出结果Sum: 15

请注意,let命令也可以用于执行其他算术操作,如减法、乘法和除法。它还支持使用变量和括号来编写复杂的算术表达式。你可以通过在终端中输入man let来获取有关let命令的更多详细信息。

#expr [root@localhost ~]#a=1 [root@localhost ~]#b=2 [root@localhost ~]#expr $a + $b #加减乘除前后有空格 3

随机数生成器变量:

$RANDOM   取值范围:0-32767

[root@localhost ~]#man bash




$[RANDOM%33+1]
[root@localhost ~]# echo $[RANDOM%34+1]
9
[root@localhost ~]#echo -e "\E[1;30mhello\E[0m"
#颜色
[root@localhost ~]# echo -e "\E[1;$[RANDOM%7+31]mhello\E[0m"
#随机颜色
[root@localhost ~]#echo $(expr $RANDOM % 33 + 1)
#注意运算符附近都要有空格

3.2.1 环境变量

  1. 由系统提前创建,用来设置用户的工作环境

  2. 可以使用env查看环境变量

  3. 需要记住的常用环境变量

[root@localhost ftp]#env #可以看到所有

image-20230813215241768

$USER 表示用户名称

$HOME 表示用户的宿主目录

$LANG 表示语言和字符集

$PWD 表示当前所在工作目录

$PATH 表示可执行用户程序的默认路径

环境变量:

  • 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量

  • 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程

  • 一般只在系统配置文件中使用,在脚本中较少使用

2.3.2 只读变量

变量值不允许修改(重新赋值)的情况

无法使用 unset删除

最快方法重启

[root@localhost opt]# name=gy15
[root@localhost opt]# readonly name
[root@localhost opt]# echo $name 
gy15
[root@localhost opt]# unset name
bash: unset: name: 无法反设定: 只读 variable
#只有退出进程
[root@localhost opt]# echo $name 
gy15
[root@localhost opt]# name=gy
bash: name: 只读变量

2.3.3 位置变量

位置变量也称为位置参数,使用$1、$2、$3、…、$9 表示

[root@test1 ~]# vim 1.sh      
#!/bin/bash
echo "$1"            位置1
echo "$2"            位置2
echo "${10}"         位置10
echo "$10"           位置1和0
echo "$*"            将所有项当成一个值
echo "$@"            所有项
echo "$0"            脚本自身
echo "$#"            后面参数的个数

[root@test1 ~]# ./1.sh {1..10}
1 
2
10
10
1 2 3 4 5 6 7 8 9 10
$0 表示当前的脚本名称

[root@test1 ~]# vim weizhi.sh
#!/bin/bash
sum=`expr $1 + $2`
echo "$1+$2=$sum"
[root@test1 ~]# chmod +x weizhi.sh
[root@test1 ~]# ./weizhi.sh 12 34 56
12+34=46
[root@test1 ~]#cat qiuhe.sh
#!/bin/bash
i=$1
m=$2
sum=0
let sum=$[i+m]
echo $sum

2.3.4 预定义(状态)变量

系统帮你定义好了 拿来用就可以了,你不需要知道为什么,记住

  • $*:表示所有位置参数的内容看成一个整体返回 返回所有

  • $@:表示所有位置参数的内容分割成n份,每份作为一个独立的个体返回 返回所有

  • $?:表示前一条命令执行后的返回状态,返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常

  • $#:表示命令行中位置参数的总个数

  • $0:表示当前执行的脚本或程序的名称 当前脚本的名字

  • $$:当前进程id

  • $!: 后台任务最后一个id

[root@localhost data]#bash test.sh {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
a b c d e f g h i j k l m n o p q r s t u v w x y z


[root@localhost data]#bash 1.sh {a..z}
at的结果是
a
[root@localhost data]#bash 2.sh {a..z}
星的结果是
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@localhost data]#cat 3.sh
#!/bin/bash

echo $1
[root@test1 ~]# vim 1.sh      
#!/bin/bash
echo "$*"           将所有项当成一个值
echo "$@"           独立个体
echo "$#"           后面参数的个数


注意:$@ $* 只在被双引号包起来的时候才会有差异
将脚本1的结果 $@ 交给3 输出$1
将脚本2的结果 $* 交给3 输出$1
[root@localhost opt]# bash 1.sh 1 2 3
#!/bin/bash
echo "@结果"
./3.sh "$@"

[root@localhost opt]# cat 2.sh 1 2 3
#!/bin/bash
echo "*结果"
./3.sh "$*"


[root@localhost opt]# cat 3.sh
#!/bin/bash
echo "$1"

区别 $* 和 $@
#!/bin/bash
echo "打印出\$*"
for var in "$*"
do
echo "$var"
done


echo "打印出\$@"
for var in "$@"
do
echo "$var"
done

3.条件语句

test 测试文件的表达式 是否成立

格式1:test 条件表达式 格式2:[ 条件表达式 ] 注意[]空格,否则会失败 测试 是否成功使用 $? 返回值 [ 操作符 文件或目录 ] help test

操作符: -d:测试是否为目录(Directory) -e:测试目录或文件是否存在(Exist) -a:测试目录或文件是否存在(Exist) -f:测试是否为文件(File) -r:测试当前用户是否有权限读取(Read) -w:测试当前用户是否有权限写入(Write) -x:测试当前用户是否有权限执行(eXcute) -L: 测试是否为软连接文件

例子:

[root@test1 ~]# test -d /etc/sysconfig
[root@test1 ~]# echo $?
0
[root@test1 ~]# test -f /etc/sysconfig
[root@test1 ~]# echo $?
1
[root@test1 ~]# [ -d /etc/sysconfig/ ]            注意前后空格
[root@test1 ~]# echo $?
0

3.4.2比较整数数值

[ 整数1 操作符 整数2 ] 公式

  • -eq:第一个数等于(Equal)第二个数

  • -ne:第一个数不等于(Not Equal)第二个数

  • -gt:第一个数大于(Greater Than)第二个数

  • -lt:第一个数小于(Lesser Than)第二个数

  • -le:第一个数小于或等于(Lesser or Equal)第二个数

  • -ge:第一个数大于或等于(Greater or Equal)第二个数

[  整数1  操作符  整数2  ]
[root@test1 ~]# a=2        实例
[root@test1 ~]# b=3
[root@test1 ~] [ $a -eq $b ]
[root@test1 ~]# echo $?
1
[root@test1 ~]# [ 2 -le 3 ]
[root@test1 ~]# echo $?
0

3.4.3字符串比较

常用的测试操作符

  • =:字符串内容相同

  • !=:字符串内容不同,! 号表示相反的意思

  • -z:字符串内容为空

  • -n: 字符是否存在

格式

[ 字符串1 = 字符串2 ] 是否相同

[ 字符串1 != 字符串2 ] 是否不相同

[ -z 字符串 ] 是否为空

[ -n 字符串 ] 字符是否存在

[root@localhost data]#str1=wang
[root@localhost data]#str2=zhou
[root@localhost data]#[ $str1 = $str2 ]
[root@localhost data]#echo $?
1

[root@localhost etc]# [ $USER = root ]&& echo true
true
[root@localhost etc]# [ $USER != root ]&& echo true

3.4.4逻辑测试(短路运算)

格式1:[ 表达式1 ] 操作符 [ 表达式2 ] ... 格式2:命令1 操作符 命令2 ...

常见条件

  • -a或&&:逻辑与,“而且”的意思全真才为真

  • -o或||:逻辑或,“或者”的意思一真即为真

  • !:逻辑否

     

(1)短路与 &&

CMD1 短路与 CMD2 && 同时满足命令1 和命令2 的要求 才会返回正确 全真才为真 一假即为假 第一个CMD1结果为真 ,第二个CMD2必须要参与运算,才能得到最终的结果 第一个CMD1结果为假 ,总的结果必定为假,因此不需要执行CMD2

 

(2)短路或 ||

CMD1 短路或 CMD2 一真即为真 第一个CMD1结果为真 (1),总的结果必定为1,因此不需要执行CMD2 第一个CMD1结果为假 (0),第二个CMD2 必须要参与运算,才能得到最终的结果

3.4.5 双中括号

[[ expression ]] 用法 == 左侧字符串是否和右侧的PATTERN相同 注意:此表达式用于[[ ]]中,PATTERN为通配符 =~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配 注意: 此表达式用于[[ ]]中;扩展的正则表达式

#通配符
[root@centos8 ~]#FILE=test.log
[root@centos8 ~]#[[ "$FILE" == *.log ]]
[root@centos8 ~]#echo $?
0
[root@centos8 ~]#FILE=test.txt
[root@centos8 ~]#[[ "$FILE" == *.log ]]
[root@centos8 ~]#echo $?
1
[root@centos8 ~]#[[ "$FILE" != *.log ]]
[root@centos8 ~]#echo $?
0

3.4.6 () {}

(CMD1;CMD2;...)和 {空格CMD1;CMD2;...; } 都可以将多个命令组合在一起,批量执行

[root@centos8 ~]#( cd /data;ls )
test.log
[root@centos8 ~]#pwd
/root
[root@centos8 ~]#{ cd /data;ls; }
test.log
[root@centos8 data]#pwd
/data



#()会开启子shell
[root@centos8 ~]#echo $BASHPID
1920
[root@centos8 ~]#( echo $BASHPID;sleep 100)
1979
[root@centos8 ~]#pstree -p
├─sshd(719)───sshd(1906)───sshd(1919)─┬─bash(1920)───bash(1979)───sleep(1980)
#{ } 不会开启子shell
[root@centos8 ~]#echo $BASHPID
1920
[root@centos8 ~]#{ echo $BASHPID; }
1920

3.5 if语句的结构

3.5.1分支结构

单分支

if 判断条件;

then 条件为真的分支代码

fi

双分支

if 判断条件; then 条件为真的分支代码

else 条件为假的分支代码

fi

多分支

if 判断条件1 then 条件1为真的分支代码

elif 判断条件2 then 条件2为真的分支代码

elif 判断条件3;then 条件3为真的分支代码

... else 以上条件都为假的分支代码

fi

3.5.2 case

格式

case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac

case 变量引用 in
PAT1)
 分支1
 ;;
PAT2)
 分支2
 ;;
...
*)
 默认分支
 ;;

###


4.循环语句

echo命令

echo -n   表示不换行输出
echo -e   表示输出转义符
常用的转义符
选项作用
\r 光标移至行首,并且不换行
\s 当前shell的名称,如bash
\t 插入Tab键,制表符
\n 输出换行
\f 换行,但光标仍停留在原处
\ 表示插入"\"本身转义
\b 表示退格 不显示前一个字符
\c 抑制更多的输出或不换行
[root@localhost ky15]#echo -e "12345\b678"
##退格删除前面的字符
1234678
[root@localhost ky15]#echo -e "12345\b\b678"
123678
[root@localhost ky15]#echo -e "12345\b\b\b678"
12678
[root@localhost ky15]#echo -e "12345\b\b\b\b678"
16785
###注意退格键和末尾的字符相关,超过末尾的字符数量 会出bug 了解即可

date

date查看当前系统时间

-d 你描述的日期,显示指定字符串所描述的时间,而非当前时间

%F 完整日期格式,等价于 %Y-%m-%d

% T 时间(24小时制)(hh:mm:ss)

[root@localhost ~]# date -d '-1 day' +%F 
2021-10-21

[root@localhost ~]# date +%F
2021-08-19
[root@localhost ~]# date -d '1 day ' +%F-%T
2021-08-20-23:28:42
[root@localhost mnt]# date -d "-3 day"     前三天
日历
[root@localhost data]#cal 2021
#查看日历

[root@localhost data]#cal 9 1752
      九月 1752     
日 一 二 三 四 五 六
       1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

5.正则表达式 过滤文本

  • 正则表达式:正则表达式是一种更复杂、更强大的模式匹配工具,可以用于文本处理和搜索。其语法包含了更多的元字符和特殊字符,例如.(匹配任意单个字符)、+(匹配前面的元素一次或多次)、{}(指定匹配次数范围)等。

与通配符的区别

  • 正则表达式:正则表达式是一种更复杂、更强大的模式匹配工具,可以用于文本处理和搜索。其语法包含了更多的元字符和特殊字符,例如.(匹配任意单个字符)、+(匹配前面的元素一次或多次)、{}(指定匹配次数范围)等。

主要用来匹配字符串(命令结果,文本内容)

通配符匹配文件(而且是已存在的文件)

  • 基本正则表达式

  • 扩展正则表达式

可以使用

 

man 7 regex
可以使用 man手册帮助

5.1.1 元字符(字符匹配)

元字符:

.   匹配任意单个字符,可以是一个汉字  
[]   匹配指定范围内的任意单个字符,示例:[zhou]   [0-9]   []   [a-zA-Z]   [:alpha:]
[^] 匹配指定范围外的任意单个字符,示例:[^zhou] [^a.z] [a.z]


[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围
广
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
\w #匹配单词构成部分,等价于[_[:alnum:]]
\W #匹配非单词构成部分,等价于[^_[:alnum:]]
\S     #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\s     #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意
Unicode 正则表达式会匹配全角空格符

元字符点(.)

[root@localhost ~]#ls /etc/|grep rc[.0-6] #此处的点代表字符 rc0.d rc1.d rc2.d rc3.d

5.1.2 表示次数

  • #匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配 .* #任意长度的任意字符,不包括0次 \? #匹配其前面的字符出现0次或1次,即:可有可无 + #匹配其前面的字符出现最少1次,即:肯定有且 >=1 次 {n} #匹配前面的字符n次 {m,n} #匹配前面的字符至少m次,至多n次 {,n} #匹配前面的字符至多n次,<=n {n,} #匹配前面的字符至少n次 ifconfig ens33|grep netmask|grep -o

[root@localhost ~]# echo google |grep 'go\{2\}gle'
#带表前面的o出现2次
google
[root@localhost ~]# echo gooooogle |grep 'go\{2,\}gle'  
#带表前面的o出现2次以上
gooooogle
[root@localhost ~]# echo gooooogle |grep 'go\{2,5\}gle'
#带表前面的o出现2次以上5次以下

5.1.3位置锚定

^ #行首锚定, 用于模式的最左侧 $ #行尾锚定,用于模式的最右侧 ^PATTERN$ #用于模式匹配整行 (单独一行 只有root) ^$ #空行 ^[[:space:]]*$ # 空白行

< 或 \b #词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部) > 或 \b #词尾锚定,用于单词模式的右侧 <PATTERN> #匹配整个单词

5.1.4分组或其他

分组:() 将多个字符捆绑在一起,当作一个整体处理,如:(root)+

[root@localhost ~]#echo abccc |grep "abc\{3\}"
abccc

[root@localhost ~]#echo abcabcabc |grep "\(abc\)\{3\}"
#分组 匹配abc
abcabcabc
[root@localhost ~]#echo 1abc |grep "1\|2abc"
#只匹配了1
1abc

[root@localhost ~]#echo 1abc |grep "\(1\|2\)abc"
#1abc或者2abc
1abc

5.1.5 扩展正则表达式(表示字符相差不大)

grep -E

egrep

 

 

表示次数

*   匹配前面字符任意次
? 0或1次
+ 1次或多次
{n} 匹配n次
{m,n} 至少m,至多n次
{,n}  #匹配前面的字符至多n次,<=n,n可以为0
{n,} #匹配前面的字符至少n次,<=n,n可以为0

表示分组

() 分组 分组:() 将多个字符捆绑在一起,当作一个整体处理,如:(root)+ 后向引用:\1, \2, ... | 或者 a|b #a或b C|cat #C或cat (C|c)at #Cat或cat

5.2 grep

grep [选项]… 查找条件 目标文件

  • -i:查找时忽略大小写

  • -v:反向查找,输出与查找条件不相符的行

  • -o 只显示匹配项

  • -f 对比两个文件的相同行

  • -c 匹配的行数([root@localhost ky15]# grep -c root passwd 2)

-E 使用ERE,相当于egrep
-F 不支持正则表达式,相当于fgrep
-f   file 根据模式文件,处理两个文件相同内容 把第一个文件作为匹配条件
-r   递归目录,但不处理软链接
-R   递归目录,但处理软链接

6 AWK

gawk:模式扫描和处理语言,可以实现下面功能

vim: 是将整个文件加载到内存中 再进行编辑, 受限你的内存

awk(语言): 读取一行处理一行,

在 Linux/UNIX 系统中,awk 是一个功能强大的编辑工具,逐行读取输入文本,默认以空格或tab键作为分隔符作为分隔,并按模式或者条件执行编辑命令。而awk比较倾向于将一行分成多个字段然后进行处理。AWK信息的读入也是逐行

指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理,可以在无交互

的情况下实现相当复杂的文本操作,被广泛应用于 Shell 脚

本,完成各种自动化配置任务。

工作原理:

前面提到 sed 命令常用于一整行的处理,而 awk 比较倾向于将一行分成多个“字段”然后再进行处理,且默认情况下字段的分隔符为空格或 tab 键。awk 执行结果可以通过 print 的功能将字段数据打印显示。

格式:

awk [options] 'program' var=value file…

awk 选项 模式 处理的动作 指定 '{print }'

-F 指定分隔符 -v 自定义变量 -f 脚本 awk [options] -f programfile var=value file…

#说明: program通常是被放在单引号中,并可以由三种部分组成 BEGIN语句块 模式匹配的通用语句块 END语句块

pattern{action statements;..} pattern:决定动作语句何时触发及触发事件,比如:BEGIN,END,正则表达式等 action statements:对数据进行处理,放在{}内指明,常见:print, printf

#常见选项: -F “分隔符” 指明输入时用到的字段分隔符,默认的分隔符是若干个连续空白符 -v(小v) var=value 变量赋值

awk [选项] '模式条件{操作}' 文件1 文件2....

awk -f|-v 脚本文件 文件1 文件2.....

6.1基础用法

print动作




[root@localhost ~]#awk ''
#什么都不写 空没有效果

[root@localhost ~]#awk '{print}'
##在打印一遍
dd
dd


[root@localhost ~]#awk '{print "hello"}'
#字符串需要添加双引号,单引号已被使用
1
hello
1
hello

[root@localhost ~]#awk '{print "hello"}' < /etc/passwd
[root@localhost ~]#ls | awk '{print "hello"}'

[root@localhost ~]#awk 'BEGIN{print 100+200}'
#运算
300

6.2awk 常见的内置变量

  • FS :指定每行文本的字段分隔符,缺省为空格或制表符(tab)。与 “-F”作用相同 -v "FS=:"

  • OFS:输出时的分隔符

  • NF:当前处理的行的字段个数

  • NR:当前处理的行的行号(序数)

  • $0:当前处理的行的整行内容

  • $n:当前处理行的第n个字段(第n列)

  • FILENAME:被处理的文件名

  • RS:行分隔符。awk从文件上读取资料时,将根据RS的定义就把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是\n

###########  FS  #################
[root@localhost ky15]#awk -v FS=':' '{print $1FS$3}' /etc/passwd
#此处FS 相当于于变量 -v 变量赋值 相当于 指定: 为分隔符  
[root@localhost ky15]#awk -F: '{print $1":"$3}' /etc/passwd

shell中的变量
[root@localhost ky15]#fs=":";awk -v FS=$fs '{print $1FS$3}' /etc/passwd
#定义变量传给FS


#########   支持变量   ##################
[root@localhost ky15]#fs=":";awk -v FS=$fs -v OFS="+" '{print $1,$3}' /etc/passwd
#输出分隔符

-F -FS一起使用 -F 的优先级高

6.3自定义变量

[root@localhost ~]#awk -v test='hello' 'BEGIN{print test}'
hello
awk -v test1=test2="hello" 'BEGIN{test1=test2="hello";print test1,test2}'



awk  -v test='hello gawk' '{print test}' /etc/fstab
awk  -v test='hello gawk' 'BEGIN{print test}'
awk  'BEGIN{test="hello,gawk";print test}'
awk  -F: '{sex="male";print $1,sex,age;age=18}' /etc/passwd  

6.4 模式

awk '模式{处理动作}'

不支持使用行号,但是可以使用变量NR 间接指定行号

gender ###正则表达式 /pat1/

匹配pat1 的行

/pat1/,/pat2/ #正则表达式1 到正则表达式2 之间的行 如果匹配不到2的表达式 会一直匹配到文末

pat1 正则表达式1 pat2 正则表达式2

#模糊匹配,用~表示包含,!~表示不包含

取时间

####比较操作符: ==, !=, >, >=, <, <=

#####逻辑 与:&&,并且关系 或:||,或者关系 非:!,取反

标签:脚本,shell,gy,echo,sh,localhost,root,bash
From: https://www.cnblogs.com/sl08/p/17627477.html

相关文章

  • 使用tcl脚本设置引脚配置
    tcl设置引脚tool->TCL->run#------------------GLOBAL--------------------##set_global_assignment-nameFAMILY"CycloneIVE"#set_global_assignment-nameDEVICEEP4CE6F17C8#set_global_assignment-nameRESERVE_ALL_UNUSED_PINS"ASINPUT......
  • 青龙脚本学习笔记
    1.安装https://github.com/whyour/qinglonghttps://raw.githubusercontent.com/whyour/qinglong/master/docker/docker-compose.yml 5700端口进行配置,搞完后把端口关了,免得被攻击  2.自动获取京东京豆的脚本 订阅脚本https://github.com/KingRan/KR.git ......
  • Linux之shell脚本的正则表达式
    目录一、正则表达式1.1元字符1.2表示次数一、正则表达式通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符[localhost~]#man7regex#可以使用man手册帮助1.1元字符. 匹配任意单个字符,可以是一个汉字[] 匹配指定范围内的任意单个字符,示例:[zhou]......
  • Shell编程规范与变量三
    目录1.正则表达式1.1元字符1.2表示次数1.3位置锚定1.4分组或其他1.5扩展正则表达式1.6grep2.AWK3.常用脚本1.正则表达式通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符[localhost~]#man7regex#可以使用man手册帮助1.1元字符. 匹配任意单个......
  • SQL:打印表索引脚本
    SQLSERVER 打印索引脚本declareC1cursorfor--表索引,不包含主约束索引。SELECTOBJ.OBJECT_IDAS[TABLE_ID],OBJ.NAMEAS[TABLE_NAME],--PK.nameASCONSTRAIN_NAME,idx.nameasindex_name,--索引类型:聚集索引、非聚集索引caseWHEN......
  • 通过重写js脚本文件的例子看文件操作
    有以下文件:相对路径:"Resources/MainWindow/MsgHtml/msgtmpl.txt"文件内容: 要求:由于将要进行通信,我们将external0这个网页对象作为qq的发送者,这是可行的,然而接收者只有这一个对象external是不够的,我们将上面的txt文件作为一个初始版本,最后要进行更改,并最终要写入js文件中。......
  • PowerShell 使用SqlScriptDOM对T-SQL做规则校验
    ​ 对于数据项目来说,编写Sql是一项基本任务同时也是数量最多的代码。为了统一项目代码规范同时降低CodeReview的成本,因此需要通过自动化的方式来进行规则校验。由于本人所在的项目以SQLServer数据库为基础,于是本人决定通过使用SqlScriptDom类库来做T-SQL的规则校验。如果是其......
  • Linux下Shell脚本中比较大小
    数字比较-eq等于,如:if["$a"-eq"$b"]-ne不等于,如:if["$a"-ne"$b"]-gt大于,如:if["$a"-gt"$b"]-ge大于等于,如:if["$a"-ge"$b"]-lt小于,如:if["$a"-lt"$b......
  • shell命令概述 Shell作用:命令解释器 介于操作系统内核与用户之间,负责解释命令行 获得
    shell命令概述Shell作用:命令解释器介于操作系统内核与用户之间,负责解释命令行获得命令帮助内部命令help命令的“--help”选项使用man命令阅读手册页命令行编辑的几个辅助操作Tab键:自动补齐反斜杠“\”:强制换行快捷键Ctrl+U:清空至行首快捷键Ctrl+K:清空至行尾快捷键Ctr......
  • 微信机器人定时发送脚本
    前言公司各域都有值班制度,安排人处理线上问题值班排期,工作日一人,周六周日两人(本周和下周的人)例如:本周z值班,下周s值班,下下周x值班,本周六周日z和s值班,下周六周日s和x值班因为我们值班表是发送到企业微信的群里的,就考虑建个机器人然后写一个脚本来定时发送值班安排思路:获取......