Linux云计算运维之Shell

find 搜索文件名是完全匹配

find . -name “abc*” 查询以abc开头的文件
通配符与正则表达式的区别?
通配符 :用于匹配文件名
? :匹配一个任意字符

  • :匹配0个或任意多个任意字符,也就是可以匹配任何内容
    [] : 匹配中括号中任意一个字符。例如,[abc]代表一定匹配一个字符,或者是a,或者是b,或者是c
    [-] : 匹配中括号中任意一个字符,-代表一个范围。例如,[a-z] 代表匹配一个小写字母
    [^] : 逻辑非,表示匹配不是中括号内的一个字符。例如,[^0-9]代表匹配一个不是数字的字符

grep 搜索文件名中的字符串,包含匹配

grep -n “123” abc : 搜索文件中abc的字符串是123,并且显示行号
grep -v “123” abc : 搜索文件abc中不是123的内容
grep --color=auto “123” abc :显示在文件中匹配的“123”的颜色

管道符 :

  1. 行提取命令 grep
    grep [选项] “搜索内容” 文件名
    选项 :
    -A 数字 ;列出符合条件的行,并列出后续的n行
    -B 数字 :列出符合条件的行,并列出前面的n行
    -c :统计找到的符合条件的字符串的次数
    -i :忽略大小写
    -n :输出行号
    -v :反向查找
    –color=auto : 搜索出的关键字用颜色显示

正则表达式 :用于匹配字符串,包含匹配
? :匹配前一个字符重复0次,或1次 : 只能用 egrep

 :匹配前一个字符重复0次,或任意多次

. : 匹配除了换行符外任意一个字符。
[] : 匹配中括号中任意一个字符。只匹配一个字符。例如,[abc]代表一定匹配一个字符,或者是a,或者是b,或者是c,[0-9] 匹配任意一位数字,[a-z][0-9]匹配小写字母和一位数字构成的两位字符。
[-] : 匹配中括号中任意一个字符,-代表一个范围。例如 ,[a-z]代表匹配一个小写字母。
[^] : 逻辑非,表示匹配不是中括号内的一个字符。例如,[0-9]代表匹配一个不是数字的字符。[a-z]表示任意一位非小写字母。
\ : 转义符。用于将特殊符号的含义取消。
{n} : 表示其前面的字符恰好出现n次。例如 :[0-9]{4} 匹配4位数字,[1][3-8][0-9]{9} 匹配手机号码
^ :匹配行首。例如 :^hello会匹配以hello开头的行。
$ : 匹配行位。例如 ;hello&会匹配以hello结尾的行。
{n,} : 表示其前面的字符出现不小于n次。例如 :[0-9]{2,} 表示两位及以上的数字。
{n,m} : 表示其前面的字符至少出现n次,最多出现m次。例如 :[a-z]{6,8}匹配6到8位的小写字母。

grep “^KaTeX parse error: Expected group after '^' at position 34: …空白行 grep -v "^̲” test.txt : 查询出来的空白行取反。
grep “​​1​” test.txt : 查询数字开头的

例如 :egrep “aaa?” abc :

netstat -an | grep “ESTABLISHED” | wc -l : 把所有链接服务转换成一个文本流,传递到下一个grep里面,并从这个文本流中搜索包含ESTABLISHED的字符串,再转换成文本流,去统计文本流中的行数

echo “字符串” : 把字符串输出到控制台

标准错误输出重定向
错误命令 2> 文件 :以覆盖的方式,把命令的错误输出到指定的文件或设备当中。
错误命令 2>> 文件 :以追加的方式,把命令的错误输出到指定的文件或设备当中。

正确输出和错误输出同时保存
命令 > 文件 2>&1 以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。
命令 >> 文件 2>&1 以追加的方式,把正确输出和错误输出都保存到同一个文件当中。
命令 &> 文件 以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。
命令 &>> 文件 以追加的方式,把正确输出和错误输出都保存到同一个文件当中。
命令 >> 文件1 2>>文件2 把正确的输出追加到文件1中,把错误的输出追加到文件2中。

