shell

因为上一次没有学好现在进行重新学习;{基础部分}

Shell


编程基础

linus: Talk is cheap,show me the code

1.1 程序组成

程序: 算法+数据结构
数据: 是程序的核心
算法: 处理数据的方式
数据结构: 数据在计算机中的类型和组织方式

1.2 程序编程风格
  • 面向过程语言

    • 做一件事情,排出个步骤,第一步干什么,第而不干什么,如果出现情况A,做什么处理,如果出现了情况B,做什么处理
    • 问题规模小,可以步骤化,按部就班处理
    • 以指令为中心,数据服务于指令
    • C,shell
  • 面向对象语言

    • 一种认识世界、分析世界的方法论。将万事万物抽象为各种对象
    • 类是抽象的概念,是万事万物的抽象,是一类事务的共同的特征的集合
    • 对象是类的具象,是一个实体
    • 问题规模大,复杂系统
    • 以数据为中心,指令服务于数据
    • java,c#,python,golang等
1.3编程语言

计算机:运行二进制指令
编程语言:人与计算机之间交互的语言。分为两种:低级语言和高级语言

  • 低级编程语言

    机器:二进制的0和1的序列,称为机器指令。与自然语言差异太大,难懂,难写

    汇编:用一些助记符号和替代机器指令,称为汇编语言

    ​ 如:ADD A,B 将寄存器A的数与寄存器B的数相加得到的数放到 寄存器A中
    汇编语言写好的程序需要汇编程序转换成机器指令
    汇编语言稍微好理解,即机器指令对应的助记符,助记符更接近自然语言

  • 高级编程语言:

    编译:高级语言——>编译器——>机器代码文件——>执行,如:C,C++

    解释:高级语言——>执行——>解释器——>机器代码,如:shell,python,php,javaScript,perl

三种逻辑
  • 顺序执行
  • 选择执行
  • 循环执行

2 shell脚本语言的基本构造

2.1shell脚本的用途
  • 自动化常用命令
  • 执行系统管理和故障排除
  • 创建简单的应用程序
  • 处理文本或文件
2.2 shell脚本基本构造

shell脚本编程:是基于过程式,解释执行的语言
编程语言的基本结构:

  • 各种系统命令的组合
  • 数据存储:变量、数组
  • 表达式:a+b
  • 控制语句:if

shell脚本:包含一些命令或声明,并符合一定格式的文本文件

格式要求:首行shebang机制

#!/bin/bash
#!/usr/bin/python
#!/usr/bin/per1
2.3 创建shell脚本过程

第一步:使用文本编辑器来创建文本文件
第一行必须包括shell声明序列: #!
示例:

#!/bin/bash

添加注释,注释以#开头
第二步:加执行权限

给与执行权限,在命令行上指定脚本的绝对或相对路径

第三步:运行脚本

直接运行解释器,将脚本作为解释器程序的参数运行

2.4 脚本注释规范
  1. 第一行一般为调用使用的语言
  2. 程序名,避免更改文件名为无法找到正确的文件
  3. 版本号
  4. 更改后的时间
  5. 作者相关信息
  6. 该程序的作用,及注意事项
  7. 最后是各版本的更新简要说明
2.5 第一个脚本
#!/bin/bash
#
#****************************************************
#Author:		ZhangGuoqing
#QQ:			2627029286
#Date:			2021-09-08
#FileName:		hello.sh
#URL:			https://blog.csdn.net/weixin_47613673?spm=1000.2115.3001.5343
#Description:		The test script
#Copyright (C):	2021 All rights reserved
#**************************************************
echo  "hello world"

范例:备份脚本

#!/bin/bash
#
#****************************************************
#Author:		ZhangGuoqing
#QQ:			2627029286
#Date:			2021-09-08
#FileName:		backups.sh
#URL:			https://blog.csdn.net/weixin_47613673?spm=1000.2115.3001.5343
#Description:		The test script
#Copyright (C):	2021 All rights reserved
#**************************************************
echo  -e  "\033[1;32mStarting backup...\033[0m"
sleep 2
cp -av  /etc/  /data/etc`date +%F`/
echo  -e  "\033[1;32mBackup  is finished\033[0m"
2.6 脚本调试

