zoukankan      html  css  js  c++  java
  • Shell编程——基于IBM培训教程的总结

    第一章 shell基础

    1. file 命令可以查看文件类型

    2. 如果需要查看普通文件内容,使用cat命令,如果需要查看二进制文件内容,使用string命令(AIX特有命令)。

    3. 以“.”开头的文件是隐藏文件,需要使用ls -a的方式查看。

    4. 在shell脚本文件的头一行使用类似于“#!/bin/ksh”的方式来告诉当前shell使用另外一个shell来执行这个脚本。
    如果prog是一个shell脚本文件,已经使用了chmod +x prog的方式拓展了执行权限。如果当前shell是ksh,而prog首行内容是
    #!/bin/tsh
    则exec prog
    将会停止ksh并且启动tsh这个shell并执行prog

    5. 如何设置shell?没看明白!通过.profile, .exrc, $ENV等

    6.SHELL的元字符与正则表达式类似,但不完全相同。例如
    * 表示零个或者多个字符;
    ?表示一个字符;
    [abc]表示a,b,c中任意选择一个
    [!abc]表示a,b,c中一个都不选(正则是[^abc])
    [a-z]

    举例:
    ls [a-z]c.c
    上面的语句将会选择出ac.c,gc.c等

    7.SHELL特殊的元字符
    *(pattern1|pattern2) 0次或者多次触发
    例如,*([0-9]) 0个或者多个数字
    ?(pattern1|pattern2) 0次或者1次触发
    例如,?([0-9]) 0个或者1个数字
    +(pattern1|pattern2) 1次或者多次触发
    @(pattern1|pattern2) 仅仅1次触发
    !(pattern1|pattern2) 1次都不触发
    例如,!(err*|fail*)表示,不能以“err”或者"fail"开头的词

    举例:
    ls [a-z]*t[0-9]

    8. 关于引号
    i) 双引号("")
    双引号表示转平凡字符串,但是除了“$”,“`”,“\”
    例如,echo "abc`date`"

    ii)单引号('')
    相当C#中的@""效果

    iii)反斜杠(\)
    只平凡化(\)之后一个单词,例如 \`date`

    9. 关于重定向
    i) "1>" 等价于 ">" 标准输出
    "0<" 等价于 "<" 标准输入
    ls > abc.txt
    ls < abc.txt
    ii)"2>" 错误输出重定向
    ls 2> abc.txt

    10. 重定向连结
    如 ls > file 2>&1
    表示将ls标准输出输出至file,错误输出输出在标准输出上

    11. 文件描述符
    0 表示标准输入
    1 表示标准输出
    2 表示错误输出

    3-9自定义使用
    例如 exec 3> /home/lee/out (把3号文件描述符打开为文件)
    例如 exec 3> &- (把3号文件描述符关闭)

    12. pipe中的暂存功能
    例如, cat a.txt | tee b.txt | sort -r
    关键字是tee.
    上面的语句的含义是,先把a.txt中内容存储到b.txt,然后逆序排列a.txt中的内容。

    13. jobs, bg, fg

    14. 重复命令(暂存命令)
    例子:
    d=$(date)
    echo $d

    第二章 参数与引用
    1. 参数设定与取消
    # name=abc (设定)
    # unset name (取消)
    # readonly name=abc (不可unset或者改变)

    2. 引用参数
    使用“$”
    # var1=Fri
    # echo $var1 (打印Fri)
    # echo ${var1}day (Friday)

    3. 引用SHELL脚本的参数
    # abc.sh arg1 arg2
    用 $1 到 $9
    用 ${10} to ${n}

    4. 在script中用set可以转换调用参数
    print $1 $2 $3
    set apple banana
    print $1 $2 $3 // 打印出apple banana

    5. 特殊符号
    $# 位置参数个数
    $@ 用空格分割的位置参数
    $* 用指定占位符分割位置参数

    $0 命令名
    $$ 当前PID
    $! 最近背景进程的PID
    $? 最近执行语句的返回值(0表示成功)

    6. shift
    shift n
    原来的$m变成$m-n

    7. 有用的环境变量
    i) ERRNO
    ii)CDPATH
    iii)HOME
    iv) PATH
    v) ENV

    第三章 返回值与信号陷阱
    1)测试
    使用test expression语句,返回0表示expression为真(true),返回非零(false)表示为假。
    当作用在if语句中时,完全可以按照字面意思去理解。

    i) 文件测试
    test -s file
    test -r file
    ....

    ii)数字测试
    test 1 -ne 2
    test 1 -eq 2
    test 1 -lt 2
    test 1 -le 2
    test 1 -gt 2
    test 1 -ge 2

    iii) 字符串测试
    test -n str str is non-zero in length
    test -z str str is zero in length
    test str1 = str2
    test str1 != str2

    2) 与,或,非, 组合(括号的概念)
    test exp1 -a exp2 与
    test exp1 -o exp2 或
    test !exp 非

    \( exp \) 注意空格 (在shell script中也需要有斜杠“\”)
    test \( 1 -ge 2 \) -a 1

    3) 信号
    i) 发送信号
    kill -s sig pid
    ii)列出所有信号
    kill -l

    4)在shell中重定向信号处理方式
    i) 指定处理方式
    以下代码表示,当有SIGINT或者SIGQUIT信号的时候,做指定的事情
    trap ‘rm /tmp/$$’ SIGINT SIGQUIT
    ii) 忽略信号
    trap '' SIGINT SIGQUIT
    iii) 恢复信号
    trap SIGINT SIGQUIT

    第四章 跳转语句

    1) if - else - elif - fi
    例如
    if [ \( 1 -le 2 \) -a \( 2 -gt 1 \) ]
    then
    echo "hello world"
    elif [ 3 -le 4 ]
    echo "hello two"
    else
    echo "faint"
    fi

    2) 循环语句
    x=0
    while [ $x -lt 2 ]
    do
    echo $x
    let x=x+1
    done

    while true
    do
    echo "hello"
    continue
    done

    until [ $x -gt 5 ]
    do
    echo $x
    let x=x+1

    break
    done

    3) for 语句
    下面的语句将会便利所有在pwd文件夹下以单个数字作为拓展名的文件
    for file in *.[0-9]
    do
    echo $file
    done

    下面的两个语句效果相同,不过更推荐第二种写法
    for file
    do
    done

    for file in $@
    do
    done

    类似C语言的做法
    for (( num=0; num < 5; num++ ))
    do
    echo $num
    done

    4) case语句
    x=0
    case "this is $1 $x" in
    "this is 1")
    echo "hello 0";;
    "this is 1 0")
    echo "hello 1";;
    *)
    echo "hello 10";;
    esac

    case语句中还可以放置命令,例如
    case $(ls) in
    0)
    echo "hello 0";;
    1)
    echo "hello 1";;
    *)
    echo "hello 10";;
    esac

    5) select关键字
    在shell编程中,为了展示一段memu以供客户选择,可以使用select关键字,网上查吧。

    6)null语句
    当在调试时,对于一个空的if, while, for等block的处理,可以使用null语句(":")。方法是:
    if [ 1 -le 2 ]
    then
    # debug only, using null statement
    :
    else
    echo "hello"
    fi

    第五章 shell命令

    1. 从标准输入中读入内容放入变量
    #read x y z
    1 2 3
    #echo $x $y $z
    输出“1 2 3”

    关于read的相关参数
    read -a variable ;读入array,index从0开始
    例如,
    #read -a name
    Lee Lynn Llewellyn
    上面的语句将会先unset数组变量name,然后将name[0]设置为Lee,name[1]设置为Lynn,name[2]设置为Llewellyn

    read -s ;no echo模式

    read -p "string " variables ;标准输入上给出一定的提示(string),然后和不带参数的read一样。
    例如:
    read -p "here is your name " var1 var2

    注意:
    i. 如果变量少于输入,则最后一个变量将会包含后续的所有输入
    ii.如果输入少于变量,则多出来的变量就会变为空
    iii.如果没有指定变量,则bash会把变量存在$REPLY中

    2. 获取参数与开关
    有下面的这个例子
    USAGE="usage: example.getopts.sh [+-c] [-a argument] arg1 arg2 ..."

    while getopts :a:cv varflag
    do
    case $varflag in
    a) argument=$OPTARG;;
    c) compile=on;;
    +c) compile=off;;
    :) echo "you forgot an argument for the switch called a.";
    exit;;
    ?) echo "$OPTARG is not a valid switch"; echo $USAGE; exit;;
    esac
    done
    shift $(( $OPTIND - 1 ))

    上面的语句几乎包含了所有的知识点
    1) USAGE中定义的用法是 option + arguments
    2) 试用getopts方法来获取所有的option
    3) getopts第一个参数是表示你需要获取的option的种类。其中第一个":"表示你要自己来控制错误信息(例如这里的\?) ),"a"后面的“:”表示"-a"后面需要有参数。c与v后面没有“:”表示不需要有arguments
    4) [+-c]表示c这个option是可选的,而"-c"习惯上表示指定c这个option,"+c"习惯上表示不指定这个option.(bash好像不支持"+")
    5) OPTARG中保存着option之后的argument,例如-a后面的那个。
    6) OPTIND是在处理过的option的个数,通过shift OPTIND就可以跳过所有的OPTION以进入到真正的arg1,arg2等。
    7) 如果出现了没有希望处理的option(这里是"acv"之外的option),则会返回“?”

    第六章 算数操作命令
    1. let 操作符及其简写形式(( expr ))
    限制:只能够处理成整数

    a=5
    b=3
    let c=a/b d=a+b
    #上句等价于 (( c = a / b )); (( d = a + b ))
    echo $c $d #输出1 8

    特点,
    i) 速度快
    ii)变量不需要使用$
    iii) 这个语法可以用在if, while中。(这个要比之前的语法方便多了)
    p=10
    q=20
    if (( (p < q && p ==54) || ( 2 > 1 ) ))
    then
    echo "hello"
    fi

    while (( p < q ))
    do
    echo "$p"
    (( p = p + 1 ))
    done
    iv) 注意区别下面的语句(关键的区别在于“(())”返回的是变量)
    q=$(( p * 3 ))
    (( q = p * 3 ))

    2. 各种进制下的数值表示
    i) 2进制下的100 : 2#100
    ii)8进制下的33 : 8#33

    第七章 SHELL数组,命令和函数
    1. SHELL数组
    i) 数组的定义
    方法一:
    list[0]=1
    list[1]="123"
    list[3]=4

    此时,list[2]会被自动配置为null。此时,如果使用${#array[*]}的方式令其返回数组元素的个数,则会返回2。因为list[2]==null,它被认为是表示数组结束的标志。但是,如果使用${list[*]}则会返回4个值,其中list[2]返回空值。


    方法二:
    set +A list 1 "123" 2 4

    此时,整个list将会被赋予4个值。

    ii) 数组的操作
    -赋值: array[N]=argument
    -打印某个元素:echo ${array[N]}
    -遍历所有的元素,用空格隔开:${array[*]}或者${array[@]}
    -此二者等价: ${array[0]} == $array
    -数组中有多少元素:${#array[*]}或者${#array[@]}

    2. 函数
    下面是一个函数的例子

    function EmbededFunc()
    {
    echo $b #输出5,因为b在上级调用函数中的全局变量
    echo "in EmbedFunc $a" #输出3,因为a在上级调用函数中被定义
    }

    function Func()
    {
    b=5
    local a=3

    echo $1

    EmbededFunc

    return 0
    }

    Func abc

    echo “in main script $a“ # 输出空值,因为a是local的
    echo “in main script $b“ # 输出5,因为b是global

    注意:
    1) $0无论在函数内还是在函数外都表示本脚本的名字
    2) $1 - ${N},表示传输的参数
    3) 在function中可以使用“return N”的方式从func中返回一个值,或者使用“exit N”退出整个script。
    4) 没有被指定为local的变量都是全局变量,也就是在此定义之外的所有地方都会有用到。
    5) 被定义为local或者typeset的变量是局部变量,出了作用域就没有作用了。
    6) 可以强行使用"unset -f function_name"的方式将函数从内存中卸除。
    7) 上级函数中定义的local对于其调用的函数都是全局变量。


    3. alias —— linux shell的#define
    例如,在shell中,打命令alias,看到常用命令的别名。
    -自定义alias:
    alias px="echo $x"
    -使用alias
    x=100
    px
    -撤销alias
    unalias px

    第八章 SHELL变量(续)
    1. 子字符串
    1) 截取要求中的“最左”与“最右”
    注意:pattern只能是从最左开始匹配,如果不包含第一个字符,那么就不能工作。
    ${variable#pattern} - 截去从最左开始匹配的最短符合pattern的子串
    ${variable##pattern} - 截去从最左开始匹配的最长符合pattern的子串

    ${variable%pattern} - 截去从最右开始匹配的最长符合pattern的子串
    ${variable%%pattern} - 截去从最右开始匹配的最长符合pattern的子串

    例如:
    variable="Now is the time"
    echo ${variable} // 打印出 Now is the time
    echo ${variable#N*i} // 打印出 s the time
    echo ${variable##N*i} // 打印出 me
    echo ${variable%time} // 打印出 Now is the
    echo ${variable%%t*e} // 打印出 Now is

    再例如
    echo ${1#*\} 表示了找到第一个参数所表示的文件全路径的文件名

    2)子串
    语法:${variable:offset:length}
    例如:
    var="hello"
    var=${var:3:2}
    echo $var //打印出 "lo"

    2. 变量长度
    例如,找到var变量所包含的长度
    ${#var}

    3. 替换
    语法:${variable/pattern/newpattern}
    将variable中第一个匹配的pattern替换为newpattern
    例如:
    var="hello world"
    var=${var/l/X}
    echo $var # 输出 heXlo world

    语法:${variable//pattern/newpattern}
    将variable中所有匹配的pattern替换为newpattern
    例如:
    var="hello world"
    var=${var//l/X}
    echo $var # 输出 heXXo worXd

    第八章 SHELL变量(续)
    1. 子字符串
    1) 截取要求中的“最左”与“最右”
    注意:pattern只能是从最左开始匹配,如果不包含第一个字符,那么就不能工作。
    ${variable#pattern} - 截去从最左开始匹配的最短符合pattern的子串
    ${variable##pattern} - 截去从最左开始匹配的最长符合pattern的子串

    ${variable%pattern} - 截去从最右开始匹配的最长符合pattern的子串
    ${variable%%pattern} - 截去从最右开始匹配的最长符合pattern的子串

    例如:
    variable="Now is the time"
    echo ${variable} // 打印出 Now is the time
    echo ${variable#N*i} // 打印出 s the time
    echo ${variable##N*i} // 打印出 me
    echo ${variable%time} // 打印出 Now is the
    echo ${variable%%t*e} // 打印出 Now is

    再例如
    echo ${1#*\} 表示了找到第一个参数所表示的文件全路径的文件名

    2)子串
    语法:${variable:offset:length}
    例如:
    var="hello"
    var=${var:3:2}
    echo $var //打印出 "lo"

    2. 变量长度
    例如,找到var变量所包含的长度
    ${#var}

    3. 替换
    语法:${variable/pattern/newpattern}
    将variable中第一个匹配的pattern替换为newpattern
    例如:
    var="hello world"
    var=${var/l/X}
    echo $var # 输出 heXlo world

    语法:${variable//pattern/newpattern}
    将variable中所有匹配的pattern替换为newpattern
    例如:
    var="hello world"
    var=${var//l/X}
    echo $var # 输出 heXXo worXd

    第十章 使用sed处理字符串
    sed是stream editor的简称。它可以处理字符串(从标准输入或者从指定文件中)的替换,append, insert以及change。

  • 相关阅读:
    关于service相关知识的认识
    如何在service实现弹出对话框
    NDK编程jni学习入门,声明native方法,使其作为java与c的交互接口
    js事件
    es6箭头函数
    es6展开运算符
    es6 解构赋值
    js 函数的this指向
    js函数作用域
    js 预解析以及变量的提升
  • 原文地址:https://www.cnblogs.com/aicro/p/3023535.html
Copyright © 2011-2022 走看看