• 回顾了下shell 编程的一些细节


    回顾了一些细节

    shell 的通配符扩展
     
    ?
    [] 
    [^xxxx] 
    {aaa,bbb}      
     

    子进程
    more `grep -l POSIX *`
    more $(grep -l POSIX *)
     

     
    shell 变量的一些特性
     
    赋值直接用变量名,获取内容需要加$
    salutation=Hello
    echo $salutation
     
    读取输入
    read salutation
     
    关于shell 中的引号
    #!/bin/bash
    myvar="Hi there"
    echo $myvar
    echo "$myvar"
    echo '$myvar'
    echo $myvar
     

    shell 中的预定义变量
     
    环境变量的概念:
        程序执行时,一些变量会根据环境设置中的值来进行初始化
    $HOME
    $PATH
    $PS1
    $PS2
    $IFS            输入域分隔符,shell读取输入时分割单词的字符
    $0            shell 脚本的名字
    $#            传给脚本的参数个数
    $$             shell脚本的进程号
    $1 $2            第几个参数
    $*                所有参数
     

    shell 的条件判断
     
    test 和 [] 
     
    if test -f fred.c
    then 
    fi
     
    if [ -f fred.c ]
    then 
    fi

    test 可以使用的三类条件
     
    1 字符串比较
    string1 = string2
    string1 != string2
    -n string                字符串不为空则为真
    -z string                字符串为空则为真
     
    2 算术比较
    expr1 -eq expr2
    expr1 -ne expr2
    expr1 -gt expr2
    expr1 -ge expr2
    expr1 -lt expr2
    expr1 -le expr2
    ! expr                    表达式为假则为真
     
    3 文件测试
    -d file                文件是目录
    -e file            如果文件存在
    -f file                如果是普通文件
    -g file            如果set-group-id 被设置
    -r file            如果文件可读
    -s file            未果文件大小不为0
    -u file            如果set-user-id 被设置
    -w file            如果文件可写
    -x file            如果文件可执行
     

    通过read获取的值,引用时最好用双引号引起来,这样的话,直接回车变量就是空字符串
     

    输出不换行
    有些系统不支持用echo -e 
    bash 可以用 echo -n 
    最好用printf
     
     

    shell 中的控制结构
     
    1 if
    echo "yes or no"
    read timeofday
    if [ "$timeofday" = "yes" ]; then
        echo "good"
    else 
        echo "wrong"
    fi
    exit 0
     
    2 elif
    echo "yes or no"
    read timeofday
    if [ "$timeofday" = "yes" ]
    then
        echo "Good morning"
    elif [ "$timeofday" = "no" ]; then
        echo "good"
    else
        echo "sorry"
        exit 1
    fi
    exit 0
     
    3 for
    for foo in bar fud 43
    do 
        echo $foo
    done
    exit 0
     
    for file in $(ls f*.sh); do
        cat $file
    done
    exit 0
     
    4 while
    echo "Enter password"
    read trythis
    while [ "$trythis" != "secret" ]; do
        echo "Sorry, try again"
        read trythis
    done
    exit 0
     
    5 until 反复执行,知道为真
    监控某个用户登陆
    until who | grep "$1" > /dev/null
    do
        sleep 60
    done
    echo -e 'a'
    echo " *** $1 has logged in *** "
    exit 0
     
    6 case 语句
     
    基础用法
    echo "yes or no"
    read timeofday
    case "$timeofday" in
        yes) echo "Good morning";;
        no ) echo "good afternoon";;
        y  ) echo "good morning";;
        n  ) echo "good afternoon";;
        *  ) echo "sorry";;
    esac
    exit 0
     
    合并匹配模式
    echo "yes or no"
    read timeofday
    case "$timeofday" in
        yes | y | Yes | YES ) echo "morning";;
        n* | N* )             echo "afternoon";;
        * )                   echo "sorry";;
    esac
    exit 0
     
    执行多条语句
    echo "yes or no"
    read timeofday
    case "$timeofday" in 
        yes | Y | Yes | YES )
            echo "morning"
            echo "up"
            ;;
        [nN]* )
            echo "good afternoon"
            ;;
        *)
            echo "sorry"
            echo no"
            exit 1
            ;;
    esac
    exit 0
     
    7 and 和 or
    短路逻辑
     
    and && 
    touch file_one
    rm -f file_two
    if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo " there"
    then 
        echo "in if"
    else
        echo "in else"
    fi
    exit 0
     
    or ||
     
     
    8 语句块
     
    在只允许单个语句的地方,比如(and or 列表) ,可以用花括号构造一个语句块
     

    shell 中的函数
    foo()  {
        echo "function"
    }
    echo "start"
    foo
    echo "end"
    exit 0
     
    函数中的局部变量
    shell 中的函数默认会使用全局变量
    sample_text="global variable"
    foo() {
        local sample_text="local variable"
        echo "function foo executing"
        echo $sample_text
    }
    echo "start"
    echo $sample_text
    foo
    echo "end"
    echo $sample_text
    exit 0
     
    函数参数传递与返回值
    #!/bin/bash
    yes_or_no() {
        echo "Is your name $* ?"
        while true
        do
            echo -n "Enter yes or no: "
            read x
            case "$x" in
                y | yes ) return 0;;
                n | no ) return 1;;
                * )     echo "answer yes or no"
            esca
        done
    }
     
    echo "Original paramers are $*"
    if yes_or_no "$1"
    then 
        echo "Hi $1, nice name"
    else
        echo "Never mind"
    fi
    exit 0
     
     

     
    shell 提供的命令
     
    1 break
    2 :             等价于true
    3 continue
     
    4 .     在当前shell中执行命令
    . ./shell_script
    source ./shell_script
     
    5 echo 
    建议在现代shell中用printf
     
    6 eval
    foo=10
    x=foo
    eval y='$'$x
    echo $y
     
    # 结果为10
     
    7 exec
    exec典型用法时将当前shell替换为一个不同程序,脚本后面的代码不会执行
    exec wall "Thanks for all the fish"
     
    另一种用法是修改当前文件描述符
    exec 3< afile
    打开文件描述符3,从afile读取数据
     
    8 exit
     
    9 export 
    export命令将作为它参数的变量导出到子shell中
     
    10 expr
    expr 将它的参数当作数学表达式运算
    x=10
    x=`expr $x + 1`
     
    expr 支持的运算符
    expr1 | expr2        如果expr1非零,则等于exp1,否则等于expr2
    expr1 & expr2        只要有一个表达式为零,则等于零,否则等于expr1
    expr1 = expr2
    expr1 > expr2    >=  < <= != + - * / %
     
    expr 常被替换为 $((…))
     
    11 printf
    printf "%s " hello
    printf "%s %d %s" "Hi There" 15 people
     
    12 return
    使函数返回,如果函数没有return,则返回值是最后一条命令的退出码
     
    13 set
    set 用来为shell设置参数变量
     
    14 shift命令
    shift把所有参数变量左移一个位置,使$2变成 $1,以此类推
     
    15 trap
    trap用于指定在接收到信号后要采取的行动
     
    trap -l 查看信号编号和关联的名称
     
    trap command signal
     
    重置某个信号的处理方式,command -
    忽略某个信号 command 设置为空字符串’'
     
    #!/bin/bash
    trap "rm -f /tmp/my_tmp_file_$$" INT
    echo creating file /tmp/my_tmp_file_$$
    date > /tmp/my_tmp_file_$$
     
    echo "press interrupt ( C-c ) to interrupt …."
    while [ -f /tmp/my_tmp_file_$$ ]; do
        echo File exists
        sleep 1
    done
    echo The file no longer exists
     
    trap "" INT
    echo creating file /tmp/my_tmp_file_$$
    date > /tmp/my_tmp_file_$$
     
    echo "press interrupt (C-c) to interrupt ….."
    while [ -f /tmp/my_tmp_file_$$ ]; do
        echo File exists
        sleep 1
    done
     
    echo we never get here
    exit 0
     
    16 unset
    unset 用来从环境中删除变量或函数,不能删除shell本身定义的只读变量

     
    17 find
     
    find [path] [option] [tests] [actions]
     
    基本用法
    find / -name test -print
    -print 是默认action
     
    不搜索挂载的其他文件系统的目录
    find / -mount -name test -print     
     
    在当前目录下搜索比文件while2新的文件
    find . -newer while2 -type f -print
     
    组合测试
    find . ( -name "_*" -or -newer while2 ) -type f -print
     
    执行一条命令,动作必须用;字符对结束
    find . -newer while2 -type f -exec ls -l {} ; 
     
    18 grep
     
    grep [options] PATTERN [FILES]
    如果没有提供文件名,grep会使用标准输入
     
    grep in words.txt
    grep -c in words.txt words2.txt       输出匹配的统计
    grep -c -v in words.txt words2.txt         -v 取反
     

    grep 中的正则表达式
     
    常用的特殊字符
    ^
    $
    .
    []    里面是范围[a-z]  范围前加^表示反向字符
     
    在方括号内可以使用的一些有用的特殊匹配模式,比如[[:alnum:]]
    [:alnum:]
    [:alpha:]
    [:ascii:]
    [:blank:]    空格或制表符
    [:cntrl:]
    [:digit:]
    [:graph:]
    [:graph:]
    [:lower:]
    [:print:]
    [:punct:]
    [:space:]   空白字符,包括垂直制表符
    [:upper:]
    [:xdigit:]        十六进制数字
     
    如果指定了-E可以用扩展匹配,但是需要加
    ?
    +
    {n}
    {n,}
    {n,m}
     
    查找以字母e结尾的行
    grep e$ words2.txt
     
    查找以字母a结尾的单词
    grep a[[:blank:]] words2.txt
     
    查找以Th开头的,由三个字母组成的单词
    grep Th.[[:space:]] words2.txt
     
    查找长度为10,都由小写字母组成的单词
    grep -E [a-z]{10} words2.txt
     

    shell 中获得命令执行结果
    whoisthere=$(who)
    echo $whoisthere
     
    如果需要把命令输出转换为参数,并作为另一个程序的参数,可以用xargs
     

    expr 的新扩展 $((..))
    x=0
    while [ "$x" -ne 10 ]; do
        echo $x
        x=$(($x+1))
    done
    exit 0
     

    参数扩展
     
    基本用法
    for i in 1 2
    do 
        my_secret_process ${i}_tmp
    done
     
    参数扩展
    ${param:-default}   如果param为空,把它设置为default的值
    ${#param}            给出param的长度
    ${param%word}       从param尾部开始删除与word匹配的最小部分,返回剩余部分
    ${param%%word}           尾部  最长
    ${param#word}        头部 最小
    ${param##word}        头部 最长
     
     
    unset foo
    echo ${foo:-bar}       # bar
     
    foo=fud
    echo ${foo:-bar}       # fud
     
    foo=/usr/bin/X11/startx
    echo ${foo#*/}         # usr/bin/X11/startx
    echo ${foo##*/}         # startx
     
    bar=/usr/local/etc/local/networks
    echo ${bar%local*}         # /usr/local/etc
    echo ${bar%%local*}        # /usr/
     
    批量转换GIF为JPEG
    for image in *.gif
    do
        cjpeg $image > ${image%%gif}jpg
    done
     

    here 文档
    ed a_text_file <<!FunkyStuff!
    3
    d
    .,$s/is/was/
    w
    q
    !FunkyStuff!
     
    exit 0
     

     
    shell 脚本调试
     
    1 只检查语法错误,不执行命令
    sh -n <script>
     
    set -o noexec
    set -n
     
    2 执行命令前回显它们
    sh -v <script>
     
    set -o verbose
    set -v
     
    3 执行完命令后回显它们
    sh -x <script>
     
    set -o xtrace
    set -x
     
    4 如果使用了未定义的变量,就给出错误消息
    sh -u <script>
     
    set -o nounset
    set -u
     
    通过捕获EXIT信号,查看脚本退出时的状态
    trap "echo Exiting: critical variable=$critical_variable" EXIT
     
  • 相关阅读:
    hdu 5170 GTY's math problem(水,,数学,,)
    hdu 5178 pairs(BC第一题,,方法不止一种,,我用lower_bound那种。。。)
    hdu 5179 beautiful number(构造,,,,)
    cf12E Start of the season(构造,,,)
    cf12D Ball(MAP,排序,贪心思想)
    cf 12C Fruits(贪心【简单数学】)
    cf 12B Correct Solution?(贪心)
    hdu 5171 GTY's birthday gift(数学,矩阵快速幂)
    hdu 5172 GTY's gay friends(线段树最值)
    cf 11D A Simple Task(状压DP)
  • 原文地址:https://www.cnblogs.com/junmoxiao/p/11963875.html
Copyright © 2020-2023  润新知