shell编程基础篇
重点注意,我们这里介绍的是CentOS 6.7 版本的Linux
一、shell的介绍?(1)什么是shell?????? ??shell是一个命令解释器,它在操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出的结果,输出到屏幕返回给用户。这种对话方式可以是交互式的(从键盘输入,立刻得到shell的回应),或者非交互式的。Shell:是一门弱类型(语法叫宽松)的语言较为通用的shell有bash shell。shell脚本语言的种类也比较多:Bourne shell (包括:sh,ksh,and bash)、C Shell (包括:csh and tcsh)。当然我们这里主要说的是bash shell!!!!! ?(2)shell的编写规范?? - 脚本的开头第一行为:#!/bin/bash 或者 #!/bin/sh。这是因为#!又称为幻数,在执行bash脚本的时候,内核会根据它来确定该用哪一个程序来解释脚本中的内容,这一行必须在脚本的顶端的第一行。其实bash和sh是一个文件,只不过在Linux中/bin/sh是一个链接文件实际的指向为/bin/bash。 ?(3)shell的注释?? - 单行注释:“#” ?(4)脚本的执行??? 在Linux下执行shell有三种方式: 二、shell中的变量?(1)shell的变量介绍??shell中的变量分为两类:环境变量(全局变量)和局部变量。 ?(2)环境变量?? 用于定义shell的运行环境,保证shell的正确执行。所有的环境变量都是系统的全局变量可以用于所有子进程中,包括编辑器、shell脚本和各类应用。 #声明 export 变量名 = 变量的值 变量名=变量的值;export 变量名 declare -x 变量名=变量的值 #系统内置的环境变量介绍: $HOME 用户的家目录 $USER 当前用户 $UID 当前用户的uid $SHELL 当前用户使用的shell $HISTISZE 记录在命令行历史文件中的命令行数 $PATH 执行命令时寻找的目录 $PWD 当前用户的家目录 $PS1 用户登录的环境变量 [[email?protected] ~] $TMOUT 用户登录的超时时间 #显示和取消环境变量 显示:echo $变量 set和env 显示所有的环境变量。 取消:unset 变量名。 readonly:设置只读变量 ?(3)局部变量?? 局部变量也成为本地变量,在用户当前的shell中使用,如果退出shell,则失效。 #声明: 变量名=value(数字、字母、下划线组成) 这里需要介绍一下Linux下的双引号、单引号和不加引号的区别: 由上面的例子可以看出: 单引号:所见即所得,单引号内的内容原样输出。 双引号:如果内容中有变量等,会将变量解析出来,然后将最终的结果打印 不加引号:把内容输出出来,如果有连续的空格会将空格合并为一个空格,然后将变量等解析出来在输出。 反引号:把字符串当做命令去执行。 注意:一般的在使用命令的时候,变量的引用尽量不要加引号或双引号。但是在做字符串判断的时候一般的都需要加上引号。 ?(4)特殊变量#介绍 $0:表示获取当前脚本的脚本名、 $n:获取当前执行的shell脚本的第n个参数,n=1..9,如果n大于10,用${10} $#:获取当前shell命令行中参数的个数 $*:表示参数列表 [email?protected]:表示参数列表 $$:获取当前shell的进程号 $!:执行上一个指令的PID $?:获取执行的上一个指令的返回值(0表示成功,非零表示失败) $_:在此之前执行的命令或脚本的最后一个参数 具体的小编在这里给大家补充两点: 大家可以运行上面的脚本并传入参数,看看具体如何打印的,就大概明白两者的区别了。 ?? - $?返回值得介绍(有助于错误排查): 0:表示执行成功 2:权限拒绝 1~125:表示运行失败,脚本命令,系统命令,错误或者参数传递错误 126:找到该命令,但是无法执行 127:未找到该命令 大于128:命令被系统强制停止 三、shell变量的进阶操作(1)shell变量的计算?? 好的shell脚本,变量的计算显然是离不开的,可以使用(())、let、expr、bc、$[]变量进行计算,这里给大家总结几个常用的。 ?? (()):?? ?只能用于整数计算。常用,效率高。 #用法 a=$((1+1)); 需要使用$进行修饰 ((a=1+1)) 此种方式不需要用$修饰 a=((3>1)) 也可以写入比较,正确返回1,错误返回0 #实现简单的计算器: #!/bin/sh read -p "Please input first num:" num1 read -p "Please input operators:" operators read -p "Please input second num:" num2 sum=$(($num1$operators$num2)) echo "$num1 $operators $num2 = $sum" ?? let:?? ?用作简单的整数计算,let赋值表达式。
?? bc:?? ?可以实现整数、小数的运算,接受标准输入。
#实现1+2…10的计算 #!/bin/sh str="" for i in `seq 10` do if [ $i -eq 10 ];then str=$str$i else str=$str$i"+" fi done sum=`echo "$str"|bc` echo "$str=$sum" #保留小数
?? $[]:?? ?a=$[1+1],与(())类似,但是[]不能讲变量提取到[]中。 (2)变量子串的常见操作#子串的操作 ${#string} 返回string这个变量的长度 ${strting:position} 在变量string中从position开始提取子串(从0开始,取到结尾) ${string:pos:len} 在变量string中从pos开始提取子串,提取长度为len ${string#sub} 在变量string中从头开始,删除sub匹配的子串 ${string%sub} 在变量string中从末尾开始,删除sub匹配的子串 ${string/old/new} 在变量string中将old内容,替换成new(只替换第一个找到的) ${string//old/new} 在变量string中将old内容,替换成new(替换所有找到的内容) ${value:=word} 给变量赋默认值,LOD=${value:=word},$LOD的值为word ${value:index:len} 从index位置开始取值,向后取len长度 #变量的替换 ${value:-word} 当value定义或者为空时,返回后面的值,当value已经有值了就返回value的值,只是针对返回值,value本身仍然没有值 #例: result=${value:-word} echo $result #打印word echo $value #打印空 ${value:=word} 当value定义或者为空时,返回后面的值,value的值也会改变,当value已经有值了就返回value的值,#例: result=${value:=word} echo $result #打印word echo $value #打印word ${value:?”not default”} 如果变量名存在且非空,则返回变量的值,否则显示“变量名:message“,并退出当前脚本 #例: [[email?protected] zy]# ${key:?"not default"} #打印 -bash: key: not default ${value:+word} 如果变量存在且不为空,则返回后面的值,否则返回null。用于测试变量是否存在 #例: [[email?protected] zy]# echo ${result:+word} #打印:word(已定义) [[email?protected] zy]# echo ${key:+word} #打印 空 (未定义) ${result-value} 与${value:-word}相同 这里给大家介绍一个具体的例子看看,变量操作的重要意义: #将某目录下的所有.jpg的文件改成,以.JPG的结尾 #方法一: for i in `ls *.jpg`;do mv $i ${i/%jpg/JPG} ; done; #方法二: rename .jpg .JPG * #计算变量的长度 #方法一: [[email?protected] zy]# echo ${#chars} #方法二: [[email?protected] zy]# echo $chars|wc –c #会多打印末尾的换行 #方法三: [[email?protected] zy]# echo $(expr length "$chars") #方法四: echo $value|awk -F’’ ‘BEFORE{count=0} {count++} END{print count}’ 看似不使用变量操作,就可以使用命令解决我们的问题,但是执行的效率呢? 同样的可以查看上面所有的方法的执行时间,一对比,就只到变量操作的强大体现在哪里。这里小编给大家总结一下(以前三种方法为例):方法一>方法三>方法二 #最终使用内置的功能效率最高 四、shell中通用常用命令介绍(1)echo命令???对于这个命令大家可能熟悉的不能再熟悉了,将指定内容显示到标准输出。
(2)eval命令???读入参数,将他们组成一个新命令执行
(3)exec命令???当shell执行到exec语句时,不会去创建新的子进程,而是转去执行命令,当指定的命令执行完成后,shell就结束了,所以exec后的命令不会执行。 #脚本 #!/bin/sh echo "before exec" exec echo "exec run" echo "after exec" 结果exec 语句之后的命令就不会执行了,而且退出了当前的shell (4)export命令???将申明的变量导出,成为全局变量。 (5)read命令???从标准输出中读取字符串,传递给变量. #介绍: -p 设置提示信息,例:read –p “请输入:” value -t time(second),设置超时时间。例:read –t 3 –p“请输入胡” value (6)shift命令???shift语句按如下方式重命名所有的位置变量,如,$2变成$1,$3变成$2…,即在程序中每使用一次shift命令,都使得所有的位置信息依次向左移动一个位置。$#也会依次减少,直到为0 #!/bin/sh # script-name : test.sh echo $# shift echo $# shift echo $# shift
(7)exit命令???表示退出当前的shell脚本,后面可接参数,0:表示正常退出,非零表示异常退出。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |