zoukankan      html  css  js  c++  java
  • Bash Shell 小试牛刀

    一、终端打印

    [root@cai ~]# echo welcome to bash!

    welcome to bash!

    [cairui@cai ~]$ echo 'welcome to bash!'

    welcome to bash!

    [cairui@cai ~]$ echo "welcome to bash!"

    welcome to bash!

    (注意,双引号内不能直接用特殊符号,需要用转义符

    [cairui@cai ~]$ printf "hello world"

    hello world

    #!/bin/bash

    #filename:printf.sh

    printf  "%-5s %-10s %-4s " no name mark

    printf  "%-5s %-10s %-4.2f " 1 sarath 80.3456

    printf  "%-5s %-10s %-4.2f " 2 james 90.9989

    printf  "%-5s %-10s %-4.2f " 3 jeff 77.564

    得到如下结果

    [cairui@cai shell]$ sh printf.sh

    no    name       mark

    1     sarath     80.35

    2     james      91.00

    3     jeff       77.56

    1.工作原理

      %s ,%c,%d%f都是格式替换符,其所对应的参数可以置于带引号的格式字符串之后。

      %-5s指明格式为左对齐且宽度为5的字符串替换,不够的用空格补上。

      对于%-4.2f,其中.2指定保留2个小数位。

    2.补充内容

    (1)echo中转义换行符

    [cairui@cai shell]$ echo -e "1 2 3"

    1 2 3

    (2)打印彩色输出

    重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37

    打印彩色文本

    [cairui@cai shell]$ echo -e "e[1;31m this is red text e[0m"

     this is red text

    设置彩色背景,重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,洋红=45,青色=46,白色=47

    二、玩转变量和环境变量

      bash中,每一个变量的值都是字符串。无论你给变量赋值时有没有引号,值都是以字符串形式存在。有一些特殊的变量会被shell环境和操作系统环境用来存储一些特别的值,这类变量就称为环境变量。

    Cat /proc/$PID/environ(查看运行时的环境变量)

    例子:

    [cairui@cai shell]$ pgrep mysql

    11029

    11313

    [cairui@cai shell]$ sudo cat /proc/11313/environ

    TERM=xtermOLDPWD=/application/mysqlPATH=/sbin:/usr/sbin:/bin:/usr/bin:/application/mysql/binPWD=/application/mysqlSHLVL=3MYSQL_HOME=/application/mysql_=/usr/bin/nohup

    [cairui@cai shell]$ sudo cat /proc/11313/environ |tr '' ' '

    TERM=xterm

    OLDPWD=/application/mysql

    PATH=/sbin:/usr/sbin:/bin:/usr/bin:/application/mysql/bin

    PWD=/application/mysql

    SHLVL=3

    MYSQL_HOME=/application/mysql

    _=/usr/bin/nohup

    1.实战演练

    [cairui@cai shell]$ var=value

    [cairui@cai shell]$ echo $var

    value

    Variable.sh代码如下:

    #!/bin/bash

    fruit=apple

    count=5

    echo "we have $count $fruit(s)"

    [cairui@cai shell]$ sh variable.sh

    we have 5 apple(s)

    Export命令就是用来设置环境变量:

    [cairui@cai shell]$ echo $PATH

    /application/mysql/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/application/xtrabackup/bin:/home/cairui/bin

    [cairui@cai shell]$ export PATH="$PATH:/home/cairui"

    [cairui@cai shell]$ echo $PATH

    /application/mysql/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/application/xtrabackup/bin:/home/cairui/bin:/home/cairui

    2.补充内容

    length=${#var}

    例如:

    [cairui@cai shell]$ vai=1234567890

    [cairui@cai shell]$ echo ${#vai}

    10

    三、使用函数添加环境变量

      PATH=/usr/bin;/bin

    这意味着只要shell需要执行二进制可执行文件时,它会首先查找/usr/bin,然后是/bin

    四、使用shell进行数学运算

      bash shell环境中,可以利用let,[],(())执行基本的算术操作。而在进行高级操作时,exprbc这两个工具也会非常有用。

    1.实例

    #!/bin/bash

    #filename:jia.sh

    no1=4;

    no2=5;

    let result=no1+no2

    echo $result

    [cairui@cai shell]$ sh jia.sh

    9

    自加操作

    let no1++

    自减操作

    let no1--

    简写形式

    let no+=6

    let no-=6

    它们分别等于let no=no+6let no=no-6

    (2)bc是一个数学高级工具,这个精密计算器包含了大量的选项。

    [root@cai ~]# echo "4*8"|bc

    32

    no=54

    result=’echo “$no*1.5”|bc’

    echo $result

    81.0

    设定小数精度。下面,参数scale=2将小数位个数设置为2.

    [cairui@cai shell]$ echo "scale=2;3/8"|bc

    .37

    进制转换。用bc可以将一种进制系统转换为另一种。(10进制转换2进制)

    #!/bin/bash

    #用途:数字转换

    no=100

    echo "obase=2;$no" |bc

    no=1100100

    echo "obase=10;ibase=2;$no" |bc

    [cairui@cai shell]$ sh shuzizhuanhuan.sh

    1100100

    100

    l 计算平方及平方根

    [cairui@cai shell]$ echo "sqrt(100)"|bc

    10

    [cairui@cai shell]$ echo "10^10"|bc

    10000000000

    五、玩转文件描述符及重定向

      文件描述符是与文件输入、输出相关联的整数。它们用来跟踪已打开的文件。最常见的文件描述符是stdin(标准输入)、stdout(标准输出)和stderr(标准错误)。

    0-----stdin

    1-----stdout

    2-----stderr

    1.实例

    [cairui@cai shell]$ echo "this is a sample text " >temp.txt

    [cairui@cai shell]$ cat temp.txt

    this is a sample text

    [cairui@cai shell]$ echo "this is a sample text " >>temp.txt

    [cairui@cai shell]$ cat temp.txt

    this is a sample text

    this is a sample text

    当命令出现错误时,错误信息就会被打印出来

    [cairui@cai shell]$ ls +

    ls: cannot access +: No such file or directory(错误信息)

    2.工作原理

    >等同于1>;对于>>也是等同于1>>

    (1)将文件重定向到命令

    cmd < file

    (2)将脚本内部的文本块进行重定向

    #!/bin/bash

    cat<<EOF>log.txt

    LOG FILE HEADER

    this is a test log

    function:system statistics

    EOF

    [cairui@cai shell]$ sh log-txt.sh

    [cairui@cai shell]$ cat log.txt

    LOG FILE HEADER

    this is a test log

    function:system statistics

    六、数组和关联数组

    array_var=(1  2  3  4  5  6)#这些值将会存储在以0为起始索引的连续位置上

    另外还可以将数组定义为一组“索引-值”

    array_var[0]=”test1”

    array_var[1]=”test2”

    ......

    ......

    ......

    ......

    array_var[5]=”test6”

    echo $array_var[0]

    test1

    echo $array_var[*]

    test1 test2 test3 test4 test5 test6

    打印数组长度

    echo ${#array_var[*]}

    6

    七、使用别名

    (1)可以用以下方式创建一个别名

    alias new_command=’command sequence’

    (2)上述别名只是暂时的。为了使别名永久生效,可以将它放在~/.bashrc文件中

    echo ‘alias cmd=”commadn seq”’ >> ~/.bashrc

    (3)删除别名,只需要从~/.bashrc中删除就可以了

    八、获取终端信息

      tputstty是两款终端处理工具。

    1.实例

    l 获取终端的行数和列数:

    tput cols

    tput lines

    l 打印当前终端名:

    tput longname

    将光标移动到坐标(100,100)处:

    tput cup 100 100

    l 设置终端背景色:

    tputsetb n

    其中,n可以在07之间取值

    l 设置文本样式为粗体

    tput bold

    l 设置下划线的起止:

    tput smu1

    tput rmu1

    l 删除从当前光标位置到行尾的所有内容:

    tputed

    l 在输入密码时,不应该显示输入内容:

    #!/bin/bash

    #filename:password.sh

    echo -e “enter password:”

    stty -echo

    read password

    stty echo

    echo

    echo password read

    九、获取、设置日期和延迟

       很多程序要以不同的格式打印日期、设置日期和时间、根据日期和时间执行操作。延时通常用于在程序执行过程中提供一段等待时间(比如1秒)。例如需要在脚本中对某项任务每隔5秒监视一次,就需要知道如何在程序中加入延时。

    1.实例

    1[cairui@cai support-files]$ date

    Tue Jun  6 15:27:22 CST 2017

    (2)打印纪元时:

    [cairui@cai support-files]$ date +%s

    1496734094

    [cairui@cai support-files]$ date --date "jan 20 2011" +%A

    Thursday

    (3)用格式串结合+作为date命令的参数:

    [cairui@cai support-files]$ date "+%d %b %y"

    06 Jun 17

    (4)设置时间和日期:

    date -s “格式化的日期字符串”

    例子:

    date -s “21 june 2009 11:01:22”

    (5)有时,我们需要检查一组命令所花费的时间,以下代码:

    #!/bin/bash

    #filename:time_take.sh

    start=$(date +%s)

    commands;

    statements;

    end=$(date +%s)

    difference=$((end - start))

    echo time taken to execute commands is $difference seconds

    2.工作原理

    日期内容

    格式

    星期

    %aA

    %bB

    %d

    固定格式日期(mmddyy

    %D

    %yY

    小时

    %I%H

    分钟

    %M

    %S

    纳秒

    %N

    Unix纪元时(以秒为单位)

    %s

    3.补充内容

     在脚本中推迟执行一段时间,可以用sleep$sleep no_of_seconds.例如,下面的脚本就使用tputsleep0开始计数到40

    #!/bin/bash

    #filename:sleep.sh

    echo -n Count:   echo -n不换行输出)

    tput sc

    count=0;

    while true;

    do

      if [ $count -lt 40 ];

      then

          let count++;

          sleep 1;

          tput rc

          tput ed

          echo -n $count;

      else exit 0;

      fi

    done

      在上面的例子中,变量count初始化为0,随后每循环一次便加1.echo语句打印出count的值。用tput sc存储光标的位置。在每次循环中,通过恢复之前存储的光标的位置,在终端中打印出新的count的值。恢复光标的命令是tput rctput ed清除从当前光标位置到行尾之间的所有内容,使得旧的count值可以被清除并写入新值。循环内的1秒钟延迟是通过sleep命令来实现。

    十、调试脚本

    (1)bash -x script.sh or sh -x script.sh

    (2)使用set -xset +x对脚本进行部分调试。例如:

    #!/bin/bash

    #filename:debug.sh

    for i in {1..6};

    do

        set -x

        echo $i

        set +x

    done

    echo "script executed"

    [cairui@cai shell]$ sh debug.sh

    + echo 1

    1

    + set +x

    + echo 2

    2

    + set +x

    + echo 3

    3

    + set +x

    + echo 4

    4

    + set +x

    + echo 5

    5

    + set +x

    + echo 6

    6

    + set +x

    script executed

    在上面的脚本中,只会打印出 echo $i的调试信息。因为使用了-x+x对调试区域进行了限制。

    (3)前面两种调试都是内建的。他们通常以固定的格式生成调试信息。但是在很多情况下,我们需要以自定义格式显示调试信息。可以通过传递_DEBUG环境变量来建立这类调试风格。

    #!/bin/bash

    function DEBUG()

    {

      [ "$_DEBUG" == "on" ]  && $@ || :

    }

    for i in {1..10}

    do

      DEBUG echo $i

    done

    ~          

    [root@cai shell]# _DEBUG=on ./DEBUG.sh

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    我们在每一个需要打印调试信息的语句前加上DEBUG。如果没有把_DEBUG=on传递给脚本,那么调试信息就不会被打印出来。在bash中,命令“:”告诉shell不要进行任何操作。

    十一、函数和参数

    1.实例

    我们可以创建执行特定任务的函数,也可以创建能够接受参数的函数。

    (1)定义函数:

    function fname()

    {

      statements;

    }

    或者

    fname()

    {

      statements;

    }

    (2)只需要使用函数名就可以调用某个函数:

    $fname  #执行函数

    (3)参数可以传递给函数,并由脚本进行访问:

    fname arg1 arg2#传递函数

    以下是函数fname 的定义。在函数fname中,包含了各种访问函数参数的方法。

    fname()

    {

    echo $1,$2;访问参数1和参数2

    echo “$@”;以列表的方式一次性打印所有参数

    echo “$*”;类似于¥@,但是参数被作为单个实体

    return 0;返回值

    }

    l $1是第一个参数

    l $2是第二个参数

    l $n是第n个参数

    l “$@”被扩展成”$1” “$2” “$3”等

    l “$*”被扩展成”$1c$2c$3”,其中cIFS的第一个字符

    l “$@”要比$*用的多。

    2.补充内容

    (1)递归函数

    f() {echo $1;f hello;sleep 1;}

    (2)导出函数

    export -f fname

    十二、不适用回车键来读取n个字符

      read是一个重要的bash命令,它用于从键盘或标准输入中读取文本。我们可以使用read以交互的形式读取来自用户的输入,不过read能做的可远远不止于此。任何编程语言的输入库大多都是从键盘读取输入;但只有当回车键按下的时候,才标志着输入完毕。而有些游戏里只需要按q就能释放技能。

    (1)下面的语句从输入中读取n个字符并存入变量variable_name

    read -n number_of_chars variable_name

    例如:

    read -n 2 var

    echo $var

    (2)用无回显的方式读取密码:

    read -s var

    (3)显示提示信息:

    read -p “enter input:” var

    (4)在特定时限内读取输入:

    read -t timeout var

    read -t 2 var  #2秒内将键入的字符串读入变量var

    (5)用特定的定界符作为输入行的结束:

    read -d delim_char var

    read -d “:” var

    hello:#var 被设置为hello

    十三、运行命令直至执行成功

      在日常工作中使用shell,有时候命令只有满足某些条件或是某种外部事件(例如文件可以被下载)操作才能成功执行。这种情况下,你可能希望重复执行命令,直到成功为止。

    1.实例:

    按照以下方式定义函数:

    repeat()

    {

     while true

     do

    $@ && return

    done

    }

    或者把它放入shellrc文件,更便于使用:

    repeat() {while true;do $@ && return;done}

    2.工作原理

      我们创建了函数repeat,它包含了一个无限while循环,该循环执行以参数形式(通过$@访问)传入函数的命令。如果命令执行成功,则返回,进而无限循环。

    3.补充内容

    (1)一种更快的做法

    repeat() {while :; do $@ && return; done } 比第一种方法快

    (2)增加延时

    repeat wget -c ........

    repeat() {while :; do $@ && return; sleep 30; done}这使得命令每30秒运行一次。

    十四、循环

    (1)for循环

    for var in list;

    do

    commands;

    done

    (2)while循环

    while condition

    do

       commands;

    done

    (3)until循环

    它会一直循环,直到给定的条件为真。

    x=0;

    until [ $x -eq 9 ];

    do

     let x++; echo $x;

    done

    十五、比较与测试

    1.实战

    (1)if条件

    if condition;

    then

      commands;

    fi

    (2)else ifelse

    if condition;

    then

      commands;

    else if condition; then

      commands;

    else

      commands;

    fi

    (3)算数比较

    l 对变量或值进行算数条件判断:

    [ $var -eq 0 ] #$var等于0时,返回真

    [ $var -ne 0 ] #当。。。为非0时,返回真

    l -gt:大于

    l -lt:小于

    l -ge:大于或等于

    l -le:小于或等于

    (4)字符串比较

    使用字符串比较时,最好用双中括号,因为有时候采用单个中括号会产生错误,所以最好避开它们。

    l [[$str1=$str2]],相等返回真

    l [[$str1==$str2]]检查字符串是否相等的另一种写法

    l [[$str1 !=$str2]]如果str1str2不相同,则返回真

    l [[$str1 > $str2]]

    l [[$str1 < $str2]]

    l [[-z $str1]],如果包含的是空字符串,返回真

    l [[-n $str]],如果包含的是非空字符串,则返回真

  • 相关阅读:
    BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路
    BZOJ 1708: [Usaco2007 Oct]Money奶牛的硬币
    BZOJ 1642: [Usaco2007 Nov]Milking Time 挤奶时间
    BZOJ 1611: [Usaco2008 Feb]Meteor Shower流星雨
    BZOJ 1610: [Usaco2008 Feb]Line连线游戏
    BZOJ 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐
    BZOJ 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
    BZOJ 1606: [Usaco2008 Dec]Hay For Sale 购买干草
    BZOJ 1083: [SCOI2005]繁忙的都市
    STL set的用法
  • 原文地址:https://www.cnblogs.com/caicairui/p/7202852.html
Copyright © 2011-2022 走看看