cat -A 查看语法
进入 vim 编辑器 set list 也可以查看语法
脚本错误常见的有三种

  • 语法错误:语法出错会导致 语法后的行将不会执行 bash -n 检查错误
  • 命令错误: 后面的命令还会继续执行,bash -n 无法检查出来,可以使用bash -x 进行检查
  • 逻辑错误:只能用bash -x 进行观察
2.7变量
2.7.1 变量

变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据

2.7.2 变量类型

变量类型:

  • 内置变量,如:PS1,PATH,HISTSIZE
[root@mikeaq ~]#echo  $UID
0
[root@mikeaq ~]#echo  $HOSTNAME
mikeaq
[root@mikeaq ~]#echo  $PPID
21423
[root@mikeaq ~]#echo  $BASHPID
21427
[root@mikeaq ~]#echo  $$
21427
  • 用户自定义变量

不同的变量存在在的数据不同,决定了一下

​ 1.数据存储方式
​ 2.参与的运算
​ 3.表示的数据范围
变量数据类型:

  • 字符
  • 数值:整型、浮点型、bash不支持浮点数

2.7.3 编程语言分类

静态和动态语言

  • 静态编译语言:使用变量前,先声明变量类型,之后类型不能改变,在编译时检查如:java 、c
  • 动态编译语言:不用事先声明,可随时改变类型,如:bash,Python

强类型和弱类型

  • 强类型语言:不同类型数据操作,必须经过强制转化才同一类型才能运算,如 java、c#、Python
  • 弱类型语言:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型:参与运算会自动进行隐式类型转换;变量无需事先定义可直接调用
2.7.4 Shell中变量命名法则
  • 不能使程序中的保留字:如 if for
  • 只能使用数字、字母及下划线、且不能以数字开头、注意:不支持短横线"-"
  • 见名知义,用英文名字,并体现出实际作用
  • 统一命令规则:驼峰命名法,studentname,大驼峰StudentName小驼峰studentName
  • 变量名大写
  • 局部变量小写
  • 函数名小写
2.7.5 变量定义和引用

变量的生效范围等标准划分变量类型

  • 普通变量:生效范围为当前shell进程:对当前的shell之外的其他shell进程,包括当前shell的子shell进程均无效
  • 环境变量:生效范围为当前shell进程及其子进程
  • 本地变量:生效范围为当前shell进程中某代码片段,通常指函数

变量赋值

name='value'

value可以是以下多种形式

直接字串:name='root'
变量引用:name='$USER'
命令引用:name=`COMMAND`  或者  name=$(COMMAND)
[root@mikeaq ~]#whoami
root
[root@mikeaq ~]#USER=`whoami`
[root@mikeaq ~]#echo  $USER
root

注意:变量赋值是临时生效,当退出终端后,将会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除

变量引用

$name
${name}

强引用和弱引用

  • “$name” 弱引用,其中的变量引用会被替换为变量值
  • ‘$name’ 强引用,其中的变量引用不会被替换为变量值,而保持元字符串
[root@mikeaq ~]#name=zhang
[root@mikeaq ~]#TITLE=$name
[root@mikeaq ~]#echo  $name
zhang
[root@mikeaq ~]#echo  $TITLE
zhang
[root@mikeaq ~]#name=guo
[root@mikeaq ~]#echo  $name
guo
[root@mikeaq ~]#echo  $TITLE
zhang
[root@mikeaq ~]#NUM=`seq 10`
[root@mikeaq ~]#echo  $NUM
1 2 3 4 5 6 7 8 9 10
[root@mikeaq ~]#seq 10
1
2
3
4
5
6
7
8
9
10
[root@mikeaq ~]#echo  "$NUM"
1
2
3
4
5
6
7
8
9
10

显示已定义的所有变量:

set

删除变量:

unset  name
2.7.6环境变量

环境变量:可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使使用子进程的变量,一旦子修改从父进程继承的变量,将会新的值传递给孙子进程

变量声明和赋值

export   name=VALUE
declare  -x  name=VALUE
#或者分两步实现
name=VLAUE
export name

变量引用:

$name
${name}

显示所有环境变量

env
printenv
export
declate  -x

删除变量

unset  name

bash内建的环境变量

PATH
SHELL
USER
UID
HOME
PWD
SHLVL  #shell的嵌套层数,即深度
LANG
MAIL
HOSTNAME
HISTSIZE
_  下划线  表示前一命令的最后一个参数
2.7.7 只读变量

只读变量:只能声明定义,但后续不能修改和删除
声明只读变量

readonly  ame
declare  -r  name

查看只读变量

readonly  [-p]
delare  -r
2.7.8位置变量

位置变量:在bash shell中内置的变量,在脚本代码中调用通过命令行传递给脚本的参数

$1,$2...对应第1个,第二个等参数,shift[n]换位置
$0  命令本身,包括路劲
$*  传递给脚本的所有参数,全部参数合为一个字符串
$@  传递给脚本的所有参数,每个参数为独立字符串
$#  传递给脚本的参数的个数
注意:$@ $*只在被双引号包起来的时候才会有差异

清空所有位置变量

set --

[root@mikeaq ~]#/data/arg.sh  {a..z}
1st  atg  is  a
2st  atg  is  b
3st  atg  is  c
10st   atg   is  j
The   number  of agr  is  26
All  args  are  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
All  args  are  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
The  scriptname  os  arg.sh
[root@mikeaq ~]#cat  /data/arg.sh 
#!/bin/bash
#
#****************************************************
#Author:		ZhangGuoqing
#QQ:			2627029286
#Date:			2021-09-12
#FileName:		arg.sh
#URL:			https://blog.csdn.net/weixin_47613673?spm=1000.2115.3001.5343
#Description:		The test script
#Copyright (C):	2021 All rights reserved
#**************************************************
echo   "1st  atg  is  $1"
echo   "2st  atg  is  $2" 
echo   "3st  atg  is  $3" 
echo  "10st   atg   is  ${10}"
echo  "The   number  of agr  is  $#"
echo  "All  args  are  $*"
echo  "All  args  are  $@"
echo  "The  scriptname  os  `basename $0`"

范例:

[root@mikeaq data]#cat rm.sh 
#!/bin/bash
#
#****************************************************
#Author:		ZhangGuoqing
#QQ:			2627029286
#Date:			2021-09-12
#FileName:		rm.sh
#URL:			https://blog.csdn.net/weixin_47613673?spm=1000.2115.3001.5343
#Description:		The test script
#Copyright (C):	2021 All rights reserved
#**************************************************
WRING="echo  -e  \E[1;31m"
END="\E[0m"
DIR=/opt/`date +%F_%H-%M-%S`
mv  $*  $DIR
${WRING}  Move   $*  to  $DIR  $END
2.7.9 退出状态码变量

进程执行后,将使用变量 ? 保 存 状 态 码 的 相 关 数 字 , 不 同 的 值 反 应 成 功 或 失 败 , ?保存状态码的相关数字,不同的值反应成功或失败, ??取值范例0-255

$?的值为0 			 代表成功
$?的值是1到255	    代表失败

范例

ping  -c1  www.baidu.com  &> /dev/null
echo  $?

用户可以在脚本中使用以下命令自定义退出状态码

exit [n]

注意:

  • 脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
  • 如果未给脚本指定退出状态码,整个脚本退出状态码取决于脚本中执行的最后一条命令的状态码
2.7.10

展开命令执行顺序

把命令行分为单个命令词
展开别名
展开大括号的声明{}
展开波浪符声明  ~
命令替换$()和 ``
再次把命令行分成命令词
展开文件通配(*、?、[abc]等等)
准备I/O重导向(<、>)
运行命令

防止扩展

