DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • 计算机基础

  • linux基础

    • 准备工作
    • 初识shell与基础常用命令
    • 文件管理之基础命令
    • 文件管理之四大模式
    • 文件管理之命令补充
    • 文件管理之文件系统
    • 权限管理之用户与组
    • 权限管理之文件权限
    • 权限管理之ACL
    • 权限管理之su与sudo
    • 软件包管理之rpm
    • 软件包管理之yum
    • 查看进程
    • 管理进程
    • 存储管理之传统磁盘管理
    • 存储管理之LVM
    • 网络管理
    • shell基础
      • shell介绍
        • 计算机体系架构
        • shell脚本运行步骤
      • 变量
      • 变量作用域
        • 全局变量
        • export
      • 元字符
        • $[ ]、$(( ))
        • 其他元字符
        • 条件测试
      • 流程控制
        • if判断
        • while循环
        • for循环
      • 练习
    • crond计划任务
    • 系统优化
  • mysql

  • git

  • 数据结构与算法

  • axure

  • english

  • docker

  • IT_Need
  • linux基础
DC
2022-10-20
目录

shell基础

# shell介绍

shell是一门动态、弱类型、解释型的语言

# 计算机体系架构

命令
shell解释器(进一步封装成命令)
系统调用接口(是对OS内核的封装)
OS内核
硬件
1
2
3
4
5

# shell脚本运行步骤

前提: 当前用户需要对脚本文件拥有r和x权限
执行的两种方式: 
    在a.sh文件所在目录下 --  `bash a.sh` 
    任一目录下 --  `/root/a.sh`

现在用的shell解释器都是Bash,一个shell脚本运行的三个步骤: 
  1> 先启动bash解释器
  2> bash解释器会把a.sh的内容从硬盘读入内存
  3> bash解释器后识别刚刚读入内存中的内容,并逐行解释执行shell代码.
  Ps: 像同为解释型语言的python,底层并发的特性、字符编码的问题都与这三个步骤有关.
1
2
3
4
5
6
7
8
9
10

# 变量

定义变量:     height=172
访问变量:     echo $height echo ${height} (推荐)
修改变量:     height=180

删除变量:     unset height

变量值的类型: 整型、浮点型、字符串 用来写shell脚本,这三儿就够用了..

引号对变量的影响
     双引号、单引号: 都可用于定义字符串类型的变量.. 在python里没区别,在shell里单引号定义的叫做硬引用..
硬引用是指将引号包裹的特殊字符都当作是普通字符.. x="\$123" 等同于 y='$123'
     反引号: 取某条命令的运行结果 touch `date "+%F"`.txt 等同于 touch $(date "+%F").txt
反引号不能嵌套, $()可以...

系统变量:
        PS1 指的就是[root@localhost ~]
        HOSTNAME 内置主机名的名字
        USER 当前登录的用户名
        ... ... ...

"""
shell里定义变量,赋值符号“=”两边不能有空格;python建议有空格Hhh 
"""
[root@localhost ~]# height=172		## -- 定义
[root@localhost ~]# echo $height	## -- 访问/取值
172
[root@localhost ~]# height=180		## -- 修改
[root@localhost ~]# echo $height
180
[root@localhost ~]# echo ${height}cm		## -- 建议用{}将要访问的变量包裹起来
180cm

[root@localhost ~]# touch `date "+%F"`.txt
[root@localhost ~]# ll 2022-08-29.txt 
-rw-r--r-- 1 root root 0 8月  29 20:55 2022-08-29.txt

[root@localhost ~]# touch $(date "+%F").bak
[root@localhost ~]# ll 2022-08-29.bak 
-rw-r--r-- 1 root root 0 8月  29 20:57 2022-08-29.bak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 变量作用域

变量作用域即变量的生效范围

# 全局变量

全局变量只在当前shell进程(不包含该进程的子进程)里生效!!!