多命令执行符合 :
; 命令1 ; 命令2 多个命令顺序执行,命令之间没有任何逻辑联系
&& 命令1 && 命令2 当命令1正确执行(Linux云计算运维之Shell_ssh?不等于0)则命令2不会执行
|| 命令1 || 命令2 当命令1执行不正确(Linux云计算运维之Shell_ssh_02?=0),则命令2不会执行

Bash中其他特殊符合 :
‘’ : 单引号。在单引号中所有的特殊符合,如“Linux云计算运维之Shell_字符串_03"、”`“(反引号)和”\“是例外,拥有”调用变量的值“、”引用命令“和”转义符“的特殊含义。
`` :反引号。反引号括起来的内容是系统命令,在Bash中会先执行它。和Linux云计算运维之Shell_ssh_04(),因为反引号非常容易看错。
$() : 和反引号作用一样,用来引用系统命令。
() : 用于一串命令执行时,()中的命令会在Shell中运行。
{} :用于一串命令执行时,{}中的命令会在当前Shell中执行。也可以用于变量变形与替换。
[] : 用于变量的测试。
# : 在Shell脚本中,#开头的行代表注释。
$ : 用于调用变量的值,如需要调用变量name的值时,需要用$name 的方式得到变量的值。
\ : 转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如$将输出“$”符号,而不当做是变量引用。

如果是把命令的结果作为变量值赋予变量,则需要使用反引号或Linux云计算运维之Shell_运维_05(date)
echo $test

变量分类 :

用户自定义变量 :名称:自定义 作用:自定义 内容:自定义
环境变量 :
用户自定义环境变量 :名称:自定义 作用:自定义 内容:自定义
系统自带环境变量 :名称:确定 作用:确定 内容:自定义
位置参数变量 :名称:确定 作用:确定 内容:自定义
预定义变量 :名称:确定 作用:确定 内容:自定义

变量查看 :

set [选项]

选项 :
-u 如果设定此选项,调用未声明变量时会报错(默认无任何提示)
-x 如果设定此选项,在命令执行之前,会把命令先输出一次

删除变量 :unset 变量名称

环境变量

环境变量设置
export age=“18”
环境变量查询和删除
env命令和set命令的区别是,set命令可以查看所有变量(包括本地变量和环境变量),而env命令只能查看环境变量

PATH变量 :系统查找命令的路径

通过echo KaTeX parse error: Expected 'EOF', got '#' at position 208: …hello.sh /bin/ #̲ 拷贝hello.sh到/bi…PATH":/root/sh # 在变量的PATH的后面,加入/root/sh目录
查看echo $PATH #查询PATH的值,变量叠加生效了
现在的PATH变量只是临时生效,一旦重启或注销就会消失,如果想要永久生效,需要写入环境变量配置文件中。

PS1变量 :命令提示符设置

通过set命令可以查看
PS1用来定义命令行的提示符的,可以按照自己的需要定义自己喜欢的提示符。PS1支持以下这些选项 :
\d: 显示日期,格式为”星期 月 日“
\H: 显示完整的主机名。如默认主机名“localhost.localdomain”
\h: 显示简写主机名。如默认主机名 “localhost”
\t: 显示24小时制时间,格式为“HH:MM:SS”
\T: 显示12小时制时间,格式为“HH:MM:SS”
\A: 显示24小时制时间,格式为“HH:MM”
@: 显示12小时制时间,格式为“HH:MM am/pm”
\u: 显示当前用户名
\v: 显示Bash的版本信息
\w: 显示当前所在目录的完整名称
\W: 显示当前所在目录的最后一个目录
#: 执行的第几个命令
$: 提示符。如果是root用户会显示提示符为“#”,如果是普通用户会显示提示符为$

例如 :PS1=’[\u@\H:\A \w]# ’

位置参数变量 :