反斜线(\)会使随后的字符按愿意解释

范例

echo  Your cost:\$5.00
Your cost:$5.00

加引号来防止扩展

单引号('')防止所有扩展
双引号("")也可防止扩展,但是以下情况例外:$(美元符号)

变量扩展

`` :反引号、命令替换
\:反斜线,禁止单个字符扩展
!:叹号,历史命令替换
2.7.11 脚本安全和set

set命令:可以用来定制shell
$-变量

h: hashall,打开选项后,Shell会将命令所在的路劲hash下来,避免每次都要查询,通过set+h将h选项关闭

i: interactive-comments,包含这个选项说明当前的shell是一个交互式的shell。所谓的交互式shell,在脚本中.i选项使关闭的

m: monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续、后台或者前台执行等

B:braceexpand 大括号扩展
H: history,H选项打开,可以扩展历史列表中的命令,可以通过!感叹号来完成,例如"!!“返回上最近的一个历史命令,”!n"返回第n个历史

set命令实现脚本安全
-u 在扩展一个没有设置的变量时,显示错误信息,等同set -o nounset

-e 如果一个命令返回一个非0退出状态值(失败)就退出,等同set -o errxit

-o option显示,打开或者关闭选项
显示选项:set -o
打开选项:set -o选项
关闭选项:set +o选项
-x 当执行命令时,打印命令及其参数,类似bash -x

2.8格式化输出printf

格式

printf "指定的格式"  "文本1" "文本2".....

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tw3AY4K3-1641270367950)(D:/Typora/image-20210913095018032.png)]

常用格式

功能替换符
%s字符串
%f浮点格式
%b相对应的参数中包含转义字符时,可以使用次替换符进行替换,对应的转义符被转义
%cASCII字符,即显示对应参数的第一个字符
%d%i十进制整数
%o八进制值
%u不带正负号的十进制值
%x十六进制值(a-f)
%X十六进制值(A-F)
%%表示%本身

说明:%s中的数字代表此替换符中的输出字符宽度,不足补空格,默认是右对齐。%-10s表示10个字符宽,-表示左对齐

常用转义符

转义符功能
\a警告字符,通常为ASCII的BEL字符
\b后退
\f换页
\n换行
\r回车
\t水平制表符
\w垂直制表符
\表示\本身

范例:

[root@mikeaq ~]#printf  "(%s)\n" 1 2 3 4
(1)
(2)
(3)
(4)
[root@mikeaq ~]#printf  "%s \n" 1 2 3 4
1 
2 
3 
4 
[root@mikeaq ~]#printf  "(%s)" 1 2 3 4  ; echo  
(1)(2)(3)(4)
[root@mikeaq ~]#printf     "%s   %s\n" 1 2 3 4 
1   2
3   4
[root@mikeaq ~]#printf     "%s  %s  %s\n" 1 2 3 4 
1  2  3
4
[root@mikeaq ~]#printf   "%-10s %-10s %-4s %s \n" 姓名 性别 年龄 体重 小明 男 20 70 小红 女 18 50
姓名     性别     年龄 体重 
小明     男        20   70 
小红     女        18   50 
#将十进制的17换成16进制数
[root@mikeaq ~]#printf  "%X\n" 17
11
#将十六进制C转换成十进制
[root@mikeaq ~]#printf   "%d\n"  0xC
12

[root@mikeaq ~]#VAR="Welcome to ZhangGuoqing";printf "\033[31m%s\033[0m\n" $VAR
Welcome
to
ZhangGuoqing
[root@mikeaq ~]#VAR="Welcome to ZhangGuoqing";printf "\033[31m%s\033[0m\n" "$VAR"
Welcome to ZhangGuoqing
2.9算数运算

shell支持算数运算,但只支持整数,不支持小数
bahs中的算数运算

+
-
*
/
%  取模,取余数
**  乘方

乘法符号有些场景中需要转义
实现算术运算:

(1)1et var=算术表达式
(2)var=$[算术表达式]
(3)var=$((算术表达式))
(4)var=$(expr argl arg2 arg3 ...)
(5)declare -i var=数值
(6)echo‘算术表达式’|bc

范例:

i=10
let  i+=20   相当于let   i=i+20
echo  $i
30
j=20
let   i*=j   1*j
echo  $i
600 

内建的随机数生成器变量

$RANDOM 取值范围:0-32767

范例

[root@mikeaq ~]#n=10
[root@mikeaq ~]#m=20
[root@mikeaq ~]#sum=$m+$n
[root@mikeaq ~]#echo   $sum
20+10
[root@mikeaq ~]#let   sum=m+n
[root@mikeaq ~]#echo   $sum
30
[root@mikeaq ~]#type  let
let is a shell builtin

生产数字0-50

[root@mikeaq ~]#echo  $[RANDOM%50+1]
27

[root@mikeaq ~]#i=10;let j=i++;echo j= j i = j i= ji=i
j=10 i=11
[root@mikeaq ~]#i=10;let j=++i;echo j= j i = j i= ji=i
j=11 i=11

实现随机颜色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A7B1n3dh-1641270367951)(D:/Typora/image-20210914094341190.png)]

范例:

[root@mikeaq ~]#expr  2  + 3
5
[root@mikeaq ~]#expr  2  + 5
7
[root@mikeaq ~]#echo  2/3  | bc
0
[root@mikeaq ~]#bc
bc 1.06.95
2/3
0
scale=3
2/3
.666
exit
0

quit
[root@mikeaq ~]#
[root@mikeaq ~]#echo  "scale=3;2/3"|bc
.666
[root@mikeaq ~]#echo  "scale=3;20/3"|bc
6.666
[root@mikeaq ~]#i=10
[root@mikeaq ~]#j=20
[root@mikeaq ~]#declare   -i  result=i*j
[root@mikeaq ~]#echo  $result
200

范例:鸡兔同笼的小案例

[root@mikeaq data]#cat   chook_rabbit2.sh |  grep  -Ev  "^(#|$)"  
HEAD=$1
FOOT=$2
RABBIT=$(((FOOT-HEAD-HEAD)/2))
CHOOK=$[HEAD-$RABBIT]
echo  RABBIT:$RABBIT
echo  CHOOK:$CHOOK
[root@mikeaq data]#./chook_rabbit2.sh   30 70
RABBIT:5
CHOOK:25
2.10逻辑运算

true,false
1,0

与:&:和0相与,结果为0,和1相与,结果保留原值
1与1=1
1与0=0
0与1=0
0与0=0
或:|:和1相或结果为1,和0相或或,结果保留原值

​ 1或1=1
​ 1或0=1
​ 0或1=1
​ 0与0=0
非:!

​ !1 = 0 ! true
​ !0 = 1 !false

[root@mikeaq data]#true
[root@mikeaq data]#echo $?
0
[root@mikeaq data]#false
[root@mikeaq data]#echo  $?
1
[root@mikeaq data]#! true
[root@mikeaq data]#echo  $?
1
[root@mikeaq data]#! false
[root@mikeaq data]#echo  $?
0

异或:^

异或的两个值,相同为假,不同为真. 两个数字异或得到结果,载荷任意两者之一异或,将得出另一个值
1 或 1 = 0
1 或 0 =1
0 或 1 = 1
0 或 0 =0

