乐趣区

关于linux:shell

一、Shell 概述

  • Shell 是一个 == 命令行解释器 ==,它为用户提供了一个向 Linux 内核发送申请以便运行程序的界面零碎级程序,用户能够用 Shell 来启动、挂起、进行甚至是编写一些程序。
  • Shell 还是一个性能相当弱小的编程语言,易编写,易调试,灵活性较强。Shell 是解释执行的脚本语言,在 Shell 中能够间接调用 Linux 系统命令。

二、Shell 脚本的执行形式

1、echo 输入命令
echo [选项] [输入内容]
选项:-e:反对反斜线管制的字符转换
控制字符 作用
\ \ 输入自身
a 输入正告音
b 退格键,也就是向左删除键
c 勾销输入行末的换行符。和“-n”选项统一
e ESCAPE 键
f 换页符
n 换行符
r 回车键
t 制表符,也就是 Tab 键
v 垂直制表符
0nnn 依照八进制 ASCII 码表输入字符。其中 0 为数字零,nnn 是三位八进 制数
xhh 依照十六进制 ASCII 码表输入字符。其中 hh 是两位十六进制数
[root@peiqi ~]# echo -e "ab\bc"
ac
[root@peiqi ~]# echo -e "a\tb\tc\nd\te\tf"
a    b    c
d    e    f
[root@peiqi ~]# echo -e "\e[1;31m 你好吗 \e[0m" 
# 输入带色彩的后果
#30m= 彩色,31m= 红色,32m= 绿色,33m= 黄色 
#34m= 蓝色,35m= 洋红,36m= 青色,37m= 红色
2、第一个脚本
[root@peiqi ~]# vim helloworld.sh
#!/bin/Bash
echo "hello world"
3、脚本执行

两种形式:

  • 赋予执行权限,间接运行

    chmod 755 helloworld.sh
    ./helloworld.sh
  • 通过 Bash 调用执行脚本

    bash helloworld.sh

三、Bash 的基本功能

1、历史命令

history [选项] [历史命令保留文件] 
选项:-c:清空历史命令 
    -w:把缓存中的历史命令写入历史命令保留文件 ~/.bash_history 

历史命令默认会保留 1000 条,能够在环境变量配置文件 /etc/profile 中进行批改。

历史命令的调用:
  • 应用上、下箭头调用以前的历史命令
  • 应用 !n 反复执行第 n 条历史命令
  • 应用 !! 反复执行上一条命令
  • 应用 ! 字串 反复执行最初一条以该字串结尾的命令

2、命令别名

# 设定命令别名
alias 别名 = 原命令
# 查问命令别名
alias
# 删除别名
unalias 别名
# 让别名永恒失效
vim /root/.bashrc

3、罕用快捷键

快捷键 作用
Ctrl+A 把光标挪动到命令行结尾。如果咱们输出的命令过长,想要把光标挪动到命令行结尾时应用。
Ctrl+E 把光标挪动到命令行结尾。
Ctrl+C 强制终止以后的命令。
Ctrl+L 清屏,相当于 clear 命令。
Ctrl+U 删除或剪切光标之前的命令。我输出了一行很长的命令,不必应用退格键一个一个字符的删除,应用这个快捷键会更加不便。
Ctrl+K 删除或剪切光标之后的内容。
Ctrl+Y 粘贴 ctrl+ U 或 ctrl+ K 剪切的内容。
Ctrl+R 在历史命令中搜寻,按下 ctrl+ R 之后,就会呈现搜寻界面,只有输出搜寻内容,就会从历史命令中搜寻。
Ctrl+D 退出以后终端。
Ctrl+Z 暂停,并放入后盾。这个快捷键牵扯工作治理的内容,咱们在系统管理章节具体介绍。
Ctrl+S 暂停屏幕输入。
Ctrl+Q 复原屏幕输入。

4、输入重定向

规范输入输出:
设施 设施文件名 文件描述符 类型
键盘 /dev/stdin 0 规范输出
显示器 /dev/stdout 1 规范输入
显示器 /dev/stderr 2 规范谬误输入
输入重定向
类 型 符 号 作用
规范输入重定向 命令 > 文件 以笼罩的形式,把命令的正确输入输入到指定的文件或设施当中。
规范输入重定向 命令 >> 文件 以追加的形式,把命令的正确输入输入到指定的文件或设施当中。
规范谬误输入重定向 谬误命令 2> 文件 以笼罩的形式,把命令的谬误输入输入到指定的文件或设施当中。
规范谬误输入重定向 谬误命令 2>> 文件 以追加的形式,把命令的谬误输入输入到指定的文件或设施当中。
命令 > 文件 2>&1 以笼罩的形式,把正确输入和谬误输入都保留到同一个文件当中。
命令 >> 文件 2>&1 以追加的形式,把正确输入和谬误输入都保留到同一个文件当中。
正确输入和谬误输入同时保留 命令 &> 文件 以笼罩的形式,把正确输入和谬误输入都保留到同一个文件当中。
命令 &>> 文件 以追加的形式,把正确输入和谬误输入都保留到同一个文件当中。
命令 >> 文件 1 2>> 文件 2 把正确的输入追加到文件 1 中,把谬误的输入追加到文件 2 中。

