2016年8月11号学习博客

shell脚本编程

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

shell脚本的用途有:

  • 自动化常用命令

  • 执行系统管理和故障排除

  • 创建简单的应用程序

  • 处理文本或文件

命令查询过程:别名–>内部变量–>hash–>$PATH

~]#bash -n 检测脚本语法错误

~]#bash -x 顺序检查调试执行

程序的组成:指令+数据
程序编程风格:
1、过程式:以指令为中心,数据服务于指令
2、对象式:以数据为中心,指令服务于数据

编程逻辑处理方式:顺序执行、循环执行、选择执行

变量

什么是变量:是一段命名的内存空间

变量数据类型:    
1、字符型    
2、数值:整型,浮点型

如何创建shell脚本

  1. 使用文本编辑器来创建文本文件 第一行必须包括shell声明序列:#!/bin/bash 可以自行添加注释,注释以#开头

  2. 运行脚本,给予执行权限,在命令行上指定脚本的绝对或相对路径,直接运行解释器,将脚本作为解释器程序的参数运行

编程程序语言分类

强类型:

  • 定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误

弱类型

  • 无须指定类型,默认均为字符类型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用

编程语言变量命名法则:

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

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

  3. 见名知义

  4. 统一命名规则:驼峰命名法

Bash中变量的种类

根据变量的生效范围等标准分:

  • 本地变量:生效范围为当前shell进程;对当前shell之外的其他shell进程,包括当前shell子shell进程均无效

  • 环境变量:生效范围为当前shell进程及其子进程

  • 局部变量:生效范围为当前shell进程某代码片段(通常指函数)

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

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

本地变量:

变量赋值:name='value'
变量引用:name="$USER"
    变量引用可分为两种        
    "":弱引用,其中的变量引用会被替换为变量值
    '':强引用,其中的变量引用不会被替换为变量值,而保持原字符串
命令引用:name=`COMMAND`,name=$(COMMAND)
显示已定义的所有变量:set
删除定义的变量:unset name

环境变量

环境变量声明、赋值
    export name=value    
    declare -x name=value
    变量引用方式:$name,${name}
显示所有环境变量:export、env、printenv
删除变量:unset name
Bash有许多内建的环境变量:    
    PATH:可执行文件的搜索路径,决定了shell将到哪些目录中寻找命令或程序。
    SHELL:当前登录用户shell类型    
    USER:当前登录用户
    UID:当前登录用户ID
    HISTSIZE:历史命令记录数,定义了history命令输出的记录数,即输出.bash_history文件中的最后HISTSIZE行
    HISTFILESIZE:定义了在~/.bash_history中保存命令的记录总数
    HISTFILE:历史命令记录的配置文件,它是隐藏文件
    HOME:当前用户主目录
    PWD:当前工作目录
    OLDPWD:之前工作目录
    PS1:一级命令提示符
    PS2:使用转义字符,第二行出现的提示符

只读变量

语法:readonly (option)(arguments)
readonly命令用于定义只读shell变量和shell函数,只能声明,不能删除和修改。
~]#readonly
    -p 输出显示系统中所有定义的只读变量    
    -f 定义只读函数    
    -a 定义只读数组变量
    
变量定义:readonly name 
         declare -r name
注意:只对当前shell有效,注销后清除

位置变量