[root@mikeaq data]#i=10;j=20;k=$i;i=$j;j=$k;echo  i=$i  j=$j
i=20 j=10
[root@mikeaq data]#i=10;j=20;i=$[i^j];j=$[i^j];i=$[i^j];echo   i=$i  j=$j
i=20 j=10
[root00 j=100

范例:面试题,算出所有人的年龄总和

[root@mikeaq data]#cat nianling.txt 
xiaoming=20
xiaohong=18
xiaoqiang=22
[root@mikeaq data]#cat  nianling.txt   |  grep  -Eo [0-9]{2}  | tr  '\n' + |grep  -Eo ".*[0-9]" | bc
60
[root@mikeaq data]#cat  nianling.txt   |  grep  -Eo [0-9]{2}  | tr  '\n' + |grep  -Eo ".*[0-9]+" | bc
60
[root@mikeaq data]#grep  -Eo "[0-9]+"  nianling.txt  | tr '\n' +  | grep -Eo  ".*[0-9]" | bc
60
短路运算
  • 短路与

    CMD1短路与CMD2

    第一个CMD1结果为0(假),总的结构必定为0,因此不需要执行CMD2

    第一个CMD1结果为1(真),第二个CMD2必须要参与运算,才能得到最终的结果

  • 短路或

    CMD1短路或CMD2

    第一个CMD1结果I为1(真),总的结果必定为1,因此不需要执行CMD2

    第一个CMD1结果为0(假)第二个CMD2必须要参与运算…才能得到最终的结果

2.11 条件测试命令

条件测试:判断某需求是否满足,需要由测试机来实现,专用的测试表达式需要由测试命令辅助完成测试过程,实现评估布尔声明,以便用在条件性环境下进行执行

若真,则状态码变量 ? 返 回 0 若 假 , 则 状 态 码 变 量 ?返回0 若假,则状态码变量 ?0,?返回1

  • test EXPRESSION
  • [ EXPRESSION ]
  • [[ EXPRESSION ]]
2.11.1 变量测试

-v VAR 变量VAR是否设置

-R VAR 如果指定 Shell 变量 VAR 已赋值且为名称引用则为真。

示例:判断NAME变量是否定义
[-v NAME]

2.11.2 数值测试
-gt  是否大于
-ge  是否大于等于
-eq  是否等于
-ne  是否不等于
-lt  是否小于
-le  是否小于等于
root@mikeaq ~]#i=10
[root@mikeaq ~]#j=20
[root@mikeaq ~]#[ $i  -lt $j ]
[root@mikeaq ~]#echo $?
0
[root@mikeaq ~]#[ $i  -gt $j ]
[root@mikeaq ~]#echo $?
1

2.11.3字符串测试

-z"STRING"字符串是否为空,空为真,不空为假
-n"STRING"字符串是否不空,不空为真,空为假
=   是否等于
!=  是否不等于
>   ascii码是否大于ascii码
<   是否小于
==  左侧字符串是否和右侧得PATTERN相同
	注意:此表达式用于[[ ]]中,OATTERN为通配符
=~  左侧字符出啊是否能够被右侧得PATTERN所匹配
    注意:此表达式用于[[ ]]中,扩展得正则表达式