5、多命令程序执行

多命令执行符 格局 作用
; 命令 1 ; 命令 2 多个命令程序执行,命令之间没有任何逻辑联系
&& 命令 1 && 命令 2 逻辑与。当命令 1 正确执行,则命令 2 才会执行;当命令 1 执行不正确,则命令 2 不会执行
\ \ 命令 1 \ \ 命令 2 逻辑或。当命令 1 执行不正确,则命令 2 才会执行;当命令 1 正确执行,则命令 2 不会执行
[root@peiqi ~]# ls ; date
helloworld.sh
Sat Aug 15 11:51:42 CST 2020
[root@peiqi ~]# ls && echo yes
helloworld.sh
yes
[root@peiqi ~]# ls 1 || echo no
ls: cannot access 1: No such file or directory
no

6、管道符

命令 1 | 命令 2
# 命令 1 的正确输入作为命令 2 的操作对象 
[root@peiqi ~]# ps -ef | grep bash | grep -v "grep"
root     12026 12023  0 11:03 pts/1    00:00:00 -bash
1000     23691 22856  0 Jul26 ?        00:00:00 bash
grep [选项] 搜寻内容
选项:-i:疏忽大小写 
    -n:输入行号 
    -v:反向查找 
    --color=auto:搜寻出的关键字用色彩显示

7、特殊符号

符号 作用
单引号。在单引号中所有的特殊符号,如 $ 和 ` 都没有非凡含意
“” 双引号。在双引号中特殊符号都没有非凡含意,然而 $ 和 ` 和 是例外,领有“调用变量的值”、“援用命令”和“本义符”的非凡含意
反引号。反引号括起来的内容是系统命令,在 Bash 中会先执行它。$()作用一样,不过举荐应用 $(),因为反引号非常容易看错
$() 和反引号作用一样,用来援用系统命令
# 在 Shell 脚本中,# 结尾的行代表正文
$ 用于调用变量的值,如须要调用变量 name 的值时,须要用 $name 的形式失去变量的值
\ 本义符,跟在 之后的特殊符号将失去非凡含意,变为一般字符。如 \$ 将输入 $ 符号,而不当做是变量援用
# 反引号与 $()
[root@peiqi ~]# echo `ls`
a b c
[root@peiqi ~]# echo $(date)
Sat Aug 15 12:12:25 CST 2020
# 单引号与双引号
[root@peiqi ~]# name=pd
[root@peiqi ~]# echo '$name'
$name
[root@peiqi ~]# echo "$name"
pd
[root@peiqi ~]# echo '$(date)'
$(date)
[root@peiqi ~]# echo "$(date)"
Sat Aug 15 12:13:43 CST 2020

四、Bash 的变量

1、用户自定义变量

变量是计算机内存的单元,其中寄存的值能够扭转。当 Shell 脚本须要保留一些信息时,如一个文件名或是一个数字,就把它寄存在一个变量中。每个变量有一个名字,所以很容易援用它。应用变量能够保留有用信息,使零碎获知用户相干设置,变量也能够用于保留临时信息。

变量设置规定:
  • 变量名称能够由字母、数字和下划线组成,然而不能以数字结尾,如果变量名是 2name 则是谬误的
  • 在 Bash 中,变量的默认类型都是字符串型,如果要进行数值运算,则必修指定变量类型为数值型
  • 变量用等号连贯值,等号左右两侧不能有空格
  • 变量的值如果有空格,须要应用单引号或双引号括起来
  • 在变量的值中,能够应用 本义符
  • 如果须要减少变量的值,那么能够进行变量值的叠加。不过变量须要用双引号蕴含 “$ 变量名 ” 或用 ${变量名} 蕴含
  • 如果是把命令的后果作为变量值赋予变量,则须要应用 反引号 或 $() 蕴含命令
  • 环境变量名倡议大写,便于辨别
变量分类:
  • 用户自定义变量
  • 环境变量:这种变量中次要保留的是和零碎操作环境相干的数据
  • 地位参数变量:这种变量次要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的
  • 预约义变量:是 Bash 中曾经定义好的变量,变量名不能自定义,变量作用也是固定的
本地变量:
  • 变量定义

    [root@peiqi ~]# name=alex
  • 变量叠加

    [root@peiqi ~]# a=123
    [root@peiqi ~]# a="$a"456
    [root@peiqi ~]# a=${a}789
  • 变量调用

    [root@peiqi ~]# echo $a
    123456789
  • 变量查看

    [root@peiqi ~]# set
  • 变量删除

    [root@peiqi ~]# unset a

2、环境变量

用户自定义变量只在以后的 Shell 中失效,而环境变量会在以后 Shell 和这个 Shell 的所有子 Shell 当中失效。如果把环境变量写入相应的配置文件,那么这个环境变量就会在所有的 Shell 中失效。

