基础知识
    使用绝对路径 和相对路径都是 在子shell中执行
    ./ds.sh 相对路径
    /root/ds.sh 绝对路径
    ds.sh 吧/root 放入环境变量中

    1. [dmtsai@study bin]$ echo ${firstname} ${lastname}
    2. <==确认了,这两个变量并不存在喔!
    3. [dmtsai@study bin]$ sh showname.sh
    4. Please input your first name: VBird <==这个名字是鸟哥自己输入的
    5. Please input your last name: Tsai
    6. Your full name is: VBird Tsai <==看吧!在 script 运行中,这两个变量有生效
    7. [dmtsai@study bin]$ echo ${firstname} ${lastname}
    8. <==事实上,这两个变量在父程序的 bash 中还是不存在的!

    使用source 执行脚本 其实实在父shell中执行的
    当然 使用 . showname.sh 也是和 source showname.sh 是一样的
    和bash环境中一样 sourve 和 . (小数点) 的作用是一样的

    dmtsai@study bin]$ source showname.sh 
    Please input your first name: VBird 
    Please input your last name: Tsai 
    Your full name is: VBird Tsai 
    [dmtsai@study bin]$ echo ${firstname} $
    

    shell脚本的调试和测试(debug)

    [dmtsai@study ~]$ sh [-nvx] scripts.sh 
    选项与参数: 
    -n :不要执行 script,仅查询语法的问题; 
    -v :再执行 sccript 前,先将 scripts 的内容输出到屏幕上; 
    -x :将使用到的 script 内容显示到屏幕上,这是很有用的参数! 
    范例一:测试 dir_perm.sh 有无语法的问题? 
    [dmtsai@study ~]$ sh -n dir_perm.sh 
    # 若语法没有问题,则不会显示任何信息! 
    范例二:将 show_animal.sh 的执行过程全部列出来~ 
    [dmtsai@study ~]$ sh -x show_animal.sh 
    + PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/root/bin 
    + export PATH 
    + for animal in dog cat elephant 
    + echo 'There are dogs.... ' 
    There are dogs.... 
    + for animal in dog cat elephant 
    + echo 'There are cats.... ' 
    There are cats.... 
    + for animal in dog cat elephant 
    + echo 'There are elephants.... ' 
    There are elephants....
    

    在加号后面的数据其实都是指令
    串,由于 sh -x 的方式来将指令执行过程也显示出来, 如此使用者可以判断程序码执行到
    哪一段时会出现相关的信息!这个功能非常的棒!通过显示完整的指令串, 你就能够依
    据输出的错误信息来订正你的脚本了!

    鸟哥本章重点
    shell script 是利用 shell 的功能所写的一个“程序 (program)”,这个程序是使用纯文
    本文件,将一些 shell 的语法与指令(含外部指令)写在里面, 搭配正则表达式、管
    线命令与数据流重导向等功能,以达到我们所想要的处理目的
    shell script 用在系统管理上面是很好的一项工具,但是用在处理大量数值运算上, 就
    不够好了,因为 Shell scripts 的速度较慢,且使用的 CPU 资源较多,造成主机资源的
    分配不良。
    在 Shell script 的文件中,指令的执行是从上而下、从左而右的分析与执行;
    shell script 的执行,至少需要有 r 的权限,若需要直接指令下达,则需要拥有 r 与 x
    的权限;
    良好的程序撰写习惯中,第一行要宣告 shell (#!/bin/bash) ,第二行以后则宣告程
    序用途、版本、作者等
    对谈式脚本可用 read 指令达成;
    要创建每次执行脚本都有不同结果的数据,可使用 date 指令利用日期达成;
    script 的执行若以 source 来执行时,代表在父程序的 bash 内执行之意!
    若需要进行判断式,可使用 test 或中括号 ( [] ) 来处理;
    在 script 内,$0, $1, $2…, $@ 是有特殊意义的!
    条件判断式可使用 if…then 来判断,若是固定变量内容的情况下,可使用 case $var in
    … esac 来处理
    循环主要分为不定循环 (while, until) 以及固定循环 (for) ,配合 do, done 来达成
    所需任务!
    我们可使用 sh -x script.sh 来进行程序的 debug

    判断式
    必须要注意
    中括号的两端需要有空白字符来分隔喔! 假设我空白键使用“□”符号来表示,那么,在这
    些地方你都需要有空白键:
    [ “$HOME” == “$MAIL” ] [□”$HOME”□==□”$MAIL”□]
    在中括号 [] 内的每个元件都需要有空白键来分隔;
    在中括号内的变量,最好都以双引号括号起来;
    在中括号内的常数,最好都以单或双引号括号起来。

    image.jpeg
    image.jpeg
    例子
    范例一
    1. 这个文件是否存在,若不存在则给予一个“Filename does not exist”的讯息,并中断程
    序;
    2. 若这个文件存在,则判断他是个文件或目录,结果输出“Filename is regular file”或
    “Filename is directory”
    3. 判断一下,执行者的身份对这个文件或目录所拥有的权限,并输出权限数据!

    [dmtsai@study bin]$ vim file_perm.sh 
    #!/bin/bash 
    # Program: 
    # 
    User input a filename, program will check the flowing: 
    # 
    1.) exist? 2.) file/directory? 3.) file permissions 
    # History: 
    # 2015/07/16 
    VBird 
    First release 
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 
    export PATH 
    # 1. 让使用者输入文件名,并且判断使用者是否真的有输入字串? 
    echo -e "Please input a filename, I will check the filename's type and permission. \n\n" 
    read -p "Input a filename : " filename 
    test -z ${filename} && echo "You MUST input a filename." && exit 0 
    # 2. 判断文件是否存在?若不存在则显示讯息并结束脚本 
    test ! -e ${filename} && echo "The filename '${filename}' DO NOT exist" && exit 0 
    # 3. 开始判断文件类型与属性 
    test -f ${filename} && filetype="regulare file" 
    test -d ${filename} && filetype="directory" 
    test -r ${filename} && perm="readable" 
    test -w ${filename} && perm="${perm} writable" 
    test -x ${filename} && perm="${perm} executable" 
    # 4. 开始输出信息! 
    echo "The filename: ${filename} is a ${filetype}"
    

    范例二
    1. 当执行一个程序的时候,这个程序会让使用者选择 Y 或 N ,
    2. 如果使用者输入 Y 或 y 时,就显示“ OK, continue ”
    3. 如果使用者输入 n 或 N 时,就显示“ Oh, interrupt !”
    4. 如果不是 Y/y/N/n 之内的其他字符,就显示“ I don’t know what your choice is ”

    [dmtsai@study bin]$ vim ans_yn.sh 
    #!/bin/bash 
    # Program: 
    # 
    This program shows the user's choice 
    # History: 
    # 2015/07/16 
    VBird 
    First release 
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 
    export PATH 
    read -p "Please input (Y/N): " yn 
    [ "${yn}" == "Y" -o "${yn}" == "y" ] && echo "OK, continue" && exit 0 
    [ "${yn}" == "N" -o "${yn}" == "n" ] && echo "Oh, interrupt!" && exit 0 
    echo "I don't know what your choice is" && exit 0
    

    位置参数变量

    dmtsai@study ~]$ file /etc/init.d/network 
    /etc/init.d/network: Bourne-Again shell script, ASCII text executable 
    # 使用 file 来查询后,系统告知这个文件是个 bash 的可执行 script 喔! 
    [dmtsai@study ~]$ /etc/init.d/network restart
    

    script 是怎么达成这个功能的呢?其实 script 针对参数已经有设置好一些变量名称
    了!对应如下:

                /path/to/scriptname opt1 opt2 opt3 opt4 
                                                $0 $1 $2 $3 $4                
    

    这样够清楚了吧?执行的脚本文件名为 $0 这个变量,第一个接的参数就是 $1 啊
    ~ 所以,只要我们在 script 里面善用 $1 的话,就可以很简单的立即下达某些指令功能
    了!除了这些数字的变量之外, 我们还有一些较为特殊的变量可以在 script 内使用来调用
    这些参数喔!
    $# :代表后接的参数“个数”,以上表为例这里显示为“ 4 ”;
    $@ :代表“ “$1” “$2” “$3” “$4” ”之意,每个变量是独立的(用双引号括起来);
    $* :代表“ “$1c$2c$3c$4” ”,其中 c 为分隔字符,默认为空白键, 所以本例中代表“
    “$1 $2 $3 $4” ”之意。
    范例一
    自己注意看执行结果的不同

    dmtsai@study bin]$ vim how_paras.sh 
    echo "The script name is ==> ${0}" 
    echo "Total parameter number is ==> $#" 
    [ "$#" -lt 2 ] && echo "The number of parameter is less than 2. Stop here." && exit 0 
    echo "Your whole parameter is ==> '$@'" 
    echo "The 1st parameter ==> ${1}" 
    echo "The 2nd parameter ==> ${2}"
    

    执行结果如下:

    [dmtsai@study bin]$ sh how_paras.sh theone haha quot 
    The script name is ==> how_paras.sh <==文件名 
    Total parameter number is ==> 3 <==果然有三个参数 
    Your whole parameter is ==> 'theone haha quot' <==参数的内容全部 
    The 1st parameter ==> theone <==第一个参数 
    The 2nd parameter ==> haha <==第二个参数
    

    范例二
    位置参数变量的偏移 shift

    [dmtsai@study bin]$ vim shift_paras.sh 
    echo "Total parameter number is ==> $#" 
    echo "Your whole parameter is ==> '$@'" 
    shift # 进行第一次“一个变量的 shift ” 
    echo "Total parameter number is ==> $#" 
    echo "Your whole parameter is ==> '$@'" 
    shift 3 # 进行第二次“三个变量的 shift ” 
    echo "Total parameter number is ==> $#" 
    echo "Your whole parameter is ==> '$@'"
    

    这玩意的执行成果如下:

    [dmtsai@study bin]$ sh shift_paras.sh one two three four five six <==给予六个参数 
    Total parameter number is ==> 6 <==最原始的参数变量情况Your whole parameter is ==> 'one two three four five six' 
    Total parameter number is ==> 5 <==第一次偏移,看下面发现第一个 one 不见了 
    Your whole parameter is ==> 'two three four five six' 
    Total parameter number is ==> 2 <==第二次偏移
    

    那个 shift 会移动变量,而且 shift 后面可以接数字,代
    表拿掉最前面的几个参数的意思。 上面的执行结果中,第一次进行 shift 后他的显示情况
    是“ one two three four five six”,所以就剩下五个啦!第二次直接拿掉三个,就变成“ two
    three four five six ”啦!