Linux学习第九节课-shell脚本编程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux学习第九节课-shell脚本编程相关的知识,希望对你有一定的参考价值。

                                                            Linux第九节课 

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

程序:算法+数据结构

数据:程序的核心

算法:处理数据的方式

 

程序编程风格

过程式:以指令为中心,数据服务于指令

对象式:以数据为中心,指令服务于数据

 

高级编程语言

编译:高级语言→编译器→机器代码→执行,例如c,c++等

解释:高级语言→执行→解释器→机器代码,例如shell,python,phpjavascript,perl等

 

编程逻辑处理方式

顺序执行、循环执行、选择执行

 

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

格式要求:#!/bin/bash(或者其他类型的shell文件,根据使用的shell类型进行选择)

 

Shell脚本用途

自动化常用命令

执行系统管理和故障排除

创建简单的应用程序

处理文本或文件

 

编写完一个脚本后,使用chmoda+x给其执行权限,然后将脚本放入bash文件夹内或者更改$PATH或者输入绝对/相对路径来执行,写的脚本属于外部命令

 

变量

强类型:变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。一般定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误

如java,c#

弱类型:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用如:bash不支持浮点数,php

 

变量命名法则:

1、不能使程序中的保留字:例如if,for

2、只能使用数字、字母及下划线,且不能以数字开头

3、见名知义

4、统一命名规则:驼峰命名法,例如小驼峰:studentName,大驼峰StudentName

局部变量:变量只能在当前进程使用,不可以给父进程或者子进程使用,name=“a”

环境变量:全局变量,生效范围为其自身和其子进程,不能给父进程使用,exportname=”a”

本地变量:生效范围为当前shell进程中某代码片断,通常指函数

位置变量:$1,$2,...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数

特殊变量:$?,$0,$*,[email protected],$#,$$

$?判断前一个命令成功还是失败,没有特别指定下,0为成功,1-255为失败

$0脚本名

$*所有参数,参数是一个独立的整体

[email protected]所有参数,参数是独立的个体

$#参数个数

$数字第数字个参数

[email protected]$*只在被双引号包起来的时候才会有差异

Shift:shift键1次后,第一个参数将没有,之前第二个参数变为第一个参数,第n个参数变为第n-1个参数

 

$$查看命令当前进程

$PPID查看当前进程的父进程

 

启用命令source、.和bash之间的区别

Source/.运行脚本不开启子进程,会影响变量,而bash开启子进程,不会影响变量,所有一般使用bash激活脚本,除非设备需要变化环境变量才会使用./source

 

变量赋值

变量赋值:name=‘value’,可以使用引用value:

(1)可以是直接字串;name=“root"

(2)变量引用:name="$USER"

(3)命令引用:name=`COMMAND`name=$(COMMAND)

 

变量引用:${name}$name

"":弱引用,其中的变量引用会被替换为变量值

'':强引用,其中的变量引用不会被替换为变量值,而保持原字符串

 

显示已定义的所有变量:set

删除变量:unsetname

 

显示所有环境变量:

env

printenv

export

declare-x

 

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

声明只读变量:

readonlyname

declare-rname

查看只读变量:readonly–p

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

set--清空所有位置变量

 

算术运算

bash中的算术运算:helplet

+,-,*,/,%取模(取余),**(乘方)

实现算术运算:

(1)letvar=算术表达式

(2)var=$[算术表达式]

(3)var=$((算术表达式))

(4)var=$(exprarg1arg2arg3...)

(5)declare–ivar=数值

(6)echo‘算术表达式’|bc

乘法符号有些场景中需要转义,如*

bash有内建的随机数生成器:$RANDOM(0-32767)

echo$[$RANDOM%50]:0-49之间随机数

 

赋值

增强型赋值:

+=,-=,*=,/=,%=

letvarOPERvalue

例如:letcount+=3

自加3后自赋值

自增,自减:

letvar+=1

letvar++

letvar-=1

letvar—

 

逻辑运算

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

! 0 = 1

短路运算

短路与

第一个为0,结果必定为0

第一个为1,第二个必须要参与运算

短路或

第一个为1,结果必定为1

第一个为0,第二个必须要参与运算

异或:^

异或的两个值,相同为假,不同为真

条件测试

判断某需求是否满足,需要由测试机制来实现

专用的测试表达式需要由测试命令辅助完成测试过程

评估布尔声明,以便用在条件性执行中

若真,则返回0

若假,则返回1

测试命令:

test EXPRESSION

[ EXPRESSION ]

[[ EXPRESSION ]]

注意:EXPRESSION前后必须有空白字符

根据退出状态而定,命令可以有条件地运行

