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)
上一篇 2016-08-15 12:06
下一篇 2016-08-15 12:06

相关推荐

  • 初识

    CPU:运算器、控制器、寄存器、缓存 分区不能直接被访问,需要接口 磁盘0 第一分区  挂载mount      C 磁盘0 第一分区  挂载mount      C:\var 如果一个目录没有被分区单独挂载,那么其数据存储在父目录所对应的…

    2017-07-11
  • Linux进程管理

    内核的功能:     进程管理 文件系统 网络功能 内存管理 驱动程序 安全功能等     rocess:运行中的程序的一个副本,是被载入内存的一个指令集合      进程ID(Process ID,PID)号码被用来标记各个进程 UID,GID,和…

    Linux干货 2016-09-12
  • N25第5周作业(grep和find使用)

    显示当前系统上root, fedora 或user1的默认shell 找出/etc/rc.d/init.d/functions文件中某单词后面跟一组小括号的行,形如:hello(); 使用echo命令输出一个绝对路径,使用grep取出基名,扩展取出其路径名 找出IFCONIFG命令结果的1-255之间的数字 挑战题:写一个模式,能匹配出合理的IP地址 挑战题…

    Linux干货 2016-12-30
  • 博客作业-N22第二周

    1、linux上的文件管理类命令都有那些,其常用的使用方法及其相关示例演示。 答: cp 复制文件 [root@localhost network-scripts]# cp ifcfg-eno16777736 ifcfg-eno.bak [root@localhost network-scripts]# ls ifcfg-eno16777736  …

    Linux干货 2016-08-22
  • 跟着vimtutor走来认识vim

        一、前言        VIM是一款在vi上进行改进的功能性强大的,开源的文本编辑器。     二、vim的设计理念     vim的设计理念是组合;       命令组合:类似于linux的由一个个单一功能的程…

    Linux干货 2016-05-13
  • 马哥教育网络班21期+第7周课程练习

    1、创建一个10G分区,并格式为ext4文件系统; (1) 要求其block大小为2048, 预留空间百分比为2, 卷标为MYDATA, 默认挂载属性包含acl; [root@localhost ~]#mke2fs -t ext4 -b 2048 -m 2 -L &qu…

    Linux干货 2016-08-15