$n : n为数字,$0代表命令本身,$1-Linux云计算运维之Shell_字符串_06{10}.
Linux云计算运维之Shell_运维_07*把所有的参数看成一个整体
Linux云计算运维之Shell_运维_08@把每个参数区分对待
$# : 把这个变量代表命令行中所有参数的个数

例如 :./count.sh 22 23 #$0 就是输出的是./count.sh

预定义变量 :

$? : 最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由
命令自己来决定),则证明上一个命令执行不正确了。
$$ : 当前进程的进程号(PID)
$! : 后台运行的最后一个进程的进程号(PID)

Shell 的运算符

需要进行数值运算,采用以下三种方法中的任意一种 :
使用declare声明变量类型 :
既然所有变量的默认类型是字符串型,使用declare命令就可以实现声明变量的类型 :
declare [+/-][选项] 变量名
选项 :

  • :给变量设定类型属性
  • :取消变量的类型属性
    -a : 将变量声明为数组类型
    -i : 将变量声明为整数型(integer)
    -r : 将变量声明为只读变量。注意,一旦设置为只读变量,既不能修改变量的值;
    也不能删除变量,甚至不能通过 + r 取消只读属性
    -x : 将变量声明为环境变量
    -p : 显示指定变量的被声明的类型
    例如 :a=11 b=22 declare -i c=Linux云计算运维之Shell_ssh_09b echo $c

变量的测试与内容置换

变量置换方式 变量y没有设置 变量y为空值 变量y设置值

x=Linux云计算运维之Shell_运维_10y
x=Linux云计算运维之Shell_运维_11y
x=Linux云计算运维之Shell_ssh_12{y:+新值} x为空 x为空 x=新值
x=Linux云计算运维之Shell_linux_13y y值不变
x=Linux云计算运维之Shell_ssh_14y y值不变
x=Linux云计算运维之Shell_shell_15y
x=Linux云计算运维之Shell_ssh_16y

