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

相关推荐

  • vi与vim的使用

    一、引言     在Linux中,vi(Visual Interface)是标准的编辑器,功能强大到不逊于任何最新的编辑器。无论在Linux中还是在Unix中,vi的使用方法都是完全相同的。vim(Vi Improved)在vi的基础上增加了很多新特性。 二、模式     vim…

    Linux干货 2016-08-11
  • keepalived高可用实例

    1、keepalived单实例 1)实验环境为VMware虚拟机,两台centos7.2,主机1IP地址为10.1.252.55,主机2IP地址为10.1.252.34,虚拟路由IP为10.1.252.246, 2)确保iptables和selinux不影响实验 (1)确保两台主机的时间同步 [root@localhost ~]# vim…

    Linux干货 2016-11-01
  • 马哥M20-1第一周作业

    作业1:通过echo实现字体闪烁,添加下划线,改变颜色      (1)添加下划线    (2)字体闪烁   (3)改变颜色 作业2:显示前10天的年月日 作业3:screen的使用

    Linux干货 2016-07-29
  • 路由器解析路由表

    1.定义——>选择最佳路径;他只完成发送到下一个路径上就结束,任务到达就撤了(就像快递员一样,当他将物件发往到下一个目的地,那他的任务就结束了)2.分类:主机路由、网络路由、默认路由3.每个路由记录由四项主要组成部分目标地址:主机IP、网络ID号、未知地址(0.0.0.0)子网掩码接口interface:从哪个口发往目标地址 网…

    2017-09-05
  • N25-第16周博客作业

    1、源码编译安装LNMP架构环境;     安装nginx:      1)安装依赖包 ]# yum groupinstall “Development Tools” “Development Libraries” -y ]# yum install wget openssl-devel ncurses-de…

    2017-05-21
  • 软硬链接区别及tr转换命令

    软硬链接的区别 (1)软连接可以 跨文件系统 ,硬连接不可以 (2)关于 I节点的问题 。硬连接不管有多少个,都指向的是同一个I节点,会把 结点连接数增加,只要结点的连接数不是 0,文件就一直存在 ,不管你删除的是源文件还是连接的文件。只         要有一个存在,文件就 存…

    Linux干货 2016-08-08