在脚本代码中调用通过命令行传递给脚本的参数:   
$1,$2,...:对应第1、第位参数,shift[n]换位置    
$0 命令本身    
$* 传递给脚本的所有参数。全部参数合为一个字符串    
$@:传递给脚本的所有参数,每个参数为独立字符串    
$#:传递到脚本的参数的个数    
$$:脚本运行的当前进程ID号
注意:$@,$*只在被双引号引起来的时候才会有差异
双引号括起来的情况:$*将所有的参数认为是一个字段,所有的位置参数,被作为一个单词
$@每个参数都是一个独立的""引用字串,这就意味着参数被完整地传递,并没有被解释和扩展,这也意味着,每个参数列表中的每个参数都被当成一个独立的单词.
示例:抄的还请见谅。
#!/bin/bash
echo "-------------ISF is set to \"-seperator\" ------------"
IFS="-seperator";  # 注意 seperator前有一个减号(-)
for i in "$@"; do echo "@ '$i'"; done
for i in "$*"; do echo "* '$i'"; done
echo "-------------ISF is set to null ------------------------"
IFS=
for i in "$@"; do echo "@ '$i'"; done
for i in "$*"; do echo "* '$i'"; done
echo "-------------ISF is unset ------------------------"
unset IFS
for i in "$@"; do echo "@ '$i'"; done
for i in "$*"; do echo "* '$i'"; done
echo "---------$* and $@ are not put into double quotes(\"\")-------"
for i in $@; do echo "@ '$i'"; done
for i in $*; do echo "* '$i'"; done
运行结果:
-------------ISF is set to "-seperator" ------------
@ '1'
@ '2'
@ '3'
* '1-2-3'
-------------ISF is set to null ------------------------
@ '1'
@ '2'
@ '3'
* '123'
-------------ISF is unset ------------------------
@ '1'
@ '2'
@ '3'
* '1 2 3'
---------1 2 3 and 1 2 3 are not put into double quotes("")-------
@ '1'
@ '2'
@ '3'
* '1'
* '2'
* '3'
由此可见,
当不加双引号("")时, $*,$@被展开时的行为是一样的;
当$*,$@都被放到双引号("")内;如果设置了变量IFS的值并且该值非空,
则$*被展开时使用${IFS}的第一个字符将所有参数(除了参数$0)连接起来,
即"$1c$2c$3c...",其中c表示${IFS}的第一个字符;
如果变量IFS为空,则$*被展开时只是将所有参数(除了参数$0)简单连接起来, 即 “$1$2$3..."
如果变量IFS没有被定义,则$*被展开时使用空格字符将所有参数(除了参数$0) 连接起来, 即"$1 $2 $3 ..."
但$@的展开和没有加双引号的情形是一致的。

算术运算

bash中的算术运算:
expr,let
+,-,*,/,%取模(取余),**(乘方)

实现算术运算

  1. let var=算术表达式

  2. var=$[算术表达式]

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

  4. var=$(expr arg1 arg2 arg3 …)

  5. declare -i var = 数值

  6. echo '算术表达式' | bc

bash中有内建的随机数生成器:$RANDOM(1-32767)
    示例:echo $[$RANDOM%50]:0-49之间随机数
expr 作乘法运算的时候需把*转义\*

赋值

增强型赋值型
    +=,-=,*=,/=,%=
    let varvalue
    示例:let count+=3 自加3后在赋值
自增,自减:    
    let var+=1
    let var++    
    let var-=1
    let var--1

逻辑运算

true 为1    false 为0
与(and) &    
    1 与 1 = 1
    1 与 0 = 0
    0 与 1 = 0
    0 与 0 = 0
 或(or) |    
    1 或 1 = 1
    1 或 0 = 1
    0 或 1 = 1
    0 或 0 = 0
    非!:! 1 = 0         ! 0 = 1
    异或^
    异或的两个值,相同为假,不同为真
短路运算
    短路与 &&
    第一个为0,第二个必须要参与运算
    第一个为1,结果必为1
    短路或 ||
    第一个为1,第二个必须要参与运算
    第一个为0,结果必为0
注意:可以说短路运算只能操作布尔型的,而非短路运算不仅可以操作布尔型,而且可以操作数值型。

聚齐命令

有两种聚集命令的方法
    复合式:date;who | wc -l
        命令会一个接一个地运行
    子shell式:(date;who) | wc -l >>/tmp/trace
        所有的输出都被发送给单个STDOUT和STDERR
        作为一个整体

退出状态

进程使用退出状态来报告成功或失败    
0 代表成功,1-255代表失败
$?特殊变量保存最近的命令退出状态
0    成功退出
>0   退出失败
1-125 命令退出失败,失败返回的相关值由程序定义(譬如,程序内退出只执行 exit 2,则返回为2)
126    命令找到了,但无法执行
127    命令找不到
>128    命令因受到信号而死亡
退出状态码
可以bash自定义退出状态码
exit [n]:自定义退出状态码
注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

