读《Linux Shell脚本攻略》第1章笔记

    1. #!、shebang意义
    Linux环境中的任何脚本语言,都是以这样一个被称为shebang的特殊行作为起始的,在这行中,字符#!被置于解释器路径之前。/bin/bash是解释器的位置

    http://zh.wikipedia.org/wiki/Shebang

    2. echo、printf
    echo 后面不用引号,用双引号,单引号区别,并总结双引号中需要转义(\)的特殊字符
    printf使用引用文本或由空格分隔的参数,我们可以在printf中使用格式化字符串。我们还可以指定字符串的宽度、左右对齐方式等。在默认情况下,printf并不像echo命令一样会自动添加换行符,我们必须在需要的时候手动添加,比如在下面的脚本中:
    #!/bin/bash
    printf “%-5s %-10s %-4s\n” No Name Mark
    printf “%-5s %-10s %-4.2f\n” 1 Sarath 80.3456
    printf “%-5s %-10s %-4.2f\n” 2 James 90.9989
    printf “%-5s %-10s %-4.2f\n” 3 Jeff 77.564
    输出结果:
    No    Name       Mark
    1     Sarath     80.35
    2     James      91.00
    3     Jeff       77.56
    %s、%c、%d、%f都是格式化字符,其所对应的参数可以置于带引号的格式化字符串之后。
    %-5s格式化为左对齐宽度为5的字符串替代(-表示左对齐),如果不用-指定对齐方式,字符串则采用右对齐形式。宽度指定了保留给某个变量的字符数,列
    和列本身有一个空字符串。对Name而言,保留宽度为10,所以看起来列和列之间有11个字符串。因此,任何Name字段的内容都会被显示在10字符宽的
    保留区域内,如果内容不足10字符,余下的则会以空格符填充。如果超过10个字符,列对齐效果将被打乱。
    %-4.2,其中.2指定保留2个小数位,对小数部分四舍五入。注意,在每行格式字符串后都有一个换行符\n。

    3. 颜色输出
    打印彩色文本对应颜色码:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37
    打印彩色背景对应颜色码:重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,洋红=45,青色=46,白色=47
    echo -e “\e[1;31mThis is red text\e[0m"
    echo -e "\e[1;42mGreen background\e[0m"

    4. cat /proc/`pgrep java`/environ | tr '\0' '\n'
    tr '\0' '\n' 重新格式化输出,将\0(null字符)替换成\n(换行)

    5. bc
    设定小数精度:scale=2 将小数位个数设置为2.
    echo "scale=2;3/8" | bc
    .37

    进制转换:
    echo "obase=2;100" | bc
    1100100 #十进制转换成二进制
    echo "obase=10;ibase=2;1100100" | bc
    100 #二进制转换成十进制

    计算平方以及平方根:
    echo "sqrt(100)" | bc
    10
    echo "10^10" | bc
    10000000000

    6. stdin、stdout、stder、tee
    0 - stdin(标准输入)
    1 - stdout (标准输出)
    2 - stderr (标准错误)

    $echo a1 > a1;cp a1 a2;cp a2 a3 ;chmod 000 a1
    $ cat * | tee -a out.txt | cat -n
    cat: a1: Permission denied
    1  a1
    2  a1
    $ cat out.txt
    a1
    a1

    tee命令接收到来自stdin的数据。它将stdout的一份副本写入文件out.txt。同时将另一份副本作为后续命令的stdin。命令cat -n将从stdin中接收到的每一行数据前加上行号并写入stdout。-a参数可以用于追加内容
    可以使用stdin作为命令参数,只需要将-作为命令的文件名参数即可:
    $ echo who is this | tee -
    who is this
    who is this

    7. 自定义文件描述符
    文件描述符是用于访问文件的一个抽象指针。存取文件离不开被称为“文件描述符”的特殊数字。0、1和2分别是stdin、stdout和stderr的预留描述符。
    我们可以使用exec命令创建自定义的文件描述符。3中模式:只读模式;截断模式;追加模式
    为读取文件创建一个文件描述符:
    # touch input.txt
    # exec 3<input.txt  #使用文件描述符3打开并读取文件
    # echo This is a test line > input.txt
    # exec 3<input.txt
    # cat <&3
    This is a test line
    如果要再次读取,我们就不能再继续使用文件描述符3了,而是需要用exec重新分配文件描述符3以便用于读取。

    创建一个文件描述符用户写入(截断模式):
    # exec 4>output.txt #打开文件用于写入
    # echo newline >&4
    # cat output.txt
    newline

    创建一个文件描述符用于写入(追加模式):
    # exec 5>>input.txt
    # echo appended line >&5
    # cat input.txt
    This is a test line
    appended line

    8. 数组和关联数组
    bash同时支持普通数组和关联数组。普通数组只能使用整数作为数组索引,而关联数组可以使用字符串作为数组索引。关联数组是从bash4.0开始被引入。
    定义关联数组
    首先需要使用单独的声明语句将一个变量名声明为关联数组。声明语句如下:
    # declare -A ass_array
    声明之后,可以用两种方法将元素添加到关联数组中。
    1). 利用内嵌索引值列表法,提供一个索引值列表:
    # ass_array=([index1]=val1 [index2]=val2)
    2). 使用独立的索引值进行赋值:
    # ass_array[index1]=val1
    # ass_array[index2]=val2

    列出数组索引
    每一个数组元素都有一个索引用于查找。普通数组和关联数组具有不同的索引类型

    9. 获取终端信息
    获取终端的行数和列数:
    tput cols
    tput lines

    打印出当前终端名:
    tput longname

    将光标移动到方位(100,100)处:
    tput cup 100 100

    设置终端背景色:
    tput setb no #no取值在0~7之间

    将文本前景色设置为白色:
    tput serf no #no取值在0~7之间

    设置文本样式为粗体:
    tput bold

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

    在输入密码的时候,不能让输入的内容显示出来,在下面的例子中,我们将看到如何使用stty来实现这个要求:
    #!/bin/bash
    #Filename:password.sh
    echo -e “Enter password: ”
    stty -echo
    read password
    stty echo
    echo
    echo $password
    echo Password read.
    其中,选项-echo禁止将输出发送到终端,而选项echo则允许发送输出。

    用tput和sleep从0开始计数到40:
    #!/bin/bash
    #Filename sleep.sh
    echo -n Count:
    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 rc。tput
    ed清除从当前光标位置到行尾之间的所有内容,使得旧的count值可以被清除并写入新值。循环内的1s延时是通过sleep命令来实现的。

    10. 调试shell脚本
    set -x:在执行时显示参数和命令。
    set +x:禁止调试。
    set -v:当命令进行读取时显示输入。
    set +v:禁止打印输入。

    11. Fork炸弹
    : () {
    : | : &
    }; :
    : 是函数名,执行一个调用自己的递归并且 pipe 到自己,& 表示后台执行程序,最后的一个 : 是在函数外调用和执行 : () 这个函数的意思

    12. read
    参数可以组合使用
    # read -n 2 var   读取2个字符并存入变量var
    # echo $var

    # read -s var  #用不回显的方式读取密码
    # echo $var

    # read -p “Enter input:” var    #显示提示信息

    # read -t 2 var    #在2s内将输入的字符串存入到变量var

    # read -d “:” var    #使用:作为定界符结束输入行

    13. 字段分隔符和迭代器
    内部字段分隔符(Internal Field Separator, IFS)
    # cat ifs.sh
    #!/bin/bash
    data=”name,sex,rollno,location”
    oldIFS=$IFS
    IFS=”,”
    for item in $data;
    do
    echo Item:$item
    done
    IFS=$oldIFS
    结果如下:
    Item:name
    Item:sex
    Item:rollno
    Item:location

    IFS的默认值为空白符(换行符、制表符或者空格)。
    当IFS被设置为逗号时,shell将逗号解释成一个定界符,因此变量$item在每次迭代中读取由逗号分隔的字串作为变量值。
    如果没有把IFS设置成”,”,那么上面的脚本将会全部数据作为单个字符串打印出来。

    14. Bash多种类型的循环
    for 循环
    while 循环
    until 循环
    &&逻辑与运算符   ||逻辑或运算符

    15. 算术比较
    条件通常被放置在封闭的中括号内。一定要注意在[]与操作数之间有一个空格。
    -gt:大于
    -lt:小于
    -ge:大于或等于
    -le:小于或等于
    -eq:等于
    -ne:不等于

    可以结合 -a 逻辑与 -o 逻辑或条件进行测试

    文件系统相关属性测试:
    [ -f $file_var ]    如果给定的变量包含正常的文件路径或文件名,则返回真
    [ -x $var ]    如果给定的变量包含的文件可执行,则返回真
    [ -d $var ]    如果给定的变量包含的是目录,则返回真
    [ -e $var ]    如果给定的变量包含的文件存在,则返回真
    [ -c $var ]    如果给定的变量包含的是一个字符设备文件的路径,则返回真
    [ -b $var ]    如果给定的变量包含的是一个块设备文件的路径,则返回真
    [ -w $var ]    如果给定的变量包含的文件可写,则返回真
    [ -r $var ]    如果给定的变量包含的文件可读,则返回真
    [ -L $var ]    如果给定的变量包含的是一个符号链接,则返回真

    字符串比较:
    使用字符串比较是,最好用双中括号,因为有时候采用单个中括号会产生错误,所以最好避开他们。
    [[ $str1 = $str2 ]]    当str1等于str2时,返回真。str1和str2包含的文本是一模一样
    [[ $str1 == $str2 ]]    这是检查字符串是否相等的另一种写法。也可以检查两个字符串是否不同
    [[ $str1 != $str2 ]]    如果str1和str2不相同,则返回真
    [[ $str1 > $str2 ]]    如果str1的字母序比str2大,则返回真
    [[ $str1 < $str2 ]]    如果str1的字母序比str2小,则返回真
    [[ -z $str1 ]]    如果str1包含的是空字符串,则返回真
    [[ -n $str1 ]]    如果str1包含的是非空字符串,则返回真
    注意:在=前后各有一个空格,如果忘记加空格,那就不是比较关系了,而变成了赋值语句

    • 本文由 发表于 2012-11-16
    • 转载请务必保留本文链接:https://linuxeye.com/225.html
    Linux下内置命令和外部命令详解 Linux

    Linux下内置命令和外部命令详解

    Linux的命令分为内部命令和外部命令: 内部命令在系统启动时就调入内存,是常驻内存的,所以执行效率高。 外部命令是系统的软件功能,用户需要时才从硬盘中读入内存。 type可以用来判断一个命令是否为内...
    shell字符串处理 脚本

    shell字符串处理

    字符串操作(长度,读取,替换) 表达式 含义 ${#string} $string的长度 ${string:position} 在$string中, 从位置$position开始提取子串 ${stri...
    Linux shell用法和技巧 脚本

    Linux shell用法和技巧

    检查远程端口是否对bash开放: echo >/dev/tcp/8.8.8.8/53 && echo "open" 让进程转入后台: Ctrl + z 将进程转到前台: fg 产...
    匿名

    发表评论

    匿名网友