设置环境变量:
# 申明变量
export 变量名 = 变量值 
# 查问变量
env 
# 删除变量
unset 变量名
零碎常见环境变量:
# PATH:零碎查找命令的门路 
[root@peiqi ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/mysql/bin:/opt/go/bin:/gopath/bin:/root/bin
# PATH 变量叠加 
[root@peiqi ~]# PATH="$PATH":/root/sh
[root@peiqi ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/mysql/bin:/opt/go/bin:/gopath/bin:/root/bin:/root/sh
# PS1:定义零碎提示符的变量
\d:显示日期,格局为“星期 月 日”\h:显示简写主机名。如默认主机名“localhost”\t:显示 24 小时制工夫,格局为“HH:MM:SS”\T:显示 12 小时制工夫,格局为“HH:MM:SS”\A:显示 24 小时制工夫,格局为“HH:MM”\u:显示以后用户名 
\w:显示以后所在目录的残缺名称 
\W:显示以后所在目录的最初一个目录 
\#:执行的第几个命令 
\$:提示符。如果是 root 用户会显示提示符为“#”,如果是普通用户会显示提示符为“$”# 示例
[root@peiqi ~]# PS1='[\u@\t \w]\$' 
[root@14:27:42 ~]#PS1='[\u@\@ \h \# \W]\$'
[root@02:28 PM peiqi 12 ~]#PS1='[\u@\h \W]\$'
[root@peiqi ~]#

3、地位参数变量

地位参数变量 作用
$n n 为数字,$0 代表 shell 脚本自身,$​1 -​ $9 代表第 1 到第 9 个参数,十以上的参数须要用大括号蕴含 ${10}
$* 这个变量代表命令行中所有的参数,$* 把所有的参数看成一个整体
$@ 这个变量也代表命令行中所有的参数,不过 $@ 把每个参数辨别看待
$# 这个变量代表命令行中所有参数的个数
示例 1:
[root@peiqi ~]#vim test1.sh
    #!/bin/bash
    n1=$1
    n2=$2
    # 变量 sum 的和是 n1 加 n2
    sum=$(($n1 + $n2))
    #打印变量 sum 的值
    echo $sum
[root@peiqi ~]#bash test1.sh 10 20
30
示例 2:
[root@peiqi ~]#vim test2.sh
    #!/bin/bash 
    # 应用 $# 代表所有参数的个数
    echo "$#"
    # 应用 $* 代表所有的参数  
    echo "$*" 
    # 应用 $@也代表所有参数 
    echo "$@" 
[root@peiqi ~]#bash test2.sh 4 5 6
3
4 5 6
4 5 6

示例 3:$* 与 $@ 的区别

[root@peiqi ~]#vim test3.sh
    #!/bin/bash
    echo '-----------------"$ *"-----------------'
    # "$*" 中的所有参数看成是一个整体,所以这个 for 循环只会循环一次 
    for i in "$*" 
        do 
            echo "$i" 
        done
    echo '-----------------"$ @"-----------------'
    # "$@" 中的每个参数都看成是独立的,所以有几个参数,就会循环几次
    for j in "$@" 
        do 
            echo "$j" 
        done
    echo '----------------- $ * -----------------'
    # 留神 "$*" 与 $* 的区别,而 "$@" 与 $@ 则无区别
    for k in $* 
        do 
            echo "$k"
        done
[root@peiqi ~]#bash test3.sh 1 2 3
----------------- "$ *" -----------------
1 2 3
----------------- "$ @" -----------------
1
2
3
----------------- $ * -----------------
1
2
3

4、预约义变量

预约义变量 作用
$? 最初一次执行的命令的返回状态。如果这个变量的值为 0,证实上一个命令正确执行;如果这个变量的值为非 0(具体是哪个数,由命令本人来决定),则证实上一个命令执行不正确
$$ 以后过程的过程号(PID)
$! 后盾运行的最初一个过程的过程号(PID)
[root@peiqi ~]#vim test.sh
    #!/bin/bash
    # 输入以后过程的 PID
    # 这个 PID 就是 test.sh 这个脚本执行时,生成的过程的 PID 
    echo "The current process is $$" 
    # 应用 find 命令在 root 目录下查找 helloworld.sh 文件
    # 符号 & 的意思是把命令放入后盾执行
    find /root -name helloworld.sh & 
    echo "The last one Daemon process is $!"
[root@peiqi ~]#bash test.sh 
The current process is 23943
The last one Daemon process is 23944
[root@peiqi ~]#/root/helloworld.sh
接管键盘输入:
read [选项] [变量名] 
选项:-p "提示信息":在期待 read 输出时,输入提示信息 
    -t 秒数:read 命令会始终期待用户输出,应用此选项能够指定等待时间 
    -n 字符数:read 命令只承受指定的字符数,就会执行 
    -s:暗藏输出的数据,实用于机密信息的输出
[root@peiqi ~]# vim read.sh
    #!/bin/bash 
    # 提醒 "请输出姓名" 并期待 30 秒,把用户的输出保留入变量 name 中 
    read -t 30 -p "Please input your name:" name
    # 年龄是隐衷,所以咱们用 "-s" 选项暗藏输出
    read -s -p "Please enter your age:" age
    echo -e "\n"
    # 应用 "-n 1" 选项只接管一个输出字符就会执行(都不必输出回车)read -n 1 -p "Please select your gender[m/f]:" gender
    echo -e "\n"
    echo "Name:$name"
    echo "Age:$age"  
    echo "Gender:$gender"
[root@peiqi ~]# bash read.sh 
Please input your name: pd
Please enter your age: 
Please select your gender[m/f]: m
Name:pd
Age:18
Gender:m

五、Bash 的运算符

1、数值运算与运算符

declare 命令用于申明 shell 变量:
declare [+/-][选项] 变量名 
选项:-:给变量设定类型属性 
    +:勾销变量的类型属性 
    -i:将变量申明为整数型(integer)-x:将变量申明为环境变量 
    -p:显示指定变量的被申明的类型
    
[root@peiqi ~]# declare -i a // 申明整数型变量
[root@peiqi ~]# a=10         // 扭转变量内容
[root@peiqi ~]# echo $a
10

Linux declare 命令

数值运算:

办法 1:

[root@peiqi ~]# a=11
[root@peiqi ~]# b=22
[root@peiqi ~]# declare -i c=$a+$b

办法 2:expr 或 let 数值运算工具

[root@peiqi ~]# a=11
[root@peiqi ~]# b=22
# d 的值是 a 和 b 的和。留神 + 号两侧必须有空格
[root@peiqi ~]# d=$(expr $a + $b)

办法 3:”$((运算式))” 或 “$[运算式]”

[root@peiqi ~]# a=11
[root@peiqi ~]# b=22
[root@peiqi ~]# e=$(($a+$b))
[root@peiqi ~]# f=$[$a+$b]
运算符:
优先级 运算符 阐明
13 -、+ 单目负、单目正
12 !、~ 逻辑非、按位取反或补码
11 *、/、% 乘、除、取模
10 +、- 加、减
9 <<、>> 按位左移、按位右移
8 <=、>=、<、> 小于或等于、大于或等于、小于、大于
7 ==、!= 等于、不等于
6 & 按位与
5 ^ 按位异或
4 \ 按位或
3 && 逻辑与
2 \ \ 逻辑
1 =、+=、-=、*=、/=、%=、&=、^==、<<=、>>= 赋值、运算且赋值
# 尽管乘和除的优先级高于加,然而通过小括号能够调整运算优先级 
[root@peiqi ~]# a=$(((11+3)*3/2 )) 
# 14 不能被 3 整除,余数是 2 
[root@peiqi ~]# b=$((14%3))  
# 逻辑与运算只有相与的两边都是 1,与的后果才是 1,否则与的后果是 0 
[root@peiqi ~]# c=$((1 && 0)) 

2、变量测试与内容替换

变量置换形式 变量 y 没有设置 变量 y 为空值 变量 y 已设置值
x=${y- 新值} x= 新值 x 为空 x=$y
x=${y:- 新值} x= 新值 x= 新值 x=$y
x=${y+ 新值} x 为空 x= 新值 x= 新值
x=${y:+ 新值} x 为空 x 为空 x= 新值
x=${y= 新值} x= 新值、y= 新值 x 为空、y 值不变 x=$y、y 值不变
x=${y:= 新值} x= 新值、y= 新值 x= 新值、y= 新值 x=$y、y 值不变
x=${y? 新值} 新值输入到规范、谬误输入(就是屏幕) x 为空 x=$y
x=${y:? 新值} 新值输入到规范、谬误输入 新值输入到规范、谬误输入 x=$y
[root@peiqi ~]# unset y     # 删除变量 y
[root@peiqi ~]# x=${y-new}  # 进行测试
[root@peiqi ~]# echo $x     # 因为变量 y 不存在,所以 x =new
new
[root@peiqi ~]# y=""        # 给变量 y 赋值为空
[root@peiqi ~]# x=${y-new}    # 进行测试
[root@peiqi ~]# echo $x        # 因为变量 y 为空,所以 x 为空

[root@peiqi ~]# y=old        # 给变量 y 赋值
[root@peiqi ~]# x=${y-new}    # 进行测试
[root@peiqi ~]# echo $x        # 因为变量 y 有值,所以 x =$y
old

六、环境变量配置文件

1、环境变量配置文件简介

source 命令:
[root@peiqi ~]# source 配置文件
或 
[root@peiqi ~]# . 配置文件
环境变量配置文件简介:

环境变量配置文件中次要是定义对系统的操作环境失效的零碎默认环境变量,比方 PATH、HISTSIZE、PS1、HOSTNAME 等默认环境变量。

  • /etc/profile
  • /etc/profile.d/*.sh
  • ~/.bash_profile
  • ~/.bashrc
  • /etc/bashrc

2、环境变量配置文件作用

/etc/profile 的作用:
  • USER 变量
  • LOGNAME 变量
  • MAIL 变量
  • PATH 变量
  • HOSTNAME 变量
  • HISTSIZE 变量
  • umask
  • 调用 /etc/profile.d/*.sh 文件
~/.bash_profile 的作用:
  • 调用了~/.bashrc 文件
  • 在 PATH 变量前面退出了 :$HOME/bin 这个目录
~/.bashrc 的作用:
  • 定义默认别名
  • 调用 /etc/bashrc
/etc/bashrc 的作用:
  • PS1 变量
  • umask
  • PATH 变量
  • 调用 /etc/profile.d/*.sh 文件

3、其余配置文件和登录信息

登记时失效的环境变量配置文件:
  • ~/.bash_logout
其余配置文件:
  • ~/bash_history
Shell 登录信息:
  • 本地终端欢送信息:/etc/issue

    本义符 作用
    d 显示以后零碎日期
    s 显示操作系统名称
    l 显示登录的终端号,这个比拟罕用
    m 显示硬件体系结构,如 i386、i686 等
    n 显示主机名
    o 显示域名
    r 显示内核版本
    t 显示以后零碎工夫
    u 显示以后登录用户的序列号
  • 近程终端欢送信息:/etc/issue.net

    • 本义符在 /etc/issue.net 文件中不能应用
    • 是否显示此欢送信息,由 ssh 的配置文件 /etc/ssh/sshd_config 决定,退出 ”Banner /etc/issue.net” 行能力显示(记得重启 SSH 服务)
  • 登陆后欢送信息:/etc/motd

    • 不论是本地登录,还是近程登录,都能够显示此欢送信息

七、根底正则表达式

1、正则表达式与通配符

  • 正则表达式用来在文件中匹配符合条件的字符串。grep、awk、sed 等命令能够反对正则表达式。
  • 通配符用来匹配符合条件的文件名,通配符是齐全匹配。ls、find、cp 这些命令不反对正则表达式,所以只能应用 shell 本人的通配符来进行匹配了。

2、根底正则表达式

字符 阐明
\ 将下一字符标记为特殊字符、文本、反向援用或八进制本义符。例如,”n” 匹配字符 “n”,”n” 匹配换行符,”\\” 匹配 ”\”,”\(” 匹配 “(“
^ 匹配输出字符串开始的地位。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 “n” 或 “r” 之后的地位匹配
$ 匹配输出字符串结尾的地位。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 “n” 或 “r” 之前的地位匹配
* 零次 屡次 匹配后面的字符或子表达式。例如,”zo*” 匹配 “z” 和 “zoo”。* 等效于 {0,}
{n} n 是非负整数,正好 匹配 n 次。例如,”o{2}” 与 “Bob” 中的 “o” 不匹配,但与 “food” 中的两个 “o” 匹配
{n,} n 是非负整数,至多 匹配 n 次。例如,”o{2,}” 不匹配 “Bob” 中的 “o”,而匹配 “foooood” 中的所有 “o”。”o{1,}” 等效于 “o+”。”o{0,}” 等效于 “o*”
{n,m} Mn 是非负整数,其中 n <= m。匹配至多 n 次,至少 m 次。例如,”o{1,3}” 匹配 “fooooood” 中的头三个 “o”。”o{0,1}” 等效于 “o?”。留神:不能将空格插入逗号和数字之间
. 匹配除 “rn” (即换行符)之外的任何单个字符。若要匹配包含 “rn” 在内的任意字符,请应用诸如 “[sS]” 之类的模式
[xyz] 字符集,匹配蕴含的任一字符。例如,”[abc]” 匹配 “plain” 中的 “a”
1 反向范畴字符,匹配不在指定的范畴内的任何字符。例如,”[^a-z]” 匹配任何不在 “a” 到 “z” 范畴内的任何字符
# 匹配至多蕴含有一个 a 的行 
grep "a*" test_rule.txt
# 匹配起码蕴含两个间断 a 的字符串 
grep "aa*" test_rule.txt  
# "s..d" 会匹配在 s 和 d 这两个字母之间肯定有两个字符的单词 
grep  "s..d" test_rule.txt  
# 匹配在 s 和 d 字母之间有任意字符 
grep "s.*d" test_rule.txt  
# 匹配所有内容
grep ".*" test_rule.txt  
# 匹配以大写 "M" 结尾的行 
grep "^M" test_rule.txt 
# 匹配以小写 "n" 结尾的行
grep "n$" test_rule.txt 
# 会匹配空白行 
grep -n "^$" test_rule.txt 
# 匹配 s 和 i 字母中,要么是 a、要么是 o
grep "s[ao]id" test_rule.txt
# 匹配任意一个数字 
grep "[0-9]" test_rule.txt
# 匹配用小写字母结尾的行
grep "^[a-z]" test_rule.txt
# 匹配不是小写字母结尾的行
grep "^[^a-z]" test_rule
# 匹配不是字母结尾的行 
grep "^[^a-zA-Z]" test
# 匹配应用 . 结尾的行 
grep "\.$" test_rule.txt
# 匹配 a 字母间断呈现三次的字符串
grep "a\{3\}" test_rule.txt 
# 匹配蕴含间断的三个数字的字符串 
grep "[0-9]\{3\}" test_rule.txt
# 匹配起码用间断三个数字结尾的行 
grep "^[0-9]\{3,\}[a-z]" test_rule.txt
# 匹配在字母 s 和字母 i 之间有起码一个 a,最多三个 a 
grep "sa\{1,3\}i" test_rule.txt 

八、字符截取命令

1、cut 字段提取命令

cut [选项] 文件名 
选项:-f 列号:提取第几列 
    -d 分隔符:依照指定分隔符宰割列
vim strudent.txt
    ID Name Gender Mark
    1 peiqi F 86
    2 qiaozhi M 90
    3 pd M 83
[root@peiqi ~]# cut -d " " -f 2 student.txt 
Name
peiqi
qiaozhi
pd
[root@peiqi ~]# cut -d " " -f 3,4 student.txt 
Gender Mark
F 86
M 90
M 83
[root@peiqi ~]# cut -d ":" -f 1,3 /etc/passwd

2、awk 命令

# 行匹配语句 awk '' 只能用单引号
awk [选项参数] 'pattern1{action1}  pattern2{action2} ...' filename
选项参数:-F fs:指定输出文件折分隔符,fs 是一个字符串或者是一个正则表达式,如 -F:
    -v var=value:赋值一个用户定义变量
pattern:示意 awk 在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令
案例实操:
  • 数据筹备

    [root@peiqi ~]# cp /etc/passwd ./
  • 搜寻 passwd 文件以 root 关键字结尾的所有行,并输入该行的第 7 列

    [root@peiqi ~]# awk -F: '/^root/ {print $7}' passwd
  • 搜寻 passwd 文件以 /bin/bash 结尾的所有行,并输入该行的第 1 列和第 7 列,两头以 ” – ” 号宰割

    [root@peiqi ~]# awk -F: '/\/bin\/bash$/ {print $1" - "$7}' passwd 
  • 只显示 /etc/passwd 的第一列和第七列,以制表符宰割,且在所有行后面增加列名 ”user,shell” 在最初一行增加 ”pd,/bin/pd”

    # 留神:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行
    awk -F: 'BEGIN{print"user\tshell"} {print $1"\t"$7} END{print"pd\t/bin/pd"}' passwd
  • 将 passwd 文件中的用户 id 减少数值 1 并输入

    [root@peiqi ~]# awk -v i=1 -F: '{print $3+1}' passwd
awk 的内置变量:
变量 阐明
FILENAME 以后文件名
NR 曾经读出的记录数,就是行号,从 1 开始
NF 一条记录的字段的数目
案例实操:
  • 统计 passwd 文件名,每行的行号,每行的列数

    awk -F: '{print" 文件名:"FILENAME"\t"" 行:" NR  "\t" "列:" NF}' passwd
    文件名:passwd    行:1        列:7
    ...
    ...
    文件名:passwd    行:23    列:7
  • 切割 IP

    [root@peiqi ~]# ifconfig eth0 | grep "inet" | awk -F ""'{print $2}'
    172.17.229.160
  • 查问 test.txt 中空行所在的行号

    [root@peiqi ~]# awk '/^$/ {print NR}' test.txt 
    4
    6
  • 有文件 grade.txt 内容如下:

    张三 40
    李四 50
    王五 60

    求第二列的和并输入

    awk -F ""'{sum+=$2} END{print sum}' grade.txt
  • 关系运算符

    # a.txt
    ID    Name    PHP    Linux    MySQL    Avg
    1   peiqi    82  95      86      87.66 
    2   pd      74  96      87      85.66 
    3   jaz     99  83      93      91.66
    [root@peiqi ~]# cat s.txt | awk '$6>=87.66 {printf $2"\n"}' | grep -v Name
    peiqi
    jaz

3、sed 命令

sed 是一种流编辑器,它一次解决一行内容。解决时,把以后解决的行存储在长期缓冲区中,称为“模式空间”,接着用 sed 命令解决缓冲区中的内容,解决实现后,把缓冲区的内容送往屏幕。接着解决下一行,这样一直反复,直到文件开端。文件内容并没有扭转,除非你应用重定向存储输入。

sed [选项参数] '[action]' filename
# 选项参数:-e:间接在指令列模式上进行 sed 的动作编辑
    -n:个别 sed 命令会把所有数据都输入到屏幕,如果退出此抉择,则只会把通过 sed 命令解决的行输入到屏幕
    -i:用 sed 的批改后果间接批改读取数据的文件,而不是由屏幕输入
# action:a:追加,在以后行后增加一行或多行。增加多行时,除最初一行外,每行开端须要用 \ 代表数据未完结
    c:行替换,用 c 前面的字符串替换原数据行,替换多行时,除最初一行外,每行开端需用 \ 代表数据未完结
    i:插入,在当期行前插入一行或多行。插入多行时,除最初一行外,每行开端须要用 \ 代表数据未完结
    d:删除,删除指定的行
    p:打印,输入指定的行
    s:字串替换,用一个字符串替换另外一个字符串。格局为 "行范畴 s / 旧字串 / 新字串 /g" 
筹备数据:
# grade.txt
ID    Name    PHP    Linux    MySQL    Avg
1   peiqi    82  95      86      87.66 
2   pd      74  96      87      85.66 
3   jaz     99  83      93      91.66
  • 查看文件的第二行

    [root@peiqi ~]# sed -n '2p' grade.txt 
    1   peiqi    82  95      86      87.66 
  • 将 4a 4 alex 88 93 79 86.66 插入到 grade.txt 第 4 行的上面

    sed '4a 4 alex 88 93 79 86.66' grade.txt
  • 删除文件中所有蕴含 peiqi 的行

    sed '/peiqi/d' grade.txt
  • 删除第 2 行到第 4 行的数据,并对内容作出的是真正的删除(-i 参数)

    sed -i '2,4d' grade.txt
  • 在第二行前插入两行数据

    sed '2i hello \
    world' grade.txt
  • 将 grade.txt 文件中的 peiqi 替换为 qiaozhi

    # g 示意 global,全副替换
    sed 's/peiqi/qiaozhi/g' grade.txt
  • 同时将 grade.txt 文件中的 peiqi 和 jaz 替换为空

    sed 's/peiqi//g;s/jaz//g' grade.txt

九、字符解决命令

1、排序命令 sort

sort [选项] 文件名
# 选项:-f:疏忽大小写 
    -n:以数值型进行排序,默认应用字符串型排序 
    -r:反向排序 
    -t:指定分隔符,默认是分隔符是制表符 
    -k n[,m]:依照指定的字段范畴排序。从第 n 字段开始,m 字段完结(默认到行尾)
筹备数据:
[root@peiqi ~]# vim sort.txt
    bb:40:5.4
    bd:20:4.2
    xz:50:2.3
    cl:10:3.5
    ss:30:1.6
  • 依照 : 宰割后的第三列倒序排序

    [root@peiqi ~]# sort -t : -nr -k 3 sort.txt
    bb:40:5.4
    bd:20:4.2
    cl:10:3.5
    xz:50:2.3
    ss:30:1.6

2、统计命令 wc

利用 wc 指令能够计算文件的 Byte 数、字数、或是列数,若不指定文件名称、或是所给予的文件名为 ”-“,则 wc 指令会从规范输出设施读取数据。

wc [选项] 文件名
# 选项:-l:只统计行数 
    -w:只统计单词数 
    -m:只统计字符数
[root@peiqi ~]# wc -l -w -m sort.txt 
 5  5 50 sort.txt

十、条件判断

1、两个判断格局

[root@peiqi ~]# test -e /etc/passwd
[root@peiqi ~]# echo $?
0
[root@peiqi ~]# [-e /etc/passwd]
[root@peiqi ~]# echo $?
0
# 第一个命令如果正确执行,则打印 yes,否则打印 no
[root@peiqi ~]# [-e /etc/pwd] && echo "yes" || echo "no"
no

2、依照文件类型进行判断

测试选项 作用
-b 文件 判断该文件是否存在,并且是否为 == 块设施 == 文件
-c 文件 判断该文件是否存在,并且是否为 == 字符设施 == 文件
-d 文件 判断该文件是否存在,并且是否为 == 目录 == 文件
-e 文件 判断该文件是否存在
-f 文件 判断该文件是否存在,并且是否为 == 一般 == 文件
-L 文件 判断该文件是否存在,并且是否为 == 符号链接 == 文件
-p 文件 判断该文件是否存在,并且是否为 == 管道 == 文件
-s 文件 判断该文件是否存在,并且是否为 == 管道 == 文件
-S 文件 判断该文件是否存在,并且是否为 == 套接字 == 文件

3、依照文件权限进行判断

测试选项 作用
-r 文件 判断该文件是否存在,并且该文件是否领有 == 读权限 ==
-w 文件 判断该文件是否存在,并且该文件是否领有 == 写权限 ==
-x 文件 判断该文件是否存在,并且该文件是否领有 == 执行权限 ==
-u 文件 判断该文件是否存在,并且该文件是否领有 SUID 权限
-g 文件 判断该文件是否存在,并且该文件是否领有 SGID 权限
-k 文件 判断该文件是否存在,并且该文件是否领有 SBit 权限

4、两个文件之间进行比拟

测试选项 作用
文件 1 -nt 文件 2 判断文件 1 的批改工夫是否比文件 2 的新
文件 1 -ot 文件 2 判断文件 1 的批改工夫是否比文件 2 的旧
文件 1 -ef 文件 2 判断文件 1 是否和文件 2 的 Inode 号统一,能够了解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的办法

5、两个整数之间比拟

测试选项 作用
整数 1 -eq 整数 2 判断整数 1 是否和整数 2 相等
整数 1 -nq 整数 2 判断整数 1 是否和整数 2 不相等
整数 1 -gt 整数 2 判断整数 1 是否大于整数 2
整数 1 -lt 整数 2 判断整数 1 是否小于整数 2
整数 1 -ge 整数 2 判断整数 1 是否大于等于整数 2
整数 1 -le 整数 2 判断整数 1 是否小于等于整数 2

6、字符串的判断

测试选项 作用
-z 字符串 判断字符串是否为空
-n 字符串 判断字符串是否为非空
字符串 1 == 字符串 2 判断字符串 1 是否和字符串 2 相等
字符串 1 != 字符串 2 判断字符串 1 是否和字符串 2 不相等

7、多重条件判断

测试选项 作用
判断 1 -a 判断 2 逻辑与,判断 1 和判断 2 都成立,最终的后果才为真
判断 1 -o 判断 2 逻辑或,判断 1 和判断 2 有一个成立,最终的后果就为真
! 判断 逻辑非,使原始的判断式取反

十一、流程管制

1、if 语句

单分支 if 条件语句:
if [条件判断式];then 
    程序 
fi 
# 或者 
if [条件判断式] 
then 
    程序 
fi

单分支条件语句须要留神几个点:

  • if 语句应用 fi 结尾,和个别语言应用大括号结尾不同
  • [条件判断式]就是应用 test 命令判断,所以中括号和条件判断式之间必须有空格
  • then 前面跟符合条件之后执行的程序,能够放在 [] 之后,用 ; 宰割。也能够换行写入,就不须要 ; 了
#!/bin/bash 
# 统计根分区使用率 
# 把根分区使用率作为变量值赋予变量 rate 
rate=$(df -h | grep "/dev/vda1" | awk '{print $5}' | cut -d "%" -f 1) 
if [$rate -ge 80];then 
    echo "Warning! /dev/vda1 is full of!" 
fi
双分支 if 条件语句:
if [条件判断式];then 
    条件成立时,执行的程序 
else 
    条件不成立时,执行的另一个程序 
fi

示例 1:备份 mysql 数据库

#!/bin/bash 
# 备份 mysql 数据库

# 同步零碎工夫 
ntpdate asia.pool.ntp.org &>/dev/null
# 把以后零碎工夫依照 "年月日" 格局赋予变量 date 
date=$(date +%Y%m%d) 
# 统计 mysql 数据库的大小,并把大小赋予 size 变量 
size=$(du -sh /var/lib/mysql) 

if [-d /tmp/dbbak];then 
    echo "Date: $date!" > /tmp/dbbak/dbinfo.txt 
    echo "Data size: $size" >> /tmp/dbbak/dbinfo.txt 
    cd /tmp/dbbak 
    tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null 
    rm -rf /tmp/dbbak/dbinfo.txt 
else 
    mkdir /tmp/dbbak 
    echo "Date: $date!" > /tmp/dbbak/dbinfo.txt 
    echo "Data size: $size" >> /tmp/dbbak/dbinfo.txt 
    cd /tmp/dbbak 
    tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null 
     rm -rf /tmp/dbbak/dbinfo.txt
fi

示例 2:判断 mysql 是否启动

#!/bin/bash
port=$(netstat -anp | grep mysql | grep tcp6 | awk '{print $4}' | cut -d ":" -f 4) 
if ["$port" == 3306];then 
    echo "mysql is running..."
else 
    service mysqld start
    echo "mysql is starting..." 
fi
多分支 if 条件语句:
if [条件判断式 1];then 
    当条件判断式 1 成立时,执行程序 1 
elif [条件判断式 2];then 
    当条件判断式 2 成立时,执行程序 2
else 
    当所有条件都不成立时,最初执行此程序 
fi

2、case 语句

case 语句和 if…elif…else 语句一样都是多分支条件语句,不过和 if 多分支条件语句不同的是,case 语句只能判断一种条件关系,而 if 语句能够判断多种条件关系。

case $ 变量名 in 
"值 1")如果变量的值等于值 1,则执行程序 1 
;; 
"值 2")如果变量的值等于值 2,则执行程序 2 
;;  
*)如果变量的值都不是以上的值,则执行此程序 
;; 
esac

3、for 循环

语法一:
for 变量 in 值 1 值 2 值 3… 
    do 
        程序 
    done

示例 1:打印工夫

#!/bin/bash
for time in morning noon afternoon evening 
    do 
        echo "This time is $time!" 
    done 

示例 2:批量解压缩脚本

#!/bin/bash
cd /opt 
ls *.tar.gz > tar.log 
for i in $(cat tar.log) 
    do 
        tar -zxf $i -C /test &>/dev/null 
    done 
rm -rf /opt/tar.log
语法二:
for ((初始值; 循环管制条件; 变量变动)) 
    do 
        程序 
    done 

示例:从 1 加到 100

#!/bin/bash
total=0 
for ((i=1;i<=100;i=i+1)) 
    do 
        total=$(($total+$i)) 
    done 
echo "The sum of 1+2+...+100 is: $total"

4、while 循环与 until 循环

while 循环:

while 循环是不定循环,也称作条件循环。只有条件判断式成立,循环就会始终持续,直到条件判断式不成立,循环才会进行。这就和 for 的固定循环不太一样了。

while [条件判断式] 
    do 
        程序 
    done

示例:从 1 加到 100

#!/bin/bash
i=1 
total=0
while [$i -le 100] 
    do 
        total=$(($total+$i)) 
        i=$(($i+1)) 
    done 
echo "The sum of 1+2+...+100 is: $total"
until 循环:

until 循环,和 while 循环相同,until 循环时只有条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。

until [条件判断式] 
    do 
        程序 
    done 

示例:从 1 加到 100

#!/bin/bash
i=1 
total=0
# 循环直到变量 i 的值大于 100,就进行循环 
until [$i -gt 100] 
    do 
        total=$(($total+$i)) 
        i=$(($i+1)) 
    done 
echo "The sum of 1+2+...+100 is: $total"

  1. a-z
退出移动版