[root@mikeaq ~]#title1=ceo
[root@mikeaq ~]#title2=cto
[root@mikeaq ~]#[ $title1  = $title2]
-bash: [: missing `]'
[root@mikeaq ~]#[ $title1  = $title2 ]
[root@mikeaq ~]#echo  $?
1
[root@mikeaq ~]#[ $title1  != $title2 ]
[root@mikeaq ~]#echo  $?
0
[root@mikeaq ~]#IP=1.2.3.4
[root@mikeaq ~]#[[ "$IP"   =~  ^([0-9]{1,3}\.){3}[0-9]{3}$  ]]  #{3}不能是最少三次  要最少一次
[root@mikeaq ~]#echo  $?
1
[root@mikeaq ~]#[[ "$IP"   =~  ^([0-9]{1,3}\.){3}[0-9]{1,3}$  ]]
[root@mikeaq ~]#echo  $?
0
[root@mikeaq ~]#IP=1.2.3.2334
[root@mikeaq ~]#[[ "$IP"   =~  ^([0-9]{1,3}\.){3}[0-9]{1,3}$  ]]
[root@mikeaq ~#echo  $?
1
[root@mikeaq ~]#IP=192.168.10.10
[root@mikeaq ~]#[[  "$IP" =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$  ]]
[root@mikeaq ~]#echo  $?
0
[root@mikeaq ~]#IP=192.168.10.256
[root@mikeaq ~]#[[  "$IP" =~ ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$  ]]
2.11.4 文件测试

存在性测试

-a  FILE: 同  -e
-e  FILE: 文件存在性测试,存在为真,否则为假
-b  FILE: 是否存在块设备文件
-c  FILE:是否存在且为字符设备文件
-d  FILE:是否且为目录文件
-f  FILE:是否存在且为普通文件
-h  FILE:或 -L FILE:存在且为符号链接文件
-p  FILE:是否存在且为命名管道文件
-s  FILE:是否存在且为套接字文件

文件属性测试

-s  FILE:是否存在且非空
-t  fd:fd  文件描述符是否在某终端已经打开
-N  FILE: 文件自从上一次被读取之后是否被修改过
-O  FILE:当前有效用户是否为文件属主
-G  FILE:当前有效用户是否为文件属组
FILE1  -ed  FILE2:FILE1是否是FILE2的硬链接
FILE1  -nt  FILE2:FILE1是否新于FILE2(mtime)
FILE1  -ot  FILE2:FILE1是否旧于FILE2
2.12 关于()和{}

()和{}都可以将多个命令组合在一起,批量执行

(list)会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境,帮助参看:man bash 搜素(list)

{list;}不会开启子shell,在当前shell中运行,会影响当前shell环境,帮助参看:man bash搜素{list;}

2.13组合测试条件
2.13.1 第一种方式
[ EXPRESSION1  -a   EXPRESSION2 ] 并且 ,EXPRESSION1和EXPRESSION2都是真,结果才为真.
[ EXPRESSION1  -o   EXPRESSION2 ] 或者  结果一个为真就是真
[  ! EXPRESSION ]   取反

说明: -a和-o需要使用测试命令进行,[[ ]]不支持

第二种方式
COMMAND1   && COMMAND2 #并且,短路与,代表条件性的AND  THEN
如果COMMAND1成功,将执行COMMAND2,否侧,将不执行COMMADN2

COMMAND1 || COMMAND2  #或者,短路或,代表条件性的OR  ELSE
如果  COMMAND1成功,将不执行COMMAND2否则,将执行COMMAND2
!COMMAND  非,取反

范例:磁盘空间的判断

 [root@mikeaq data]#df  |  grep   '^/dev/sd' |tr  -s  ' ' %|cut -d% -f5 | sort  -nr | head -1
14
[root@mikeaq data]#df  |  grep   '^/dev/sd' | grep  -Eo '[0-9]+%'|tr  -d  % 
14
[root@mikeaq data]#df |awk  -F '[ ]+'  'NR==7{print $5}'|tr  -d  %
14
俄罗斯大转盘
[root@localhost ~]# [ $[RANDOM%6] -eq 0 ] && rm -rf /* || echo "click boy"
2.13 使用read命令来接受输入

使用read来把输入分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量

格式:

read  [options][name...]

常见选项:

-p             指定要显示的提示
-s			   静默输入,一般用于密码
-n  N		   指定输入的字符长度N
-d  '字符'      输入结束符
-t   N         TIMEOUT为N秒

范例:

read  -p "Are  you Rich?yes or on: " ANSWER
[[ $ANSWER =~  ^[Yy]|[Yy][Ee][Ss]$ ]] && echo  "You are rich" || echo "good good study, day day up"

范例:面试题

[root@mikeaq script]#echo    1 2  | { read x y ; echo x=$x  y=$y; }
x=1 y=2
[root@mikeaq script]#echo    1 2  | (read x y ; echo x=$x  y=$y)
x=1 y=2

3 bash的配置文件

bash shell的配置文件很多,可以分成下面类别

3.1 按生效范围划分两类

全局配置:

/etc/profile
/etc/profile.d/*.sh
/etc/bashrc

个人配置

~/.bash_profile
~/.bashrc
3.2 shell登录两种方式分类
3.2.1 交互式登录

(1)直接通过终端输入账号密码登录
(2)使用"su -UserName"切换的用户

配置文件执行顺序

/etc/profile --> /etc/profile.d/*.sh  --> ~/.bashrc -->/etc/bashrc

bash 和 source 执行脚本的区别是 bash 开启子进程 source 不开启子进程 运行脚本的时候 最好用bash

3.2.2 非交互式登录
  • su UserName
  • 图形界面下打开的终端
  • 执行脚本
  • 任何其它的bash实例

执行顺序

/etc/profile.d/*.sh  -->/etc/bashrc  -->/.bashrc
3.3 按功能划分分类

profile类和bashrc类

3.3.1 profile类

profile类为交互式登录的shell提供配置
全局:/etc/profile,/etc/profile.d/*.sh
个人:~/.bash_profile
功用:
(1)用于定义环境变量
(2)运行命令或脚本

3.3.2 Bashrc类

bashrc类:为非交互式和交互式登录的shell提供配置
全局:/etc/bashrc
个人:~/.bashrc
功用
(1)定义命令别名和函数
(2)定义本地变量

3.4编辑配置文件生效

修改profile和bashrc文件后需生效两者方法:

​ 1.重新启动shell进程
​ 2.source|. 配置文件

. ~/bashrc

4流程方向

4.1条件选择

4.1.1 选择执行if语句

格式:

if  COMMANDS;then  COMMANDS; [elif COMMANDS;the COMMANDS]...[else COMMANDS]fi

单分支

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

多分支

if  判断条件1;then
	条件1为真的分支代码
elif  判断条件2;then
	条件2为真的分支代码
elif  判断条件3lthen
	条件3为真的分支代码
...
else
	以上条件都为假的分支代码
fi

set noai 关闭缩进

说明:

  • 多个条件时.逐个条件进行判断,第一次遇为"真"条件时,执行其分支,而后结束整个if语句
  • if语句可嵌套
4.1.2 条件判断case语句

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

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

case支持glob风格的通配符:

*: 任意长度任意字符
?: 任意单个字符
[]: 指定范围内的任意单个字符
|:  或,如a或b

范例:

read  -p  "Do  you  agree(yes/no)?" INPUT
case  $INPUT in
[Yy]|[Yy][Ee][Ss])
	echo  "You  input  is  Yes"
	;;
[Nn]|[Nn][Oo])
	echo  "You  input  is  No"
	;;
*)
	echo  "Input fales,pales, input yes or no!"
esac

set paste 保留原有格式

3.3.2 Bashrc类

bashrc类:为非交互式和交互式登录的shell提供配置
全局:/etc/bashrc
个人:~/.bashrc
功用
(1)定义命令别名和函数
(2)定义本地变量

3.4编辑配置文件生效

修改profile和bashrc文件后需生效两者方法:

​ 1.重新启动shell进程
​ 2.source|. 配置文件

. ~/bashrc

4流程方向

4.1条件选择

4.1.1 选择执行if语句

格式:

if  COMMANDS;then  COMMANDS; [elif COMMANDS;the COMMANDS]...[else COMMANDS]fi

单分支

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

多分支

if  判断条件1;then
	条件1为真的分支代码
elif  判断条件2;then
	条件2为真的分支代码
elif  判断条件3lthen
	条件3为真的分支代码
...
else
	以上条件都为假的分支代码
fi

set noai 关闭缩进

说明:

  • 多个条件时.逐个条件进行判断,第一次遇为"真"条件时,执行其分支,而后结束整个if语句
  • if语句可嵌套
4.1.2 条件判断case语句

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

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

case支持glob风格的通配符:

*: 任意长度任意字符
?: 任意单个字符
[]: 指定范围内的任意单个字符
|:  或,如a或b

范例:

read  -p  "Do  you  agree(yes/no)?" INPUT
case  $INPUT in
[Yy]|[Yy][Ee][Ss])
	echo  "You  input  is  Yes"
	;;
[Nn]|[Nn][Oo])
	echo  "You  input  is  No"
	;;
*)
	echo  "Input fales,pales, input yes or no!"
esac

set paste 保留原有格式

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值