[root@localhost ~]# x=1000
[root@localhost ~]# echo $x
1000
[root@localhost ~]# echo $y					## -- bash进程中一开始是没有变量y的存在的

[root@localhost ~]# vim b.sh
[root@localhost ~]# cat b.sh
echo $x
y = 10000
[root@localhost ~]# bash b.sh 		  ## -- 起了个新的bash进程,文件里面的代码在新终端里运行

[root@localhost ~]# chmod u+x b.sh 
[root@localhost ~]# ./b.sh					## -- 开起了一个子shell进程,在新的进程里执行的

[root@localhost ~]# source b.sh     ## -- source相当于将文件中的两行代码拿出来在当前终端运行
1000
[root@localhost ~]# echo $y					## -- so,可以访问到y的值
10000
[root@localhost ~]# bash						## -- 进入一个新终端
[root@localhost ~]# echo $y

[root@localhost ~]# exit
exit
[root@localhost ~]# echo $y
10000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# export

通过export 变量 ,可以将此变量继承到子子孙孙...
跟 9_权限管理之su与sudo.md中 配置文件的妙用 那部分的知识点可以呼应起来..

"""
x变量
第一层 111
第二层 222
第三层 333
  有就用自己的,没有则继承最近的父类的x值;
  exit退出本层到上一层,查看x变量的值,也是以本层有没有,没有再往上层看的逻辑查看..
  不会说,第三层的x值变为333,第一层第二层的值都变为了333..
"""
[root@localhost ~]# x=111
[root@localhost ~]# export x
[root@localhost ~]# bash
[root@localhost ~]# echo $x
111
[root@localhost ~]# x=222
[root@localhost ~]# bash
[root@localhost ~]# echo $x
222
[root@localhost ~]# x=333
[root@localhost ~]# exit
exit
[root@localhost ~]# echo $x
222
[root@localhost ~]# exit
exit
[root@localhost ~]# echo $x
111
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 元字符

# 、[]、(( ))

$[ ] 等同于 $(( )) 只支持整数的加减乘除取余+-*/%运算,不能做浮点数的

x=10
y=20
z=$[ $x + $y ]		z=$(( $x + $y )) 
z=$[ $x / $y ] 		z=$(( $x + $y ))		## -- 值为0
z=$[ 10 + 20 ]		z=$(( 10 + 20 ))		## -- 可以直接写值
1
2
3
4
5

bc软件包

"""
浮点数的运算需要借助bc软件包
yum install bc -y
"""
## -- scale指定保留几位小数 不会四舍五入
[root@localhost ~]# echo "scale=2;10/3"|bc
3.33
## -- 有个弊端,.33在做运算时,不会识别成0.33
[root@localhost ~]# res=`echo "scale=2;1/3"|bc`
[root@localhost ~]# echo $res
.33
[root@localhost ~]# echo $[ $res * 100 ]
-bash: .33 * 100 : 语法错误: 期待操作数 (错误符号是 ".33 * 100 ")
## -- 解决: 借助cut做分割处理
## echo $(echo "scale=2;1/3"|bc|cut -d. -f2)%
[root@localhost ~]# echo `echo "scale=2;1/3"|bc|cut -d. -f2`%
33%
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

练习:计算内存的可用率(百分比)

[root@localhost ~]# free
              total        used        free      shared  buff/cache   available
Mem:         995640      169672      522184        8192      303784      676212
Swap:       2097148           0     2097148
# awk默认空格分割,NR指定第2行
[root@localhost ~]# avail=$(free | awk 'NR==2{print $7}')
[root@localhost ~]# total=$(free | awk 'NR==2{print $2}')
[root@localhost ~]# echo $avail $total
675564 995640
[root@localhost ~]# per=`echo "scale=2;$avail/$total"|bc|cut -d. -f2`
[root@localhost ~]# echo ${per}%
67%
1
2
3
4
5
6
7
8
9
10
11
12

