Linuxshell脚本基础

编程基础
Linus:Talk is cheap, show me the code
程序
程序:算法+数据结构
数据:是程序的核心
数据结构:数据在计算机中的类型和组织方式
算法:处理数据的方式

程序编程风格:
过程式:以指令为中心,数据服务于指令
对象式:以数据为中心,指令服务于数据
shell程序:提供了编程能力,解释执行

编程基本概念
编程逻辑处理方式:
顺序执行
循环执行
选择执行
shell编程:过程式、解释执行
编程语言的基本结构:
各种系统命令的组合
数据存储:变量、数组
表达式:a + b
语句:if

shell脚本基础
shell脚本:
包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行shebang机制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
shell脚本的用途有:
自动化常用命令
执行系统管理和故障排除
创建简单的应用程序
处理文本或文件

 建⽴脚本

vim hello.sh
#!/bin/bash
echo "hello world"

---------------------
脚本调试

检测脚本中的语法错误
bash -n disk.sh

调试执行
bash -x disk.sh

---------------

运⾏脚本:
添加执行权限
chmod +x disk.sh

直接运行bash 

bash disk.sh

PATH变量的使⽤

[root@localhost data]# PATH=.:$PATH    把.加入PATH变量
[root@localhost data]# echo $PATH
.:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

[root@localhost /]# PATH=/data:$PATH   把/data加入PATH变量
[root@localhost /]# echo $PATH
/data:.:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

------------------------------------

变量:

脚本中的变量
Shell中变量命名法则:
1、不能使程序中的保留字:例如if, for
2、只能使用数字、字母及下划线,且不能以数字开头
3、见名知义
4、统一命名规则:驼峰命名法
Shell中命名建议规则:
1、变量名大写
2、局部变量小写
3、函数名小写
4、用英文名字,并体现出实际作用

----------------------------------------------------

关键字,不能⽤作变量

[root@localhost ~]# type while
while is a shell keyword

统⼀命名规则: 

forName
FOR_NAME

局部变量
变量赋值:name=‘value’
可以使用引用value
(1) 可以是直接字串:name=“root"
(2) 变量引用:name="$USER"
(3) 命令引用:name=`COMMAND`
name=$(COMMAND)
变量引用:${name} 或者 $name
" " 弱引用,其中的变量引用会被替换为变量值
' ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
显示已定义的所有变量:set
删除变量:unset name

---------------------------------------

变量的定义和读取$

[root@localhost ~]# NAME=CHEN
[root@localhost ~]# echo $NAME
CHEN
[root@localhost ~]# echo "$NAME"
CHEN
[root@localhost ~]# echo '$NAME'
$NAME

--------------------------------------------------

单引号、双引号、反向单引号区别:

1、由单引号('),强引用,其中的变量会被替换未变量值。
2、由双引号("),弱引用,其中的变量不会被替换未变量值,而保持原字符串。
3、反向单引号(`)括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准
输出结果取代整个反引号(包括两个反引号)部分。

----------------------------------------------------------------------

多个变量的定义和读取$

[root@localhost ~]# g1=duan

[root@localhost ~]# g2=zhao
[root@localhost ~]# echo $g1$g2
duanzhao

区别变量名和变量,⽤{}或"分隔。

[root@localhost ~]# num=1
[root@localhost ~]# echo No$num
No1
[root@localhost ~]# echo $numNo
[root@localhost ~]# echo ${num}No
1No
[root@localhost ~]# echo ${num}
1
[root@localhost ~]# echo $"num"No
numNo
[root@localhost ~]# echo "$num"No
1No

----------------------------------------

变量赋值,m指向新的赋值,n不变
[root@localhost ~]# m=10
[root@localhost ~]# n=$m
[root@localhost ~]# echo $m
10
[root@localhost ~]# echo $n
10
[root@localhost ~]# m=20
[root@localhost ~]# echo $m
20
[root@localhost ~]# echo $n
10
⾃定义变量

[root@localhost data]# name=zhang

[root@localhost ~]# unset name 删除变量

⼦进程不能使⽤⽗进程定义的普通变量

[root@localhost ~]# name=zhang
[root@localhost ~]# echo $name
zhang
[root@localhost ~]# bash 开启子进程
[root@localhost ~]# $name
[root@localhost ~]# exit 退出子进程
exit

-------------------------------------------------
父进程与子进程建立关系,环境变量可以传递

父进程与子进程建立关系 普通变量不能传递

去掉环境变量效果

 

 

⾃定义环境变量,⽗进程的变量可以传给⼦进程

root@localhost ~]# VAR=test
[root@localhost ~]# export VAR 自定义环境变量
[root@localhost ~]# echo $VAR
test

[root@localhost ~]# bash 开启子进程
[root@localhost ~]# echo $VAR 父进程的变量可以传给子进程。
test
[root@localhost ~]# exit 退出子进程
exit

"( )"开启⼦进程

--------------------------------------------------------------

只读变量:
只读变量:只能声明,但不能修改和删除
声明只读变量:
readonly name
declare -r name
查看只读变量:
readonly -p

-----------------------------

位置变量:
位置变量:在脚本代码中调用通过命令行传递给脚本的参数
$1, $2, ... 对应第1、第2等参数,shift [n]换位置
$0 命令本身
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数
注意:$@ $* 只在被双引号包起来的时候才会有差异
set -- 清空所有位置变量

位置变量脚本。

只读变量,不能修改

特殊变量:$? , $0 , $*, $@ , $# , $$

进程使用退出状态来报告成功或失败0 代表成功,1-255代表失败$? 变量保存最近的命令退出状态
bash自定义退出状态码
exit [n]:自定义退出状态码

自定义,退出状态$?

 算术运算: 

bash中的算术运算:help let
+, -, *, /, %取模(取余), **(乘方),乘法符号有些场景中需要转义
实现算术运算:
(1) let var=算术表达式
(2) var=$[算术表达式]
(3) var=$((算术表达式))
(4) var=$(expr arg1 arg2 arg3 ...)
(5) declare –i var = 数值
(6) echo ‘算术表达式’ | bc
bash有内建的随机数生成器变量:$RANDOM(0-32767)
示例:生成 0 - 49 之间随机数

var=$[算术表达式]和var=$((算术表达式

var=$(expr arg1 arg2 arg3 ...),"*"需要转义

 

 

赋值

增强型赋值:
+=, -=, *=, /=, %=

逻辑运算:

true, false
1, 0

1 与 1 = 1
1 与 0 = 0
0 与 1 = 0
0 与 0 = 0

1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0
非:!
! 1 = 0 ! true
! 0 = 1 ! false
true, false。

短路运算
短路与
第一个为0,结果必定为0
第一个为1,第二个必须要参与运算
短路或
第一个为1,结果必定为1
第一个为0,第二个必须要参与运算
异或:^
异或的两个值,相同为假,不同为真

 异或

条件测试:
判断某需求是否满足,需要由测试机制来实现。专用的测试表达式需要由测试命令辅助完成测试过程
评估布尔声明,以便用在条件性执行中
若真,则返回0
若假,则返回1

test=[ ]

est=[[]]⽀持正则表达式

数值测试
-v VAR
变量VAR是否设置
数值测试:
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于

字符串测试:

= 是否等于
> ascii码是否大于ascii码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
注意: 此表达式一般用于[[ ]]中;扩展的正则表达式
-z "STRING“ 字符串是否为空,空为真,不空为假
-n "STRING“ 字符串是否不空,不空为真,空为假

数值测试

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

⽂件权限测试:
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行

⽂件特殊权限测试
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限

read命令:
使用read来把输入值分配给一个或多个shell变量
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d ‘字符’ 输入结束符

read 从标准输入中读取值,给每个单词分配一个变量。所有剩余单词都被分配给最后一个变量

、条件选择if语句
选择执行:
注意:if语句可嵌套
单分支
if 判断条件;then
条件为真的分支代码
fi
双分支
if 判断条件; then
条件为真的分支代码
else
条件为假的分支代码
fi
多分支
if 判断条件1; then
条件1为真的分支代码
elif 判断条件2; then
条件2为真的分支代码
elif 判断条件3; then
条件3为真的分支代码
else
以上条件都为假的分支代码
fi
逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句

条件判断:case语句
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac
case支持glob风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b

posted @ 2019-05-26 19:13  凤溪潇潇  阅读(123)  评论(0编辑  收藏  举报