&& 代表条件性的AND THEN

|| 代表条件性的OR ELSE

test命令

长格式的例子:

test "$A" = "$B" && echo "Strings are equal"

test “$A”-eq “$B” && echo "Integers are equal"

简写格式的例子:

[ "$A" = "$B" ] && echo "Strings are equal"

[ "$A" -eq "$B" ] && echo "Integers are equal"

 

bash的数值测试

-v VAR

变量VAR是否设置

数值测试:

-gt 是否大于

-ge 是否大于等于

-eq 是否等于

-ne 是否不等于

-lt 是否小于

-le 是否小于等于

bash的字符串测试

字符串测试:

= 是否等于

> ascii码是否大于ascii码

< 是否小于

!= 是否不等于

=~ 左侧字符串是否能够被右侧的PATTERN所匹配

注意: 此表达式一般用于[[ ]]中;扩展的正则表达式

-z "STRING“ 字符串是否为空,空为真,不空为假

-n "STRING“ 字符串是否不空,不空为真,空为假

 注意:用于字符串比较时的用到的操作数都应该使用引号

 

Bash的文件测试

存在性测试

-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权限

 

文件大小测试:

-s FILE: 是否存在且非空

文件是否打开:

-t fd: fd 文件描述符是否在某终端已经打开

-N FILE:文件自从上一次被读取之后是否被修改过

-O FILE:当前有效用户是否为文件属主

-G FILE:当前有效用户是否为文件属组

 

双目测试:

FILE1 -ef FILE2: FILE1是否是FILE2的硬链接

FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)

FILE1 -ot FILE2: FILE1是否旧于FILE2

 

Bash的组合测试条件

第一种方式:

COMMAND1 && COMMAND2 并且

COMMAND1 || COMMAND2 或者

! COMMAND 非

如:[[ -r FILE ]] && [[ -w FILE ]]

第二种方式:

EXPRESSION1 -a EXPRESSION2 并且

EXPRESSION1 -o EXPRESSION2 或者

! EXPRESSION

必须使用测试命令进行

 

使用read来把输入值分配给一个或多个shell变量

-p 指定要显示的提示

-s 静默输入,一般用于密码

-n N 指定输入的字符长度N

-d ‘字符’ 输入结束符

-t N TIMEOUT为N秒

read 从标准输入中读取值,给每个单词分配一个变量

所有剩余单词都被分配给最后一个变量

read -p “Enter a filename: “ FILE

 

把命令行分成单个命令词

展开别名

展开大括号的声明({})

展开波浪符声明(~)

命令替换$() 和 ``)

再次把命令行分成命令词

展开文件通配(*、?、[abc]等等)

准备I/0重导向(<、>)

运行命令

 

防止扩展

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

$ echo Your cost: $5.00

Your cost: $5.00

加引号来防止扩展

单引号(’)防止所有扩展

双引号(”)也防止所有扩展,但是以下情况例外:

?$(美元符号) - 变量扩展

?`(反引号) - 命令替换

?(反斜线) - 禁止单个字符扩展

?!(叹号) - 历史命令替换

 

bash的配置文件

按生效范围划分,存在两类:

全局配置:

/etc/profile

/etc/profile.d/*.sh

/etc/bashrc

个人配置:

~/.bash_profile

~/.bashrc

 

shell登录两种方式

交互式登录:

(1)直接通过终端输入账号密码登录

(2)使用“su - UserName” 切换的用户

执行顺序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc

非交互式登录:

(1)su UserName

(2)图形界面下打开的终端

(3)执行脚本

(4)任何其它的bash实例

执行顺序: ~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh

 

Profile类

按功能划分,存在两类:

profile类和bashrc类

profile类:为交互式登录的shell提供配置

全局:/etc/profile, /etc/profile.d/*.sh

个人:~/.bash_profile

功用:

(1) 用于定义环境变量

(2) 运行命令或脚本

 

Bashrc类

bashrc类:为非交互式和交互式登录的shell提供配置

全局:/etc/bashrc

个人:~/.bashrc

功用:

(1) 定义命令别名和函数

(2) 定义本地变量

 

编辑配置文件生效

修改profile和bashrc文件后需生效

两种方法:

1重新启动shell进程

2 . 或source

 

Bash 退出任务

保存在~/.bash_logout文件中(用户)

在退出登录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 个历史命令


以上是关于Linux学习第九节课-shell脚本编程的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记第九节课

centos shell编程5LANMP一键安装脚本 第三十九节课

嵌入式Linux从入门到精通之第九节:系统编程

嵌入式Linux从入门到精通之第九节:系统编程

0527 第九节课

第八节课第九节