# 其他元字符

sed、grep、awk文件处理三剑客这三个命令工具是支持正则表达式的使用的!!
其余的命令暂且只能使用元字符!

元字符 含义
~ 家目录
`` 取命令运行结果,不可嵌套
$() 取命令运行结果,可以嵌套
$(()) 或者 $[] 里面可以做整数运算
${} 界定边界,包含
touch {1..6}{d,e,f}.txt 6*3=18种可能
$? 上一条命令是否运行成功,值为0成功,非0失败..
() 括号里写命令,代表在子shell中提交任务
? 代表任意一个字符,不能指定 ll /test/?.txt
[] 取其中任一一个字符
也可以做测试用(结合$?使用), test命令
! 或者 ^ 取反,在[]号里使用
- 代表范围
& 放在命令末尾意味着命令后台运行;
&& 并且 类似于and 同真为真(找错的 遇错则停)
|| 或者 类似于or 有真为真(找对的 遇对则停)
; 从左到右依次执行,哪怕中途失败,后面的照常运行
* 代表所有
= 赋值
== 判断值是否相等
\ 转义
: 这也是个命令,跟true一样 运行结果永远为真
[!12][^21].txt      ## -- 文件名由两个字符组成,第一个字符不是1和2,第二个字符不是2和1,并以.txt结尾的文件
[0-9a-z].txt        ## -- 0-9,a-z中任一字符
echooo 123 && pwd   ## &&左边命令出错,&&右边命令是不会运行的
echooo 123 || pwd   ## ||左边命令失败,&&右边命令是会运行的

[root@localhost ~]# :
[root@localhost ~]# echo $?
0
[root@localhost ~]# true
[root@localhost ~]# echo $?
0
1
2
3
4
5
6
7
8
9
10
11

# 条件测试

▲ 字符串的判断
## -- [ "egon" = "123" ] 注意:错了也不会有提示信息的	
[root@localhost ~]# name="egon"
[root@localhost ~]# [ $name = "egon111" ]			## -- 记得里面的空格
[root@localhost ~]# echo $?										## -- $?表明上一条命令是否运行成功	0为成功,非0失败
1
[root@localhost ~]# [ $name = "egon" ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ $name != "egon111" ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ "aa" != "aa" ] && echo "ok" || echo "no"
no
[root@localhost ~]# [ "aa" = "aa" ] && echo "ok" || echo "no"
ok


▲ 数字的判断 
  -eq 等于
  -gt 大于>
  -ge	大于等于>=
  -lt	小于
  -le	小于等于 
  -ne 不等于
[root@localhost ~]# [ 3 -lt 5 ]
[root@localhost ~]# echo $?
0

▲ 文件的判断 
  -f 存在并且得是个标准文件
	-e 文件存在,不管类型
	
[root@localhost ~]# [ -f /root/a.sh ]
[root@localhost ~]# echo $?
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

练习:登录脚本

[root@localhost ~]# vim login.sh
[root@localhost ~]# cat login.sh
#!/bin/bash

read -p "请输入您的用户名:" username
read -p "请输入您的密码:" password

## -- 对 && 运行  ;  错 && 不运行  ;  对 || 不运行  ;  错 || 运行		
[ $username = "egon" ] && [ $password = 123 ] && echo "认证成功"  || echo "认证失败"
[root@localhost ~]# bash login.sh 
请输入您的用户名:egon
请输入您的密码:123
认证成功
[root@localhost ~]# bash login.sh 
请输入您的用户名:dc
请输入您的密码:123
认证失败
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 流程控制

# if判断

命令1
命令2
if 条件1;then
     代码 elif 条件2;then
     代码 elif 条件3;then
     代码
else
     代码
fi
命令3

[root@localhost ~]# vim if1.sh
[root@localhost ~]# cat if1.sh
#!/bin/bash


# -- 单分支
if [ 10 -gt 3 ];then
    echo "10>3? yes"
