SHELL编程笔记

1 普通变量

      略

2 系统专用变量

shell在初始化的时候会在执行profile等初始化脚本,脚本中定义了一些环境变量,这些变量会在创建子进程时传递给子进程。

用env命令可以查看当前的环境变量。常用的系统环境变量如下:

_(下划线) 上一条命令的最后一个参数

变量名称

描述

$UID

 展开为当前用户的用户ID,在shell启动时初始化

$HOME

 

$USER

当前用户

$TMOUT

在无操作情况下的超时时间【秒】

$PATH

 

$GROUPS

当前用户所属的组

$BASH

展开为调用bash实例时使用的全路径名

$CDPATH 

 

$SHELLOPTS

包含一列开启的shell选项,比如braceexpand、hashall、monitor等

$SHELL

当调用shell时,它扫描环境变量以寻找该名字。shell给PATH、PS1、PS2、MAILCHECK和IFS设置默认值。HOME和MAIL由login(1)设置 

PS1

主提示符串,默认值是$

PS2

次提示符串,默认值是>

PS3

与select命令一起使用的选择提示符串,默认值是#?

PS4

当开启追踪时使用的调试提示符串,默认值是+。追踪可以用set –x开启

EUID

展开为在shell启动时被初始化的当前用户的有效ID

HISTFILE 

指定保存命令行历史的文件。默认值是~/.bash_history。如果被复位,交互式shell退出时将不保存命令行历史

HISTSIZE

记录在命令行历史文件中的命令数。默认是500

  
  
  

3 命令作为变量

3.1 反引号``的方式

        cmd=`date`

  3.2 $(cmd)的形式

        cmd=$(date)

4 特殊变量

   $0:获取当前执行shell脚本的文件名,包含脚本的路径

$n:获取执行当前脚本的第n个参数n=1..9 ,如果需要获取大于10的参数那么需要用{}比如${10}

$#:获取执行脚本传递过来的参数个数 (如上图所示)

$*:获取当前shell的所有参数,将所有的命令行参数视为当个字符串,相当于“$1$2$3......”

$@:获取当前shell的所有参数,将每个参数视为独立的字符串

$?:当前shell进程中,上一个命令的返回值,如果上一个命令成功执行则$?的值为0,否则为其他非零值,常用做if语句条件

$?返回值参考:

  

返回码

描述

0

表示执行成功

1

表示权限不够

2~125

表示运行失败,脚本命令,系统命令错误或参数传递错误

126

找到该命令,但是无法执行

127

未找到要执行的命令

>128

命令被系统强制结束

    $$:当前shell进程的pid

    $!:上一个指令的pid

    $-:显示shell使用的当前选项

    $_:之前命令的最后一个参数

 

   $* 和$@ 案例:

         设置参数:

         set -- "i am " hunan hailong

         查看参数个数:$#

 for i in $*; do echo $i ; done

         $*没有带引号,程序会将$*分别打印出来【并且会解析”i am“】

for i in $@; do echo $i ; done

 从以上结果可以看出 在没有双引号的情况下$@和$*的效果是一样的

       for i in "$*"; do echo $i ; done

       带有双引号的$* 会将所有数据当成当个字符串

   for i in "$@"; do echo $i ; done

        带有双引号的$@ 会将所有数据当成当个字符串,并且如果没有in 默认情况下是"$@" 

        即:for i 等价于 for i in "$@"

 $* 和$@总结:

         1 如果$*和$@带引号的话,那么$* 会把所有的参数当做一个字符串,而$@会认为是多个参数

5 变量子串的常用操作

    常用操作如下表:

表达式

说明

${#string}

返回$string的长度

${string:position}

在$string中,从位置$postion之后开始提取子串

${string:position:length}

在$string中,从位置$postion之后开始提取长度为$length的字串

${string#substring}

从变量$string开头开始删除最短匹配$substring子串

${string##substring}

从变量$string开头开始删除最长匹配$substring子串

${string%substring}

从变量$string结尾开始删除最短匹配$substring子串

${string%%substring}

从变量$string结尾开始删除最长匹配$substring子串

${string/substring/replace}

使用$replace,来替换第一个匹配的$substring

${string/#substring/replace}

如果$string前缀匹配$substring,就使用$replace来替代匹配的$substring

${string/%substring/replace}

如果$string后缀匹配$substring,就使用$replace来替代匹配的$substring

    举例说明:

     定义一个变量内容为:name="i am hailong"

     返回name的长度

提取字符串:

6 其他变量的替换

      交替变量替换表:

      

运算符号

替换

${value:-word}

如果变量名存在且为非null,则返回变量的值,否则返回word字符串。

用途:如果变量不存在,则返回默认值

${value:=word}

如果变量名存在且为非null,则返回变量的值,否则设置这个变量值为word,并返回其值

${value:?"not defined"

如果变量名存在且为非null,则返回变量的值,否则显示变量名:message,并退出当前的命令或者脚本

${value:+word}

如果变量名存在且为非null,则返回变量的值,否则返回null

用途:测试变量是否存在

     

7 变量耗时对比

    获取字符串长度的三种方法

    name="yuanhailong"

      1 echo ${#name}

      2 echo $name | wc -m

      3 echo ${expr length "$name"}

      

       利用time命令检查耗时:

        生成数据:

  ${#chars}

         time for i in $(seq 11111);do count=${#chars};done;

 wc -m

        time for i in $(seq 11111);do count=`echo ${chars} | wc -m`; done;

expr length "$chars"

        time for i in $(seq 11111);do count=`expr length "$chars"`; done;

从以上结果对比中可以看出  ${#chars}效率要比其他两种方式高出几十倍甚至上百倍。

8 变量的数值计算

     变量的数值计算常用有以下几个命令:

      (())    let     expr    bc    $[]

let和(())是一样的 但是let的效率比(())低

小案例:

    利用expr 判断判断是否为整数

bc命令的用法:

  bc是unix下的计算器,他可以用在命令行下面:


 

计算器

判断字符串是否为数字的多种方法

 

 

-z -n -o -a的含义

 

-z 表示字符串为null,即指定字符串长度为0

-n 表示字符串不为null

-o 表示两个表达式中只要一个一个成立就为真

-a 表示两个表达式中都要真才返回真

 


 

9 条件测试

    条件测试语法:

    在basha的各种流程控制结构中通常需要进行各种测试,然后根据测试执行不同的操作,有事也会通过与if等条件语句相结合,使我们可以方便的完成判断。

    【语法说明】

      格式1: test <测试表达式>

      格式2: [<测试表达式>]

      格式3:[[测试表达式]]

      说明:

      格式1和格式2是等价的。

      格式3为扩展的test命令。

 

      提示:

        在[[]]中可以使用通配符进行模式匹配。 && ,||,>,<等操作符可以应用于[[]]中,但是不能应用于[]中。

        对整数进行关系运算,也可以使用shell运算符(())

        对test<>进行测试

        test -f file && echo true || echo false

利用!可以对结果取反

        test ! -f file && echo true || echo false

  对[]进行测试

        [ -f file ] && echo true || echo false

        取反

         [ ! -f file ] && echo true || echo false


 

对[[]]进行测试

        [[ -f file ]] && echo true || echo false

 文件测试操作符

            在书写测试表达式的时,可以使用下表中的文件操作符

            

常用文件操作符号

说明

-f 文件

若文件存在且为普通文件则为真

-d 文件

若文件存在且为目录则为真

-s 文件

若文件存在且不为空(文件大小大于0)则为真

-e 文件

若文件存在则为真(注意和-f的区别)

-r 文件

若文件存在且可读则为真

-w 文件

若文件存在且可读则为真

-x 文件

若文件存在且可执行则为真

-L 文件

若文件存在且为链接文件则为真

f1 -nt f2

若文件f1比f2要新则为真

f1 -ot f2

若文件f1比f2要旧则为真

 

   字符串测试操作符 

         字符串测试操作符的作用是:比较两个字符串是否相同,字符串长度是否为0,字符串是否为null(注:bash区分零长度字符串和空字符串)等

          “=”比较2个字符串是否相等,与==等价, 如[ “$a”=="$b" ] ,其中$a这样的变量最好用""括起来,因为中间有空格,*等符号就可能出错了,当然更好的方法是[ "${a}"="${b}" ] "!=" 比较两个字符串是否相同,不同则为“是”

             在书写表达式时,可以使用下表的操作符:

            

常用字符串测试字符

说明

-z "字符串"

若长度为0则为真, -z 可以理解为zero

-n "字符串"

若长度不为0则为真,和-z相反

"串1"="串2"

若串1等于串2 则为真,可以使用"=="替代"="

"串1"="串2"

若串1不等于串2 则为真

特别注意:以上表格中的字符串测试操作符号务必用""引起来

 

整数二元比较操作符

在[]使用比较符

在(())和[[]]中使用比较符

说明

-eq

==

equal的缩写,相等

-ne

!=

not equal的缩写,不相等

-gt

>

大于

-ge

>=

大于等于

-lt

<

小于

-le

<=

小于等于

提示:

       1) “<”意思是小于,if[[ "$a" < "$b" ]],if[ "$a" \< "$b" ] 在[]中需要转义,因为在shell中<也用<和>重定向

       2) ">"  意思是小于,if[[ "$a" > "$b" ]],if[ "$a" \> "$b" ] 在[]中需要转义,因为在shell中<也用<和>重定向  

       3) "=" 意思是等于 ,if[[ "$a" = "$b" ]],if[ "$a" = "$b" ] 在[]中不需要转义

 

       经过实践,“=”和“!=”在[]中不需要转义,但是">"和"<"在[]中需要使用转义符,对于数字不使用转义符未必会报错,但是结果可能会不对
 

逻辑操作符

在[]使用逻辑操作符

在(())和[[]]中使用逻辑操作符

说明

-a

&&

-o

||

10分支域循环结构

注: 如果 [条件]和then在一行需要用分号 如果不在一行不需要分号

case语句

        语法

        case "字符串变量" in 

                value1) 指令

                   ..........

                ;;

               value2) 指令 

                    ........

                ;;

                *) 指令

                    ,.,.....

        esac

     加颜色


  提示:while循环是条件满足才回执行,until循环是直到条件满足就退出

            案例


11 shell中的函数

    语法:

        func_name () {

            ......

        }

        或者

        function func_name(){

            .......

        } 

 

    函数调用

        1 func_name   #注意调用函数的时候不要带() 可以考虑下和python或java有什么区别

        2 func_name 参数1 参数2 .....

        【带参数函数说明】

           1) 在函数体中参数位置($1,$2,$3..... $#,$? 等) 都可以是函数的参数

           2) 父脚本的参数则临时的被函数参数所覆盖

           3) $0比较特殊,它依旧是父脚本的参数

           4) 当函数完成时,原来的命令行参数会恢复

           5) 在shell函数里面,return和exit是一样的,用于跳出循环

           6) 在shell函数里面,exit会使得整个shell脚本种植

           7) return 语句会返回一个退出之给调用程序

 

        函数练习:

函数和执行体分离

        1 创建一个名叫做hailong_fun.sh脚本 里面包含如下:

  2 给hailong_fun.sh赋予执行权限

  3 编写调用函数 比如fun.sh

4 调用


 

12 shell数组

    数组介绍

        简单来说,数组就是相同数据类型的元素按一定顺序排列的集合。

        数组就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们区分他们的变量的集合。这个名字成为数组名,编号成为下标。组成数组的各个变量成为数组的分量,也成为数组的元素,有事也成为下表变量。

        如果有过其他语言编程经历,那么想必会熟悉数组的概念。由于有了数组,可以用相同的名字引用一系列的变量,并用数字(索引)来识别他们。在许多场合,使用数组可以缩短和简化程序,因为可以利用索引设计一个循环,高校处理多种情况

     数组定义和读取

            方法1:array=(value1 value2 value3 ....)   【元素之间用空格分割】

打印数组元素

            echo ${array[1]}

数组赋值

array[3]=4

数组的删除

直接通过 unset array[index]可以删除数据

数组的截取和替换

  数组实战案例

        1 将当前目录下的文件用数组的方式打印

2 检查URL脚本

13 shell脚本的调试  


 

  提示:你检查脚本明明没有问题,但就是执行出现莫名其妙的语法错误,要想到执行dos2unix格式化一下。

 

14 Shell开发环境的配置和优化

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值