环境变量配置文件

  1. source 命令 : 不用系统重启,直接加载配置文件
    source 配置文件 或者 . 配置文件
  2. 环境变量配置文件
    1)。登录时生效的环境变量配置文件
    在Linux系统登陆时主要生效的环境变量配置文件有以下五个 :
    /etc/profile
    /etc/profile.d/*.sh
    ~/.bash_profile
    /etc/bashrc

在etc目录下的对所有用户生效,在家目录下的只对当前用户生效

在用户登陆过程先调用/etc/profile文件
在这个环境变量配置文件中会定义这些默认环境变量 :
USER : 根据登录的用户,给这个变量赋值(就是让USER变量的值是当前用户)
LOGNAME变量 :根据USER变量的值,给这个变量赋值。
MAIL变量 :根据登录的用户,定义用户的邮箱为/var/spool/mail/用户名
PATH变量 :根据登录的用户的UID是否为0,判断PATH变量是否包含/sbin、/usr/sbin和/usr/local/sbin这三个系统命令目录。
HOSTAME变量 :更加主机名,给这个变量赋值。
HISTSIZE变量 :定义历史命令的保存条数。
umask :定义umask默认权限。注意/etc/profile文件中的umask权限是在“有用户登录过程(也就是输入了用户名和密码)”时才会生效。
调用/etc/profile.d/*.sh文件,也就是调用/etc/profile.d/目录下所有以.sh结尾的文件。

由/etc/profile 文件调用/etc/profile.d/*.sh文件
这个目录中所有以.sh结尾的文件都会被/etc/profile文件调用,这里最常用的就是lang.sh文件,而这个文件又会调用/etc/sysconfig/i18n文件。这是默认语系配置文件。

由/etc/profile文件调用~/.bash_profile文件
~/.bash_profile文件就没有那么复杂了,这个文件主要实现了两个功能L:
调用了~/.bashrc文件
在PATH变量后面加入了“:$HOME/bin”这个目录。那也就是说,如果我们在自己的家目录中建立bin目录,然后把自己的脚本放入“~/bin”目录,就可以直接执行脚本,而
不用通过目录执行了。
/.bash_profile文件调用/.bashrc文件
在~/.bashrc文件中主要实现了 :
定义默认别名,所以把自己定义的别名也放入了这个文件。
调用/etc/bashrc
由~/.bashrc 调用了/etc/bashrc文件
在/etc/bashrc文件中主要定义了这些内容 :
PS1变量 :也就是用户的提示符,如果我们想要永久修改提示符,就要在这个文件中修改
umask : 定义umask默认权限。这个文件中定义的umask是针对“没有登录过程”(也就是不需要输入用户名和密码时,比如从一个终端切换到另一个终端,或进入子Shell)“
时生效的。如果是”有用户登录过程“,则是/etc/profile文件中的umask生效。
PATH变量 :会给PATH变量追加值,这也是在”没有用户登录过程“是才调用。在”有用户登录过程“时,/etc/profile.d/*.sh文件已经被/etc/profile文件调用过。
如果打算对所有用户生效,可以修改/etc/profile环境变量配置文件;如果你的修改只是给自己使用的,那么可以放入~/.bash_profile或!/。bashrc这两个配置文件
中的任一个。
可是如果我们误删除了这些环境变量,比如删除了/etc/bashrc文件,或删除了/.bashrc文件,那么这些文件中配置就会失效(/.bashrc文件会调用/etc/bashrc文件)。那么
我们的提示符就会变成 : -bash-4.#

注销时生效的环境变量配置文件
在用户退出登录时,只会调用一个环境变量配置文件,就是~/.bash_logout,这个文件默认没有写入任何内容,可是如果我们希望再退出登录时执行一些操作,比如清除历史命令,备份某些数据,就可以把命令写入这个文件。
~/.bash_history文件,保存的是历史命令

字符串截取和替换命令

cut列提取命令
cut [选项] 文件名
选项 :
-f 列号 :提取第几列
-d 分隔符 :按照指定分隔符分割列
-c 字符范围 :不依赖分隔符来区分列,而是通过字符范围(行首为0)来进行字段提取。”n-“表示从第n个字符到行尾;”n-m“从第n个字符到第m个字符:”-m“表示从第1个字符到第m个字符。

cut命令的默认分隔符是制表符,也就是”tab“键,不过对空格符可是支持的不好,我们先建立一个测试文件,然后看看cut命令的作用吧 :
vi student.txt
ID Name gender Mark
1 Liming M 86
2 Sc M 90
3 Tg M 83

awk ‘{printf $2 “\t” $6 “\n”}’ student.txt : 输出第二列和第六列 (printf输出需要换行符,print输出不需要换行符
awk的条件 :
条件的类型 条件 说明
awk保留字 BEGIN 在awk程序一开始时,尚未读取任何数据之前执行。BEGIN后的动作只在程序开始时执行一次
END 在awk程序处理完所有数据,即将结束时执行。END后的动作只在程序结束时执行一次
关系运算符 > 大于
< 小于

= 大于等于
<= 小于等于
== 等于。用于判断两个值是否相等,如果是给变量赋值,请使用“=”号
!= 不等于
A~B 判断字符串A中是否包含能匹配B表达式的子字符串
A !~ B 判断字符串A中是否不包含能匹配B表达式的子字符串
正则表达式 /正则/ 如果在“//” 中可以写入字符,也可以支持正则表达式
BEGIN是awk的保留字,是一种特殊的条件类型。BEGIN的执行时机是“在awk程序一开始时,尚未读取任何数据之前执行”。一旦BEGIN后的动作执行一次,当awk开始从文件中读入数据,BEGIN的条件
就不再成立,所以BEGIN定义的动作只能被执行一次。
例如 :awk ‘BEGIN{printf “This is a transcript \n”} {printf “\t” $4 “\n”}’ student.txt

关系运算符
举几个例子。假设看看平均成绩大于等于87分的学员是谁,就可以这样输入命令 ;
cat student.txt | grep -v Name | awk ‘$4 >= 87 {printf $2 “\n”}’

awk编程

printf格式化输出

printf ‘输出类型输出格式’ 输出内容
输出类型 :
%ns :输出字符串。n是数字指代输出几个字符
%ni :输出整数。n是数字指代输出几个数字
%m.nf : 输出浮点数。m和n是数字,指代输出的整数位数和小数位数。如%8.2f
代表共输出8位数,其中2位是小数,6位是整数。
输出格式 :
\a : 输出警告声音
\b : 输出退格键,也就是Backspace键
\f : 清楚屏幕
\n : 换行

awk 基本使用

awk ‘条件1{动作1} 条件2{动作2}…’ 文件名
条件(Pattern):
一般使用关系表达式作为条件。这些关系表达式非常多,具体参考表12-3所示,例如 :
x > 10 判断变量x是否大于10
x == y 判断变量x是否等于变量y
A ~ B 判断字符串A中是否包含能匹配B表达式的子字符串
A !~ B 判断字符串A中是否不包含能匹配B表达式的子字符串
动作(Action):
格式化输出
流程控制语句

sed命令

sed主要是用来将数据进行选取、替换、删除、新增的命令,我们看看命令的语法 :
sed 【选项】‘【动作】’ 文件名
选项 :
-n 一般sed命令会 把所有数据都输出到屏幕,如果加入此选择,则只会把经过sed命令处理的行输出到屏幕。
-e 允许对输入数据英语多条sed命令编辑。
-f 脚本文件名 :从sed脚本中读入sed操作,和awk命令的-f非常类似,
-r 在sed的修改结果直接修改读取数据的文件,而不是由屏幕输出
动作 :
a : 追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。
c : 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用“\”代表数据未完结。
i : 插入,在当期行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。
d : 删除,删除指定的行。
p :打印,输出指定的行。
s :字串替换,用一个字符串替换另外一个字符串。格式为“行范围 s/
旧字串/新字串/g“ (和vim中的替换格式类似)
对sed命令要注意,sed所做的修改并不会直接改变文件的内容(如果是用管道符接收的命令的输出,这种情况连文件都没有),而是把修改结果只是显示到屏幕上,除非用“-i”选项才会直接修改文件

字符处理命令

排序命令 sort
sort 【选项】 文件名
选项 :
-f :忽略大小写
-b :忽略每行前面的空白部分
-n :以数值型进行排序,默认使用字符串型排序
-r :反向排序
-u :删除重复行。就是uniq命令
-t :指定分隔符,默认是分隔符是制表符
-k n[m] : 按照指定的字段范围排序。从第n字段开始,m字段结束(默认到行末尾)
sort 命令默认是用每行开头第一个字符来进行排序的,比如 :
sort -n -t “:” k 3,3 /etc/passwd
当然“-k” 选项可以直接使用 “-k 3”,代表从第三字段到行尾都排序(第一个字符先排序,如果一致,第二个字符再排序,直到行尾)
uniq
unid命令是用来取消重复行的命令,其实和“sort -u”选项是一样的。命令格式如下 :
uniq 【选项】文件名
-i :忽略大小写
统计命令 wc
wc 【选项】文件名
选项 :
-l :只统计行数
-w :只统计单词数
-m :只统计字符数

条件判断

1. 按照文件类型进行判断

测试选项

作用

-b 文件

判断该文件是否存在,并且是否为块设备文件(是块设备文件为真)

-c 文件

判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真

-d 文件

判断该文件是否存在,并且是否为目录文件(是目录为真)

-e 文件

判断该文件是否存在(存在为真)

-f 文件

判断该文件是否存在,并且是否为普通文件(是普通文件为真)

-L 文件

判断该文件是否存在,并且是否为符号链接文件(是符号链接文件为真

-p 文件

判断该文件是否存在,并且是否为管道文件(是管道文件为真)

-s 文件

判断该文件是否存在,并且是否为非空(非空为真)

-S 文件

判断该文件是否存在,并且是否为套接字文件(是套接字文件为真)

2. 按照文件权限进行判断

test是非常完善的判断命令,还可以判断文件的权限。

测试选项

作用

-r 文件

判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真)

-w 文件

判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真)

-x 文件

判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真)

-u 文件

判断该文件是否存在,并且是否该文件拥有SUID权限(有SUID权限为真)

-g 文件

判断该文件是否存在,并且是否该文件拥有SGID权限(有SGID权限为真)

-k 文件

判断该文件是否存在,并且是否该文件拥有SBit权限(有SBit权限为真)

3. 两个文件之间进行比较

测试选项

作用

文件 1 -nt 文件 2

判断文件 1 的修改时间是否比文件 2 的新(如果新则为真)

文件 1 -ot 文件 2

判断文件 1 的修改时间是否比文件 2 的旧(如果旧则为真)

文件 1 -ef 文件 2

判断文件 1 是否和文件 2 的Inode号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法

4.两个整数之间比较

测试选项

作用

整数 1 -eq 整数 2

判断整数 1 是否和整数 2 相等(相等为真)

整数 1 -ne 整数 2

判断整数 2 是否和整数 2 不相等(不相等位置)

整数 1 -gt 整数 2

判断整数 1 是否大于整数 2 (大于为真)

整数 1 -lt 整数 2

判断整数 1 是否小于整数 2(小于为真)

整数 1 -ge 整数 2

判断整数 1 是否大于等于整数 2(大于等于为真)

整数 1 -le 整数 2

判断整数 1 是否小于等于整数 2(小于等于为真)

5. 字符串的判断

测试选项

作用

-z 字符串

判断字符串是否为空(为空返回真)

-n 字符串

判断字符串是否为非空(非空返回真

字符串1 == 字串2

判断字符串1是否和字符串2相等(相等返回真)

字串 1 != 字串 2

判断字符串1是否和字符串2不相等(不相等返回真)

6. 多重条件判断

测试选项

作用

判断 1 -a 判断 2

逻辑与,判断 1 和判断 2 都成立,最终的结果才为真

判断 1 -o 判断 2

逻辑或,判断 1 和 判断 2 有一个成立,最终的结果就为真

!判断

逻辑非,使原始的判断式取反

流程控制

1. if条件判断

1)单分之if条件语句
单分之条件语句最为简单,就是只有一个判断条件,如果符合条件则执行某个程序,否则什么事情都不做。语法如下 :
if [ 条件判断式 ] ; then
程序
fi
单分之条件语句需要注意几个点 :

  1. if语句使用fi结尾,和一般语言使用大括号结尾不同
  2. [ 条件表达式 ] 就是使用 test 命令判断,所以中括号和条件判断式之间必须有空格
  3. then 后面跟符合条件之后执行的程序,可以放在[] 之后,用“:”分割。也可以换行斜日,就不需要“;”了,比如单分支if语句还可以这样写 :
    if [ 条件判断式 ]
    then
    程序
    fi
    案例1 :
#!/bin/bash

aa=$( jps | grep TestDemo | awk '{print $2}' )

if [ "$aa" != "TestDemo" ]
then
java -cp /root/test-demo-0.0.1-SNAPSHOT.jar com.example.testdemo.TestDemo
else
echo "java is ok"
fi

2)双分支if条件语句
if [ 条件判断式 ]
then
条件成立时,执行的程序
else
条件不成立时,执行的另一个程序
fi
案例2 :

#!/bin/bash

aa=$( jps | grep TestDemo | awk '{print $2}' )

if [ "$aa" != "TestDemo" ]
then
java -cp /root/test-demo-0.0.1-SNAPSHOT.jar com.example.testdemo.TestDemo
else
echo "java is ok"
fi

3)多分支if条件语句
if [ 条件判断式 1 ]
then
当条件判断式 1 成立时,执行程序1
elif [ 条件判断式 2 ]
then
当条件判断式 2 成立时,执行程序 2
else
当所有条件都不成立时,最后执行此程序
fi
案例3 :

#!/bin/bash

read -p "Please input a filename: " filename

if [ -z $filename ]
then
echo "11111"
exit 101
elif [ ! -e $filename ]
then
echo "2222222"
exit 102
elif [ -f $filename ]
then
echo "$filename
elif [ -d $filename ]
then
echo "$filename
else
echo "$filename
fi

案例4 :

#!/bin/bash
#字符界面加减乘除计算器

read -t 30 -p "Please input num1 : " num1
read -t 30 -p "Please input num2 : " num2
#通过 read 命令接收要计算的数值,并赋予变量num1和num2
read -t 30 -p "Please input a operator : " ope
# 通过 read 命令接收要计算的符号,并赋予变量ope

if [ -n "$num1" -a -n "$num2" -a -n "$ope" ]
#第一层判断,用来判断num1、num2和ope中都有值
then
test1=$(echo $num1 | sed ' s/[0-9]//g')
test2=$(echo $num2 | sed 's/[0-9]//g')
#定义变量test1和test2的值为$(命令)的结果
#后续命令作用是,把变量test1的值替换为空。如果能替换为空,证明num1的值为数字
#如果不能替换为空,证明num1的值为非数字。我们使用这种方法判断变量num1的值为数字
#用同样的方法测试test2变量
if [ -z "$test1" -a -z "$test2" ]
# 第二层判断,用来判断num1和num2为数值
#如果变量test1和test2的值为空,则证明num1和num2是数字
then
#如果 test1和test2是数字,则执行以下命令
if [ "$ope" == '+' ]
#第三层判断用来确认运算符
#测试变量$ope中是什么运算符
then
value=$(( $num1 + $num2 ))
#如果是加号则执行加法运算
elif [ "$ope" == '-' ]
then
value=$(( $num1 - $num2 ))
#如果是减号,则执行减法运算
elif [ "$ope" == '*' ]
then
value=$(( $num1 * $num2 ))
elif [ "$ope" == '/' ]
then
value=$(( $num1 / $num2 ))
else
echo "Please enter a valid symbol"
#如果运算符不匹配,提示输入有效的符号
exit 10
# 并退出程序,返回错误代码10
fi
else
# 如果test1和test2不为空,说明num1和num2不是数字
echo "Please enter a valid value"
#则提示输入有效的数值
exit 11
#并退出程序,返回错误代码 11
fi
else
echo "qing shuru neirong"
exit 12
fi
echo "$num1 $ope $num2 : $value"

4)多分支 case 条件语句
case 语句和if … elif … else 语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而if语句可以判断多种条件关系。case语句语法如下 :
case $变量名 in
“值 1” )
如果变量的值等于值1,则执行程序 1
;;
“值 2” )
如果变量的值等于值2,则执行程序 2
;;
… 省略其他分支…
* )
如果变量的值都不是以上的值 则执行此程序
;;
esac
这个语句需要注意以下内容 :
case 语句,会取出变量中的值,然后与语句体中的值逐一比较。如果数值符合,则执行对应的程序,如果数值不符,则依次比较下一个值。如果所有的值都不符合,则执行“)” (“”代表所有其他值)中的程序
case语句以“case” 开头,以 “esac” 结尾。
案例5 :

#!/bin/bash

echo "want to beijing,please input 1"
echo "want to shanghai,please input 2"
echo "want to chendu,please input 3"

read -t 30 -p "please input your choice: " cho

case $cho in
"1")
echo "beijing111111111"
;;
"2")
echo "shanghai22222222"
;;
"3")
echo "chendu333333333"
;;
*)
echo "error input"
;;

3 for 循环
for 循环是固定循环,也就是在循环时已经知道需要进行几次的循环,有时也把for循环称为计数循环。for的语法有如下两种 :
语法一 :
for 变量 in 值1 值2 值3 …
do
程序
done
这种语法中 for 循环的次数,取决于in后面值的个数(空格分隔),有几个值就循环几次,并且每次循环都把值赋予变量。也就是说,假设in后面有三个值,for 会循环三次,第一次循环会把值 1 赋予变量,第二次循环会把值 2 赋予变量,依次类推。
语法二 :
for (( 初始值 ;循环控制条件 ;变量变化 ))
do
程序
done
语法二中需要注意 :
初始值 :在循环开始时,需要给某个变量赋予初始值,如 i = 1;
循环控制条件 :用于指定变量循环的次数,如 i <= 100,则只要i的值小于等于100,循环就会继续;
案例6 :

#!/bin/bash

cd /root/sh/

ls *.tar.gz > tar.log
ls * .tgz >> tar.log & >/dev/null

aa=$( cat tar.log | wc -l )

for (( i = 1; i <= "$aa"; i=i+1 ))
do
bb=$( cat tar.log | awk 'NR=='$i' {print $1}' )
tar -zxvf $bb -C /root/sh
done

案例7 :

#!/bin/bash

cd /root/sh/

ls *.tar.gz > tar.log
ls *.tgz >> tar.log &>/dev/null
ls *.tar.bz2 >> tar.log &>/dev/null


for i in $( cat tar.log )
do
tar -zxvf $i
done

rm

案例8 :

#!/bin/bash

grep "^[0-9]\{1,3}\.[0-9]\{1,3}\.[0-9]\{1,3}\.[0-9]\{1,3\}$" /root/ip.txt > /root/ip_test1.txt

#先通过正则,把明显不符合规则的ip过滤,把结果保存在ip_test1.txt临时文件中

line=$( wc -l /root/ip_test1.txt | awk '{print $1}' )
# 统计 test1中有几行IP
echo "" >/root/ip_test.txt
#清空最终数据文件

for (( i=1; i<=$line;i=i+1 ))
#有几行,循环几次
do
cat/root/ip_test1.txt | awk 'NR=='$i'{print}' >/root/ip_test2.txt #第几次循环,就把第几行读入 ip_test2.txt文件(此文件中只有一行IP)
a=$( cat /root/ip_test2.txt | cut -d '.' -f 1 )
b=$( cat /root/ip_test2.txt | cut -d '.' -f 2 )
c=$( cat /root/ip_test2.txt | cut -d '.' -f 3 )
d=$( cat /root/ip_test2.txt | cut -d '.' -f 4 )
#分别把IP地址的四个数值分别读入变量a、b、c、d

if [ "$a" -lt 1 -o "$a" -gt 255 ]
#如果第一个数值小于1或大于等于255
then
continue
#则退出本次循环
fi

if [ "$b" -lt 0 -o "$b" -gt 255 ]
then
continue
fi

if[ "$c" -lt 0 -o "$c" -gt 255 ]
then
continue
fi

if [ "$d" -lt 0 -o "$d" -gt 255 ]
then
continue
fi
#依次判断四个ip数值是否超出范围,如果超出,退出本次循环

cat /root/ip_test2.txt >> /root/ip_test.txt
#如果四个IP数值都符合要求,则把合法IP记录在文件中
done

rm

案例9 :

#!/bin/bash
i=1
s=0
#给变量i和变量s复制
while [ $i -le 100 ]
#如果变量i的值小于等于100,则执行循环
do
s=$(( $s+$i ))
i=$(( $i+1 ))
done
echo "The sum is : $s"

案例 :10

#!/bin/bash
read -p "Please input a number : " -t 30 num
#接收用户的输入,并把输入赋予变量num
y=$( echo $num | sed 's/[0-9]//g' )
#如果变量num的值是数字,则把num的值替换为空,否则不替换
#把替换之后的值赋予变量y
[ -n "$y" ] && echo "Error,Please input a number!" && exit 18
#判断变量y的值如果不为空,输出报错信息,退出脚本,退出返回值为18
echo "The number is : $num"
#如果没有退出,则打印变量num中的数字

案例11 :

#!/bin/bash
i=1
s=0
until [ $i -gt 100 ]
do
s=$(( $s+$i ))
i=$(( $i+1 ))
done
echo "This is sum : $s"

案例12 :

#!/bin/bash
for (( i=1;i<=10;i=i+1 ))
do
if [ "$i" -eq 4 ]
then
break
fi
echo $i
done

  1. 0-9​​↩︎​