fi

# -- 双分支
if [ 3 -gt 10 ];then
    echo "ok"
else
    echo "3>10? no"
fi

# -- 多分支
read -p "请输入您的成绩: " score

if [ $score -ge 90 ];then
    echo "优秀"
# -- 可以优化判断条件 能走到这一步 score值肯定是小于90的 elif [ $score -ge 80 ];then 
elif [ $score -ge 80 ] && [ $score -lt 90 ];then
    echo "良好"
elif [ $score -ge 70 ] && [ $score -lt 80 ];then
    echo "一般"
else
    echo "很差"
fi  
[root@localhost ~]# bash if1.sh 
10>3? yes
3>10? no
请输入您的成绩: 76  
一般
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# while循环

[root@localhost ~]# vim while.sh 
[root@localhost ~]# bash while.sh 
请输入您的用户名:dc
请输入您的密码:123456
认证失败
请输入您的用户名:egon
请输入您的密码:123
认证成功
[root@localhost ~]# cat while.sh 
#!/bin/bash

while true
do
    read -p "请输入您的用户名:" username
    read -p "请输入您的密码:" password
    
    if [ $username = "egon" ] && [ $password = 123 ];then
        echo "认证成功"
	break
    else
        echo "认证失败"
    fi
done


[root@localhost ~]# vim while2.sh
[root@localhost ~]# bash while2.sh
0
1
2
[root@localhost ~]# cat while2.sh
#!/bin/bash

count=0

while [ $count -lt 3 ];do
    echo $count
    ## -- 等同于 count = $[ $count + 1 ]
    ((count++))
done
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

Ps: shell脚本的缩进 control +v 上下选择缩进行 shift+i 四个空格先缩进第一行 两下esc实现选择的行全部缩进..

# for循环

[root@localhost ~]# seq 1 3
1
2
3

[root@localhost ~]# vim for.sh
[root@localhost ~]# cat for.sh
#!/bin/bash

# -- 以空格为分隔符,依次读1 2 3 4 5赋值给变量i
# -- 等同于 for i in `seq 1 5`
# -- 等同于 for i in {1..5}
for i in 1 2 3 4 5
do
    # -- 当i的值为4时,通过break跳出循环
    if [ $i -eq 4 ];then
        break
    fi
    echo $i
done


for i in `ls /root | grep .sh`
do
    echo $i
done
[root@localhost ~]# bash for.sh
1
2
3
for.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 练习

案例1: 创建check_network.sh检测是否能连通某个IP

"""
#!/bin/bash

ping -c 5  www.baidu.com &> /dev/null

if [ $? -eq 0 ];then
    echo "network ok"
else
    echo "network error"
fi
"""

[root@localhost ~]# vim check_network.sh
[root@localhost ~]# bash check_network.sh
network ok
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

案例2: 检测同网段哪些IP能ping通(并发)

#!/bin/bash

for i in {3..254}
do 
    # -- 此方案,一条条的检测太慢了!!!
    # ping -c 1 172.16.150.$i &> /dev/null
    # if [ $? -eq 0 ];then
    #    echo "172.16.150.$i up" # -- 注意,若用单引号,$就没有取值之意啦
    # else
    #    echo "172.16.150.$i down"
    # fi

    # -- 瞬间200多条ping命令全部提交到后台,实现并发运行
    # -- 等同于 ping -c 1 172.16.150.$i &> /dev/null && echo "172.16.150.$i up" >> /tmp/ip.log || echo "172.16.150.$i down" >> /tmp/ip.log &
    
    (ping -c 1 172.16.150.$i &> /dev/null
    if [ $? -eq 0 ];then
       echo "172.16.150.$i up" >> /tmp/ip.log
    else
       echo "172.16.150.$i down" >> /tmp/ip.log
    fi) &

done
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

网络管理
crond计划任务

← 网络管理 crond计划任务→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式