zoukankan      html  css  js  c++  java
  • shell入门基础 

    shell入门基础  
    1.建立和运行shell程序
    什么是shell程序呢? 简单的说shell程序就是一个包含若干行
    shell或者linux命令的文件.
    象编写高级语言的程序一样,编写一个shell程序需要一个文本编辑器.如VI等.
    在文本编辑环境下,依据shell的语法规则,输入一些shell/linux命令行,形成一个完整
    的程序文件.
    执行shell程序文件有三种方法
    (1)#chmod +x file
    (2)#sh file
    (3)# . file
    在编写shell时,第一行一定要指明系统需要那种shell解释你的shell程序,如:#! /bin/bash,
    #! /bin/csh,/bin/tcsh,还是#! /bin/pdksh .
    2.shell中的变量
    (1)常用系统变量
    $# :保存程序命令行参数的数目
    $? :保存前一个命令的返回码
    $0 :保存程序名
    $* :以("$1 $2...")的形式保存所有输入的命令行参数
    $@ :以("$1""$2"...)的形式保存所有输入的命令行参数
    (2)定义变量
    shell语言是非类型的解释型语言,不象用C++/JAVA语言编程时需要事先声明变量.给一
    个变量赋值,实际上就是定义了变量.
    在linux支持的所有shell中,都可以用赋值符号(=)为变量赋值.
    如:
    abc=9 (bash/pdksh不能在等号两侧留下空格 )
    set abc = 9 (tcsh/csh)
    由于shell程序的变量是无类型的,所以用户可以使用同一个变量时而存放字符时而存放
    整数.
    如:
    name=abc (bash/pdksh)
    set name = abc (tcsh)
    在变量赋值之后,只需在变量前面加一个$去引用.
    如:
    echo $abc
    (3)位置变量
    当运行一个支持多个命令行参数的shell程序时,这些变量的值将分别存放在位置变量里.
    其中第一个参数存放在位置变量1,第二个参数存放在位置变量2,依次类推...,shell保留
    这些变量,不允许用户以令外的方式定义他们.同别的变量,用$符号引用他们.

    3.shell中引号的使用方法
    shell使用引号(单引号/双引号)和反斜线("\")用于向shell解释器屏蔽一些特殊字符.
    反引号(")对shell则有特殊意义.
    如:
    abc="how are you" (bash/pdksh)
    set abc = "how are you" (tcsh)
    这个命令行把三个单词组成的字符串how are you作为一个整体赋值给变量abc.
    abc1='@LOGNAME,how are you!' (bash/pdksh)
    set abc1='$LOGNAME,how are you!' (tcsh)
    abc2="$LOGNAME,how are you!" (bash/pdksh)
    set abc2="$LOGNAME,how are you!" (tcsh)
    LOGNAME变量是保存当前用户名的shell变量,假设他的当前值是:wang.执行完两条命令后,
    abc1的内容是:$LOGNAME, how are you!.而abc2的内容是;wang, how are you!.
    象单引号一样,反斜线也能屏蔽所有特殊字符.但是他一次只能屏蔽一个字符.而不能屏蔽
    一组字符.
    反引号的功能不同于以上的三种符号.他不具有屏蔽特殊字符的功能.但是可以通过他将
    一个命令的运行结果传递给另外一个命令.
    如:
    contents=`ls` (bash/pdksh)
    set contents = `ls` (tcsh)
    4.shell程序中的test命令
    在bash/pdksh中,命令test用于计算一个条件表达式的值.他们经常在条件语句和循环
    语句中被用来判断某些条件是否满足.
    test命令的语法格式:
    test expression
    或者
    [expression]

    在test命令中,可以使用很多shell的内部操作符.这些操作符介绍如下:
    (1)字符串操作符 用于计算字符串表达式
    test命令 | 含义
    -----------------------------------------
    Str1 = str2 | 当str1与str2相同时,返回True
    Str1! = str2| 当str1与str2不同时,返回True
    Str | 当str不是空字符时,返回True
    -n str | 当str的长度大于0时,返回True
    -z str | 当str的长度是0时,返回True
    -----------------------------------------
    (2)整数操作符具有和字符操作符类似的功能.只是他们的操作是针对整数
    test表达式 | 含义
    ---------------------------------------------
    Int1 -eq int2|当int1等于int2时,返回True
    Int1 -ge int2|当int1大于/等于int2时,返回True
    Int1 -le int2|当int1小于/等于int2时,返回True
    Int1 -gt int2|当int1大于int2时,返回True
    Int1 -ne int2|当int1不等于int2时,返回True
    -----------------------------------------
    (3)用于文件操作的操作符,他们能检查:文件是否存在,文件类型等
    test表达式 | 含义
    ------------------------------------------------
    -d file |当file是一个目录时,返回 True
    -f file |当file是一个普通文件时,返回 True
    -r file |当file是一个刻读文件时,返回 True
    -s file |当file文件长度大于0时,返回 True
    -w file |当file是一个可写文件时,返回 True
    -x file |当file是一个可执行文件时,返回 True
    ------------------------------------------------
    (4)shell的逻辑操作符用于修饰/连接包含整数,字符串,文件操作符的表达式
    test表达式 | 含义
    ----------------------------------------------------------
    ! expr |当expr的值是False时,返回True
    Expr1 -a expr2|当expr1,expr2值同为True时,返回True
    Expr1 -o expr2|当expr1,expr2的值至少有一个为True时,返回True
    -----------------------------------------------------------
    注意:
    tcsh shell 不使用test命令,但是tcsh中的表达式同样能承担相同的功能.tcsh
    支持的表达式于C中的表达式相同.通常使用在if和while命令中.
    tcsh表达式 | 含义
    -------------------------------------------------------
    Int1 <= int2 |当int1小于/等于int2时,返回True
    Int1 >= int2 |当int1大于/等于int2时,返回True
    Int1 < int2 |当int1小于int2时,返回True
    Int1 > int2 |当int1大于int2时,返回True
    Str1 == str2 |当str1与str2相同时,返回True
    Str1 != str2 |当str1与str2不同时,返回True
    -r file |当file是一个可读文件时,返回True
    -w file |当file是一个可写文件时,返回True
    -x file |当file是一个可执行文件时,返回True
    -e file |当file存在时,返回True
    -o file |当file文件的所有者是当前用户时,返回True
    -z file |当file长度为0时,返回True
    -f file |当file是一个普通文件时,返回True
    -d file |当file是一个目录时,返回True
    Exp1 || exp2 |当exp1和exp2的值至少一个为True时,返回True
    Exp1 && exp2 |当exp1和exp2的值同为True时,返回True
    ! exp |当exp的值为False时,返回True
    5.条件语句
    同其他高级语言程序一样,复杂的shell程序中经常使用到分支和循环控制结构,
    bash,pdksh和tcsh分别都有两种不同形式的条件语句:if语句和case语句.
    (1)if语句
    语法格式:
    bash/pdksh用法:
    if [expression1]
    then
    commands1
    elif [expression2]
    commands2
    else
    commands3
    if

    tcsh用法:
    if (expression1) then
    commands1
    else if (expression2) then
    commands2
    else
    commands3
    endif

    含义:当expression1的条件为True时,shell执行then后面的commands1命令;当
    expression1的条件为false并且expression2的条件满足为True时,shell执行
    commands2命令;当expression1和expressin2的条件值同为false时,shell执行
    commands3命令.if语句以他的反写fi结尾.

    (2)case语句
    case语句要求shell将一个字符串S与一组字符串模式P1,P2,...,Pn比较,当S与
    某个模式Pi想匹配时,就执行相应的那一部分程序/命令.shell的case语句中字符
    模式里可以包含象*这样的通配符.
    语法格式:
    bash/pdksh用法:
    case string1 in
    str1)
    commands1;;
    str2)
    commands2;;
    *)
    commands3;;
    esac

    tcsh用法:
    switch (string1)
    case str1:
    statements1
    breaksw
    case str2:
    statements2
    breaksw
    default:
    statements3
    breaksw
    endsw

    含义:shell将字符串string1分别和字符串模式str1和str2比较.如果string1与str1匹配,则
    shell执行commands1的命令/语句;如果string11和str2匹配,则shell执行commands2的命令/
    语句.否则shell将执行commands3的那段程序/命令.其中,每个分支的程序/命令都要以两个
    分号(;;)结束.

    6.循环语句
    当需要重复的某些操作时,就要用到循环语句.

    (1)for语句
    大家知道在很多编程语言中for语句是最常见.在shell中也不例外.for语句要求shell将包含
    在这个语句中的一组命令连续执行一定的次数.
    语法格式:
    bash/pdksh
    用法1:
    for var1 in list
    do
    commands
    done
    含义:在这个for语句中,对应于list中的每个值,shell将执行一次commands代表的一组命令.
    在整个循环的每一次执行中,变量var1将依此取list中的不同的值.
    用法2:
    for var1
    do
    setatements
    done
    含义:在这个for语句中,shell针对变量var1中的每一项分别执行一次statements代表的一组
    命令.当使用这种形式的语句时,shell认为var1变量中包含了所有的位置变量,而位置变量中
    存放着程序的命令行参数值.也就是说,他等价于下列形式:
    for var1 in " $@"
    do
    statements
    done

    tcsh用法:
    在tcsh中没有for这个单词,与for语句起同样功能的是foreach语句
    foreach name (list)
    commands
    end

    举例:
    for file ;bash/pdksh
    do
    tr a-z A-Z<$file>file.caps
    done

    # ;tcsh
    foreach file ( $ * )
    tr a-z A-Z<$file>$file.caps
    end


    (2)while语句
    while语句是shell提供的另一种循环语句. while语句指定一个表达式和一组命令.这个
    语句使得shell重复执行一组命令,直到表达式的值为False为止.
    语法格式:
    while expression  
    do
    statements
    done

    while (expression) ;tcsh
    statements
    end
    举例:
    count=1 ;bash
    while [ -n "$ *"] ***
    do
    echo "this is a parameter number $count $1"
    shift
    count='expr $count + 1'
    done

    set count = 1 ;tcsh
    while ( " $ * " ! = "")
    echo "this is a parameter number $count $1"
    shift
    set count = 'expr $count + 1'
    end

    语句中shift命令的功能是将所有的命令行参数依次相左传递.

    (3)until语句
    until与while语句具有类似的语法格式和功能,不同的是while中expression的值为True时,
    shell执行命令组;而until中当expression的值为False时,shell才执行那组命令.
    语法格式:
    until expression
    do
    commands
    done
    举例:
    count=1
    until [ -z " $ * "] ***
    echo "this is a parameter number $count $1"
    shift
    count='expr $count + 1'
    done
    情注意上述例子中带***号.在while中的表达式: -n string,他的含义是当string不是空
    字符串时,表达式的值为True;在until中的表达式: -z string,他的 含义是当string是空
    字符串时,表达式的值为True.由此可见,两个程序对条件表达式的设置恰好是相反的.

    (4)shift语句
    bash和tcsh都支持shift命令.shift将存放在位置变量中的命令行参数,依次向左传递.例如
    位置变量当前值为:
    $1=file1 $2=file2 $3=file3
    执行一次shift命令后,位置变量的值为:
    $1=file2 $2=file3
    还可以在shift命令中指定位置变量转移的次数, 如:
    shift n
    例子:
    while [ "$1"]
    do
    if [ "$1"="-i"] then
    infile=" $2"
    shift 2
    else if [ "$1"="-o"] then
    outfile="$2"
    shift 2
    else
    echo "Program $0 does not recognize option $1"
    fi
    done
    tr a-z A-Z<$infile>$outfile

    (5)select语句
    select语句是pdksh提供的一个独特的循环语句.他不同于前面介绍的循环语句.他不是
    反复计算一个条件表达式,并依据表达式的值决定是否执行一组命令.select的功能是自动的
    生成一个简单的文本菜单.
    语法格式:
    select menu [in list_of_items]
    do
    commands
    done
    含义:当执行一个select语句时,pdksh分别为每个列在list_of_items中的成员建立一个菜单
    选项.list_of_items既可以是一个包含多个选项的变量,也可以是直接列在程序中的一组选项
    .如果语句中没有提供list_of_items,select语句将使用位置变量作为list_of_items.
    举例:
    select menuitem in pick1 pick2 pick3
    do
    echo "are you sure you want to pick $menuitem"
    read res ;接收用户的输入,并且将输入的值存放在特定变量里.
    if [ $res=" y" -o $res=" Y"]
    then
    break ;用于退出while,for,select等循环语句
    fi
    done
    (6)repeat语句
    repeat语句是tcsh提供的独有的循环语句.使用repeat命令要求shell对一个命令执行一定
    的次数.
    语法格式:
    repeat count command
    如;
    foreach num ( $ *)
    repeat $num echo -n " *"
    echo " "
    end

    7.shell中的函数
    shell允许用户定义自己的函数.函数是高级语言中的重要结构.shell中的函数于C或者其他
    语言中定义的函数一样.与从头开始,一行一行地写程序相比,使用函数主要好处是有利于组织
    整个程序.在bash中,一个函数的语法格式如下:
    fname (){
    shell comands
    }
    定义好函数后,需要在程序中调用他们.bash中调用函数的格式:
    fname [parm1 parm2 parm3...]
    调用函数时,可以向函数传递任意多个参数.函数将这些参数看做是存放他的命令行参数的
    位置变量.
    举例:
    这个程序定义了4个函数:
    upper ():将传递给他的文件中的字母转换成大写,并存放到同名的结尾为.out的文件中.
    lower ():将传递给他的文件里的字母转换成小写,并存放到同名的结尾为.out的文件中.
    print ():输出传递给他的文件的内容.
    usage_error ():输出程序的帮助信息.
    程序的主模块是个case条件语句,他根据命令行中第一个参数,决定程序要完成的功能,并调用相应
    的函数完成这一功能.
    upper (){
    shift
    for i
    do
    tr a-a A-Z<$!>$1.out
    rm $1
    mv $1.out $1
    shift
    done; }
    lower () {
    shift
    for i
    do
    tr A-Z a-z<$1>$1.out
    rm $1
    mv $1.out $1
    shift
    done; }
    print() {
    shift
    for i
    do
    lpr $1
    shift
    done; }
    usage_error() {
    echo " $1 syntax is $1"
    echo ""
    echo " where option is one of the following"
    echo " p--to print frame files"
    echo " u--to save as uppercase"
    echo " l--to save as lowercase";}
    case $1 in
    p | -p)print $@;;
    u | -u)upper $@;;
    l | -l)lower $@;;
    *) usage_error $0;;
    esac

    ------------------------------------------------------------------------------
    总结
    利用shell编程是提高系统管理工作效率的重要手段,学好shell跟了解系统基本命令和管理
    工具的使用方法同样重要!

    附:
    A.bash中常用的命令
    命令 | 含义
    -------------------------------------------------------------------------------
    Alias |设置命令别名
    Bg |将一个被挂起的进程在后台执行
    cd |改变用户的当前目录
    exit |终止一个shell
    export |使作为这个命令的参数的变量及其当前值,在当前运行的shell的子进程中可见
    fc |编辑当前的命令行历史列表
    fg |让一个被挂起的进程在前台执行
    help |显示bash内部命令的帮助信息
    history |显示最近输入的一定数量的命令行
    kill |终止一个进程
    pwd |显示用户当前工作目录
    unalias |删除命令行别名
    --------------------------------------------------------------------------------

    B.bash中常用的系统变量
    变量 | 含义
    -------------------------------------------------------------------------------
    EDITOR,FCEDIT |Bash的fc命令的默认文本编辑器
    HISTFILE |规定存放最近输入命令行文件的名字
    HISTSIZE |规定命令行历史文件的大小
    HOME |当前用户的宿主目录
    OLDPWD |用户使用的前一个目录
    PATH |规定bash寻找可执行文件时搜索的路径
    PS1 |命令行环境中显示第一级提示符号
    PS2 |命令行环境中显示第二级提示符号
    PWD |用户当前工作目录
    SECONDS |当前运行的bash进程的运行时间(以秒为单位)

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    1.        学习提示

    学习shell主要在于用,光看书没用

    2.        单引号、双引号、括号、花括号及反引号

    单引号内所有元字符都失去特殊含义(包括\)双引号内除了变量域$和命令域`以外的元字符都失去特殊含义,所以一般使用双引号引用

    花括号{}被用来区分变量名和周围的文本:echo ${file} and $file1 寻找变量file,file1

    命令替代的格式:反引号来环绕一个命令象` cmd `,它和$(command) 是等价的:ls -l `find . -type f`

    3.        取行

    sed -n "3"p file 取第3

    sed -n "1,3"p file 取第13

    sed -n "1,$"p file 取第1到最后一行

    sed -n "1,$num"p file 取第1num

    sed -n "\$p" file 取最后1

    sed -e '1!G;h;$!d' file倒过来显示

    4.        sed 附加/替换:

    sed "/xmdh/a\daoyou" file 把含有xmdh的行的结尾附加daoyou(有换行)

    sed 's/$/ daoyou/' file把每行的结尾附加daoyou(在同一行)

    sed '/test/s/$/ daoyou/' file把包含test行的结尾附加daoyou(在同一行)

    sed '10s/$/ daoyou/' file把第10行的结尾附加daoyou(在同一行)

     

    sed "s/xmdh/daoyou/g" filexmdh替换成daoyou

    sed "s/xmdh/daoyou/;G" filexmdh替换成daoyou并增加一个换行

    cat userlog |sed -n '/xmdh/ w test.txt'查看含有xmdh并写入test.txt

    5.        搜索:

    vi file 后:/\<daoyou\>/

    6.        显示行号:

    awk '/dhshunde/{print NR,$0}' userloggrep -n dhshunde userlog 显示含有dhshunde的行号及内容

    cat userlog |sed -n ‘/erptest/=’ 显示含有erptest的行号

    cat userlog |sed -n '/xmdh/p'|sed -n '$p' 显示包含xmdh的最后一行

    7.        awk中使用变量

    /bin/cat /etc/ppp/chap-secrets|grep $5|awk '{print logouttime"\t","username:"$1"\t","logout""\t","data:"datasize}' logouttime="`/bin/date`" datasize="$size" >>$pptplogdirectory/userlog(注:size前面已经有定义)

    8.        Find的用法

    注:f i n d命令将所有匹配到的文件一起传递给e x e c执行,而x a rg s命令每次只获取一部分文件而不是全部,所以exec有长度限制,文件不能太多,否则会产生溢出错误,而xargs则没有

    find . -mtime -1 –print 跟现在小于1天修改的文件

    find . -perm 755 –print 显示具有755属性的文件

    find . -size +1000000c –print 查找大于1M的文件

    find . -type f -exec ls -l {} \; 查找文件并列表显示(注:{}\之间有空格,最后有;

    find . -type f -exec rm {} \;查找文件并删除

    find . -type f -print |xargs ls –l查看文件并列表显示

    find /  \( -perm -4000 -o -perm -2000 \) -type f –print 查找SUIDSGID文件

    9.        向登录终端用户发送消息

    echo "hello I am jiangdaoyou"|tee /dev/pts/2 (tty可以查看自已的终端号),等同于:write root pts/2然后输入:hello I am jiangdaoyou然后Ctrl+D结束

    10.   awkBEGINEND

    即在文件头增加列名:

    cat userlog |awk 'BEGIN{print "Time username\n-----------------"};{print $4,$7}'

    Time     username

    ------------------------------

    15:19:28 username:xmdh

    15:20:00 username:xmdh

    将在上面的基础上增加结尾说明“end of report!!!!

    cat userlog |awk 'BEGIN{print "Time     username\n-----------------"}{print $4,$7}END{print "end of report!!!!"}'

     

    11.   截取/转化字符

    echo "200604211031"|cut -c9-12 得到1031

    cat test.ok |tr 'arp' 'rpm' arp转为rpm

    12.   求平均值

    vmstat 1 4|awk '{print $4}'|grep -o '[0-9]*'|sed 's/,//g' |awk '{total=total+$1;if(NR%4= =0) {print total/4}}'或如下方法:

    vmstat 1 4|awk 'NR>2{sum+=$4}END{print sum/4}'

    13.   循环

    ls |for file in *;do echo "rpm -ivh" $file;done

    ls |for file in $(ls *.rpm);do echo "rpm -ivh" $file;done

    ===============================================================================

    好久没有碰shell编程了,都忘了,现在回顾一下
     
    1.变量赋值
    a=123
    read name
    b=$(ls /home) 把命令的执行结果赋值给变量
    2.使用变量(前面用$)
    echo $a
    let a=a+1
    系统变量

    CODE:
    $0 这个程序的执行名字
      $n  这个程序的第n个参数值,n=1...9
      $*  这个程序的所有参数
      $# 这个程序的参数个数
      $$ 这个程序的PID
      $! 执行上一个背景指令的PID
      $? 上一个指令的返回值
    3.if语句

    CODE:
    if [ "22" -lt "33" ]注意空格
    then
    echo "22 less than 33"
    else
    echo "no"
    fi
    4.case语句

    CODE:
    #!/bin/bash
    echo "enter a number"
    read ans
    case $ans in
    1)
    echo  "you numer is $ans"
    ;;
    2)
    echo "you number is 2"
    ;;
    [3-9])
    echo "you number is $ans"
    esac

    case语句
    case语句要求shell将一个字符串S与一组字符串模式P1,P2,...,Pn比较,当S与
    某个模式Pi想匹配时,就执行相应的那一部分程序/命令.shell的case语句中字符
    模式里可以包含象*这样的通配符.
    语法格式:
    bash用法:
    case string1 in
    str1)
    commands1;;
    str2)
    commands2;;
    *)
    commands3;;
    esac

    5.比较运算符
    运算符        描述        示例

    文件比较运算符
    -e filename         如果 filename 存在,则为真        [ -e /var/log/syslog ]
    -d filename         如果 filename 为目录,则为真        [ -d /tmp/mydir ]
    -f filename         如果 filename 为常规文件,则为真        [ -f /usr/bin/grep ]
    -L filename         如果 filename 为符号链接,则为真        [ -L /usr/bin/grep ]
    -r filename         如果 filename 可读,则为真        [ -r /var/log/syslog ]
    -w filename         如果 filename 可写,则为真        [ -w /var/mytmp.txt ]
    -x filename         如果 filename 可执行,则为真        [ -L /usr/bin/grep ]
    filename1 -nt filename2         如果 filename1 比 filename2 新,则为真        [ /tmp/install/etc/services -nt /etc/services ]
    filename1 -ot filename2         如果 filename1 比 filename2 旧,则为真        [ /boot/bzImage -ot arch/i386/boot/bzImage ]

    字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法)

    -z string         如果 string 长度为零,则为真        [ -z "$myvar" ]
    -n string         如果 string 长度非零,则为真        [ -n "$myvar" ]
    string1 = string2        如果 string1 与 string2 相同,则为真        [ "$myvar" = "one two three" ]
    string1 != string2        如果 string1 与 string2 不同,则为真        [ "$myvar" != "one two three" ]

    算术比较运算符
    num1 -eq num2        等于        [ 3 -eq $mynum ]
    num1 -ne num2        不等于        [ 3 -ne $mynum ]
    num1 -lt num2        小于        [ 3 -lt $mynum ]
    num1 -le num2        小于或等于        [ 3 -le $mynum ]
    num1 -gt num2        大于        [ 3 -gt $mynum ]
    num1 -ge num2        大于或等于        [ 3 -ge $mynum ]

    6.while语句
    语法格式:
    while expression 
    do
    statements
    done
    输出<10的基数
     

    #!/bin/bash

    i=1
    while [ $i -lt 10 ]
    do
     echo $i >> newfile
     let i=i+2
     
    done

    for循环有几种方式:
    1.for name [ in word ] ; do list ; done
    2.for (( expr1 ; expr2 ; expr3 )) ; do list ; done//注意有2层括号

    其中list简单说就是一串由操作符(operator ;、&、&&、||)分隔开的管道(pipeline)序列,详情参看man bash
    各给出一个简单例子:

    1.
    for filename in `ls`
    do
    cat $filename
    done

    2.
    for((i=0; i<10; i++))
    do
    echo $i
    done

    1.条件变量替换:
    Bash Shell可以进行变量的条件替换,既只有某种条件发生时才进行替换,替换
    条件放在{}中.
    (1) ${value:-word}
    当变量未定义或者值为空时,返回值为word的内容,否则返回变量的值.
    (2) ${value:=word}
    与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将
    word赋值给value
    (3) ${value:?message}
    若变量以赋值的话,正常替换.否则将消息message送到标准错误输出(若
    此替换出现在Shell程序中,那么该程序将终止运行)
    (4) ${value:+word}
    若变量以赋值的话,其值才用word替换,否则不进行任何替换
    (5) ${value:offset}
    ${value:offset:length}
    从变量中提取子串,这里offset和length可以是算术表达式.
    (6) ${#value}
    变量的字符个数
    (7) ${value#pattern}
    ${value##pattern}
    去掉value中与pattern相匹配的部分,条件是value的开头与pattern相匹配
    #与##的区别在于一个是最短匹配模式,一个是最长匹配模式.
    (8) ${value%pattern}
    ${value%%pattern}
    于(7)类似,只是是从value的尾部于pattern相匹配,%与%%的区别与#与##一样
    (9) ${value/pattern/string}
    ${value//pattern/string}
    进行变量内容的替换,把与pattern匹配的部分替换为string的内容,/与//的区
    别与上同

    注意:上述条件变量替换中,除(2)外,其余均不影响变量本身的值


    2.变量的算术运算
    在Bash Shell中,只能进行两个整数间的运算,其结果仍为整数.要进行算术
    运算,需要使用let命令,语法为:
    let expr
    expr是一个包含项和操作符的表达式,项可以是一个变量或是一个整数常数,
    当使用整数常数时,其默认为十进制整数,用户可以用radio#number来指定其它
    形式的整数,其中radio定义了整数是几进制表示的,number是该整数的值.若
    radio>10,那么数字字符可从0-9和A-Z.
    在表达式中支持的操作符及其含义为:
    +,-,*,/,% 加,减,乘,除,取模
    >>,<<,&,^,| 左移,右移,位与,位异或,位或
    ?: 三元运算符.与C语言中的定义一致
    ~ 取补码
    !,>=,<=,>,<,==,!=,&&,||
    =,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=
    表达式式中也可以使用括号.括号或运算优先级的定义与一般计算机语言中的
    相同.
    let命令具有返回值.当计算结果(若有多个表达式时,以最后一个为准)为0时,
    返回值为1,否则为0.
    当表达式中含有shell的特殊字符(如|)时,需要用引用符('或")将其引用起来.
    使用let时还需要注意的时,对于let x+y这样的式子,shell虽然计算了x+y的值
    但却将结果丢弃,若不想这样,可以使用let sum=x+y将x+y的结果保存在变量sum中
    另外还可以使用((和))操作符取代let命令,而且这样的话,还可以省去对算术
    表达式的引用,如果想返回表达式的值,则需用$(())的格式

    使用set命令可以设置各种shell选项或者列出shell变量.单个选项设置常用的特性.
    在某些选项之后-o参数将特殊特性打开.在某些选项之后使用+o参数将关闭某些特性,
    不带任何参数的set命令将显示shell的全部变量.除非遇到非法的选项,否则set总是
    返回ture.
    当BASH shell被调用时,可以列出全部的选项.当前的选项集列在$-中.在option参数
    被处理后,其他的参数被赋值到位置参数中($1,$2,...,$n)

    set [--abefhkmnptuvxldCHP] [-o option name] [arguments ...]


    源码:


    选项 说明
    -a 自动向已经修改的变量或为导出后序命令的变量作出标志
    -b 不是在原提示符之前,而是立即引发终止后台任务的状态表表
    -e 如果命令带非零值返回,立即退出
    -f 禁止带扩展名的路径
    -h 定义函数时,定位和存储函数命令,当函数被执行时,通常查询
    函数命令
    -k 所有的关键词参数,而不只是那些命令名前的关键词参数,被放
    在环境命令中
    -m 监视器模式,启动任务控制.此选项默认支持系统shell交互.后
    台进程以单独的进程组运行,在每次完成任务时显示包含退出的
    状态行
    -n 读取命令但不执行命令.通常监查shell脚本的句法错误.交互
    shell被忽略

    -o option-name 选项名可以是下列之一:
    选项 说明
    allexport 同-a选项
    braceexpand shell执行花括号扩展,在默认情况下起作用
    emacs 使用emacs风格命令行编辑接口.除非shell以-noline-editing
    选项启动,否则当shell交互时,通过默认启动该选项
    errexit 同-e选项
    histexpand 同-H选项
    ignoreeof 其结果是好像shell命令IGNOREEOF=10被执行
    interactive 允许单词前带#号,以使得在交互shell中忽略命令行的全部字符
    -commands
    monitor 同-m选项
    noclobber 同-C选项
    noexec 同-n选项
    noglob 同-f选项
    nohash 同-d选项
    notify 同-b选项
    nounset 同-u选项
    physical 同-p选项
    posix 改变BASH属性以匹配标准,默认操作不同于POSIX1003.2标准
    verbose 同-v选项
    vi 使用vi风格的命令行编辑器
    XTRACE 同-x选项,如果没有给出选项名,显示当前选项值
    -p 打开特权模式(在此模式,$ENV文件被处理,不能从环境中继承
    shell函数.如果是有效用户ID而不是实用户组则自动启动.关闭
    此选项将使得有效用户和组IDs设置实用户和组IDs)
    -t 在读取命令并执行之后退出
    -u 当执行参数括展时,把非设置变量作为错误处理(如果扩展企图
    出现在非设置变量中,shell显示错误信息.如果不是交互式,则
    带非凌值退出)
    -v 输入行被读取时,显示shell输入行
    -x 在每个简单命令被扩展之后,显示PS4扩展值,之后是要执行的命令
    -l 保存和恢复绑定在命令中的名称
    -d 禁止执行查找散列命令(通常,命令被保存在散列表中,一旦被找到
    就不再继续查找)
    -C 效果好像是执行了noclobber=shell命令
    -H 使用!风格的历史替代(当shell交互时,在默认情况下,此选项有效)
    -P 如果设置此参数,当执行改变目录命令cd时,不遵循符号链接,而是
    使用实际的目录
    -- 如果在选项后没有参数,不设置位置参数.否则,即使一些参数以a
    选项开始,也要把位置参数设置为argument
    - 结束选项的信号,将引发其余的参数被赋值到位置参数中(-x和-v
    选项被关闭.如果没有argument,位置参数将保留未改变的参数)


    函数

    函数的使用
    BASH 是一个相对简单的脚本语言,不过为了方便结构化的设计,BASH 中也提供了函数定义的功能。BASH 中的函数定义很简单,只要向下面这样写就可以了:
    function my_funcname {
     code block
    }

    或者

    my_funcname() {
     code block
    }

    上面的第二种写法更接近于 C 语言中的写法。BASH 中要求函数的定义必须在函数使用之前,这是和 C 语言用头文件说明函数方法的不同。

    更进一步的问题是如何给函数传递参数和获得返回值。BASH 中函数参数的定义并不需要在函数定义处就制定,而只需要在函数被调用时用 BASH 的保留变量 $1 $2 ... 来引用就可以了;BASH 的返回值可以用 return 语句来指定返回一个特定的整数,如果没有 return 语句显式的返回一个返回值,则返回值就是该函数最后一条语句执行的结果(一般为 0,如果执行失败返回错误码)。函数的返回值在调用该函数的程序体中通过 $? 保留字来获得。下面我们就来看一个用函数来计算整数平方的例子:

    #!/bin/bash

    square() {
     let "res = $1 * $1"
     return $res
    }

    square $1
    result=$?
    echo $result

    exit 0

    1.函数声明后的使用域是全局的
    (谁知道怎么声明为局部的,希望可以通知我)

    2.默认情况下变量的声明也是全局的

    3.local语句在函数内部使用作为局部变量,哪怕声明的变量是数组
    fun()
    {
       local -a test
       fun2()
       {
        test[0]=...
        test[1]=...
        }
    }

    在实际应用过程中
    无论你怎么调用,你都无法获取test数组的值

  • 相关阅读:
    开始学习编写用于 Windows SideShow 设备的小工具【转】
    Windows Mobile 6.5 Developer Tool Kit 下载
    Microsoft Security Essentials 微软免费杀毒软件下载
    SQL Server 2008 空间数据存储摘抄(SRID 点 MultiPoint LineString MultiLineString 多边形 MultiPolygon GeometryCollection)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (2)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (4)
    负载测试、压力测试和性能测试的异同
    Windows Server 2008 Vista Sidebar Gadget (侧边栏小工具) 入门开发实例
    Silverlight Tools 安装失败 解决办法
    SQL Server 2008 空间数据库 空间索引概念及创建(取自帮助)
  • 原文地址:https://www.cnblogs.com/kentyshang/p/814297.html
Copyright © 2011-2022 走看看