ping -W(设置响应时间)

脚本中添加(置于子shell下)相当于调用一个shell脚本

条件测试
        判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成测试过程。
评估布尔声明,以便用在条件性执行中
    若真,则返回0
    若假,则返回1测试命令
    test expression(表达式)
    [ expression ]    [[ expression ]]
    注意:expression前后必须有空白字符
根据退出状态而定,命令可以有条件地进行
    && 代表条件性的AND THEN
    || 代表条件下的or else
Bash的测试类型
数值测试:
    -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:是否存在且可执行

文件特殊权限测试:

-g file:是否存在且拥有sgid权限    
-u file:是否存在且拥有suid权限    
-k file:是否存在且拥有sticky权限

文件大小测试:

-s file:是否存在且非空

文件是否打开:

-t fd:fd表示文件描述符是否已经打开且与某终端相关    
-N file:文件自动与上一次被读取之后是否被修改过    
-O file:当前有效用户是否为文件属主    
-G file:当前有效用户是否为文件属组

双目测试:

file1 -ef file2 file1与file2是否指向同一个设备上的相同inode
file1 -nt file2 file1是否新于file2
file1 -ot file2 file1是否旧于file2

原创文章,作者:真的可行(wzb),如若转载,请注明出处:http://www.178linux.com/33968

(0)
真的可行(wzb)真的可行(wzb)
上一篇 2016-08-15
下一篇 2016-08-15

相关推荐

  • Linux系统启动流程初识

    centos系统启动流程 本篇仅仅讲解centos5和6 centos7并不适用 Linux系统的组成部分:内核+根文件系统 内核功能: 进程管理 内存管理 网络管理 驱动程序 文件系统 安全功能 有以下目录结构的文件系统可以被识别为根文件系统,但根文件系统本身不存在 rootfs:/bin/ /sbin /etc/ /sys/…

    Linux干货 2016-09-11
  • 那些年我们一起追过的缓存写法(三)

    原文出处: 蘑菇先生    上次我们说了多级缓存,本章详细介绍下内存缓存该如何设计。 一:分析设计 假设有个项目有一定并发量,要用到多级缓存,如下: 在实际设计一个内存缓存前,我们需要考虑的问题: 1:内存与Redis的数据置换,尽可能在内存中提高数据命中率,减少下一级的压力。 2:内存容量的限制,需要控制缓存数量。 3:热点数…

    Linux干货 2015-03-04
  • Cobbler简单部署小结

     Cobbler 和 koan 的安装源:        ubuntu(12.04)的源:             注: Ubuntu的可用源可从这里查询:http://wiki.ubuntu.org.cn/Template:12.04source …

    Linux干货 2016-03-20
  • 第六周总结VIM编辑器的使用并完成练习题

    第六周 总结VIM编辑器的使用并完成练习题 1. VIM是什么? VIM(Vi IMproved)是从vi发展出来的一个文本编辑器。 2.为什么要使用VIM? VIM有代码补完,编译以及错误跳转等方便编程的功能,在程序员中广泛使用。对于大多数的用户来说,VIM有着比较陡峭的学习曲线,但是一旦掌握一些基本操作之后,能大幅度提高编辑效率。VIM是类Unix系统用…

    Linux干货 2017-09-02
  • 机器学习排序

     从使用的数据类型,以及相关的机器学习技术的观点来看,互联网搜索经历了三代的发展历程。        第一代技术,将互联网网页看作文本,主要采用传统信息检索的方法。        第二代技术,利用互联网的超文本结构,有效…

    Linux干货 2015-12-15
  • gawk基础及进阶

    GUN awk: 文本处理三工具:grep,sed,awd grep,egrep,fgrep:文本过滤工具:pattern sed:行编辑器 模式空间、保持空间 awk:报告生成器,格式化文本输出; AWK:Aho,Weinberger,Kernighan –> New AWK,NAWK GNU awk,gawk gawk – …

    Linux干货 2017-05-22