当前位置:   article > 正文

Linux学习笔记:Shell脚本学习_shell脚本qe

shell脚本qe

一、什么是Shell Scripts

    利用Shell的功能所写的一个程序,使用纯文本文件,将一些shell的语法与指令(含外部指令)写在里面,搭配正则表达式、管线命令与数据流重导向功能,以达到我们所想要的处理目的

    就像是DOS年代的批处理文件(.bat)

    为什么要学习:

        自动化管理的重要依据

        追踪和管理系统的重要工作

        简单入侵检测功能

        连续指令单一化

        简易的数据处理

        跨平台支持与学习历程较短

    注意事项

         

    几种执行的方法

        

        当使用sh shell.sh 运行时,只要有r的权限即可被执行

    撰写脚本的良好习惯

        在开头处记录:功能、版本信息、作者与联络方式、版权的宣告方式、History、脚本内较特殊的指令(使用绝对路径方式来下达的)、运行时需要的环境变量预先宣告与设定

二、简单的shell script练习

    1、练习代码

(1)输入姓、名,完整输出

  1. #!/bin/bash
  2. #Program:
  3. # show full name
  4. #History
  5. #2018.1.29 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. read -p "Please input your first name: " firstname
  9. read -p "Please input your last name: " lastname
  10. echo -e "\nYour full name is: ${firstname} ${lastname}"

 

  1. [gyy@localhost bin]$ chmod 777 showname.sh
  2. [gyy@localhost bin]$ ./showname.sh
  3. Please input your first name: G
  4. Please input your last name: YY
  5. Your full name is: G YY

(2)随日期变化进行文件建立

  1. #!/bin/bash
  2. #Program:
  3. # Program creates three files,which named by user's input and date command
  4. #History
  5. #2018.1.29 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. #1、让输入者输入文件名,并取得fileuser这个变量
  9. echo -e “I will use ’touchcommand to create 3 files”
  10. read -p "Please input your filename: " fileuser
  11. #2、为了避免使用者随意按Enter,利用变量分析档名是否有设定
  12. filename=${fileuser:-"filename"}
  13. #3、利用date指令来获取所需要的档名
  14. date1=$(date --date='2 days ago' +%Y%m%d)
  15. date2=$(date --date='1 days ago' +%Y%m%d)
  16. date3=$(date +%Y%m%d)
  17. file1=${filename}${date1}
  18. file2=${filename}${date2}
  19. file3=${filename}${date3}
  20. #4、建立档名
  21. touch "${file1}"
  22. touch "${file2}"
  23. touch "${file3}"
  1. [gyy@localhost bin]$ chmod 777 create_3_filename.sh
  2. [gyy@localhost bin]$ ./create_3_filename.sh
  3. “I will use ’touchcommand to create 3 files”
  4. Please input your filename: GYY
  5. [gyy@localhost bin]$ ls | grep GYY
  6. GYY20190126
  7. GYY20190127
  8. GYY20190128

(3)两数相乘

  1. #!/bin/bash
  2. #Program:
  3. # User inputs 2 integer numbers;program will cross these two numbers.
  4. #History
  5. #2018.1.29 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. echo -e "You should input 2 numbers, I will mutiplying them !\n"
  9. read -p "first number : " firstnum
  10. read -p "secong number : " secondnum
  11. total=$((${firstnum}*${secondnum}))
  12. echo -e "\nThe result of ${firstnum} * ${second} is ${total}"
  1. [gyy@localhost bin]$ chmod 777 multiplying.sh
  2. [gyy@localhost bin]$ ./multiplying.sh
  3. You should input 2 numbers, I will mutiplying them !
  4. first number : 4
  5. secong number : 5
  6. The result of 4 * is 20

(4)数值运算:透过bc计算pi

  1. #!/bin/bash
  2. #Program:
  3. # User input a scale number to calculate pi number.
  4. #History
  5. #2018.1.29 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. echo -e "This program will calculate pi value. \n"
  9. echo -e "You should input a float numer to calculate pi value.\n"
  10. read -p "The scale numbher (10~10000)? " checking
  11. num=${checking:-"10"}
  12. echo -e "Starting calcuate pi value. Be patient."
  13. time echo "scale=${num}; 4*a(1)" | bc -lq
  1. [gyy@localhost bin]$ chmod 777 cal_pi.sh
  2. [gyy@localhost bin]$ ./cal_pi.sh
  3. This program will calculate pi value.
  4. You should input a float numer to calculate pi value.
  5. The scale numbher (10~10000)? 500
  6. Starting calcuate pi value. Be patient.
  7. 3.141592653589793238462643383279502884197169399375105820974944592307\
  8. 81640628620899862803482534211706798214808651328230664709384460955058\
  9. 22317253594081284811174502841027019385211055596446229489549303819644\
  10. 28810975665933446128475648233786783165271201909145648566923460348610\
  11. 45432664821339360726024914127372458700660631558817488152092096282925\
  12. 40917153643678925903600113305305488204665213841469519415116094330572\
  13. 70365759591953092186117381932611793105118548074462379962749567351885\
  14. 75272489122793818301194912
  15. real 0m0.067s
  16. user 0m0.065s
  17. sys 0m0.003s

    2、script的执行方式差异(source,sh script,./script)

    (1)利用直接执行的方式来执行script

        利用直接指令或利用bash(或sh)来下达脚本,该script会使用一个新的bash环境来执行脚本内的指令,即script是在子程序的bash环境内执行的,当子程序完成后,在子程序内的各项变量或动作将会结束而不会传回到父程序中

    (2)利用source来执行脚本:在父程序中执行

        这样变量会传回到父程序

    因此,不注销系统而要让某些吸入~/.bashrc的设定生效时,需要使用 source ~/.bashrc 而不能使用bash ~/.bashrc

三、判断式

    test参数

    

    

    

    

    练习代码:

    判断档名类型和权限

  1. #!/bin/bash
  2. #Program:
  3. # User input a filename ,program will check the flowing:
  4. # 1.exist? 2.file/directory 3.file permissions
  5. #History
  6. #2018.1.29 GYY First release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH
  9. #1.让使用者输入档名,并且判断使用者是否真的有输入字符串
  10. echo -e "Please input a filename,I will check filename's type and permission. \n\n"
  11. read -p "Input a filename : " filename
  12. test -z ${fliename} echo "You Must input a filename." && exit 0
  13. #2.判断文件是否存在?若不存在则显示讯息并结束脚本
  14. test ! -e ${filename} && echo "The filename '${filename}' DO NOT exist" && exit 0
  15. #3.开始判断文件类型和属性
  16. test -f ${filename} && filetype="regular file"
  17. test -d ${filename} && filetype="directory"
  18. test -r ${filename} && perm="readable"
  19. test -w ${filename} && perm="${perm} writable"
  20. test -x ${filename} && perm="${perm} executable"
  21. #4.开始输出信息
  22. echo "The filename: ${filename} is a ${filetype}"
  23. echo "And the permissions for you are : ${perm}"
  1. [gyy@localhost ~]$ chmod 777 file_perm.sh
  2. [gyy@localhost ~]$ ./file_perm.sh
  3. Please input a filename,I will check filename's type and permission.
  4. Input a filename : /home/gyy
  5. ./file_perm.sh: line 13: test: echo: binary operator expected
  6. The filename: /home/gyy is a directory
  7. And the permissions for you are : readable writable executable

    利用判断符号[]

        []也可以进行数据的判断

        中括号的两端需要有空格符来分隔

        参数与test相同

        示例程序:使用[]进行判断

  1. #!/bin/bash
  2. #Program:
  3. # This program shows the user's choice
  4. #History
  5. #2018.1.29 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. read -p "Please input (Y/N): " yn
  9. [ "${yn}" == "Y" -o "${yn}" == "y" ] && echo "OK,continue" && exit 0
  10. [ "${yn}" == "N" -o "${yn}" == "n" ] && echo "OK,interrupt!" && exit 0
  11. echo "I don't know what you choice is " && exit 0
  1. [gyy@localhost bin]$ chmod 777 ans_yn.sh
  2. [gyy@localhost bin]$ ./ans_yn.sh
  3. Please input (Y/N): n
  4. OK,interrupt!
  5. [gyy@localhost bin]$ ./ans_yn.sh
  6. Please input (Y/N): y
  7. OK,continue
  8. [gyy@localhost bin]$ ./ans_yn.sh
  9. Please input (Y/N): g
  10. I don't know what you choice is

     默认变数 

         

        示例程序:一个参数分析脚本

  1. #!/bin/bash
  2. #Program:
  3. # Program shows the script name,parameters
  4. #History
  5. #2018.1.29 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. echo "The script name is ==> ${0}"
  9. echo "Total parameter number is ==> ${#}"
  10. [ "$#" -lt 2 ] && echo "The number of parameter is less than 2. Stop here." && exit 0
  11. echo "Your whole parameter is ==> '$@'"
  12. echo "The 1st parameter ==> ${1}"
  13. echo "The 2nd parameter ==> ${2}"
  1. [gyy@localhost bin]$ chmod 777 how_paras.sh
  2. [gyy@localhost bin]$ ./how_paras.sh aaa bbb ccc
  3. The script name is ==> ./how_paras.sh
  4. Total parameter number is ==> 3
  5. Your whole parameter is ==> 'aaa bbb ccc'
  6. The 1st parameter ==> aaa
  7. The 2nd parameter ==> bbb

    shift的作用

        shift后面接数字表示拿掉前面几个参数,默认拿掉一个

        示例程序:使用shift进行参数变量号码偏移

  1. #!/bin/bash
  2. #Program:
  3. # Program shows the effect of shift function.
  4. #History
  5. #2018.1.29 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. echo "Total parameter number is ==> $#"
  9. echo "Your whole parameter is ==> '$@'"
  10. shift
  11. echo "Total parameter number is ==> $#"
  12. echo "Your whole parameter is ==> '$@'"
  13. shift 3
  14. echo "Total parameter number is ==> $#"
  15. echo "Your whole parameter is ==> '$@'"
  1. [gyy@localhost bin]$ chmod 777 shift_paras.sh
  2. [gyy@localhost bin]$ ./shift_paras.sh aaa bbb ccc ddd eee fff ggg
  3. Total parameter number is ==> 7
  4. Your whole parameter is ==> 'aaa bbb ccc ddd eee fff ggg'
  5. Total parameter number is ==> 6
  6. Your whole parameter is ==> 'bbb ccc ddd eee fff ggg'
  7. Total parameter number is ==> 3
  8. Your whole parameter is ==> 'eee fff ggg'

四、条件判断式

    单层、简单条件判断式

        if [ 条件判断式 ]; then

            当条件判断式成立时,可以进行的指令工作内容

        fi   #将if反过来写,结束if

        可以使用 && 和 ||

    示例程序:使用if-then写yn判断

  1. #!/bin/bash
  2. #Program:
  3. # This program shows the user's choice
  4. #2018.1.29 GYY First release
  5. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  6. export PATH
  7. read -p "Please input (Y/N): " yn
  8. if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; then
  9. echo "OK,continue"
  10. exit 0
  11. fi
  12. if [ "${yn}" == "N" ] || [ "${yn}" == "n" ]; then
  13. echo "OK,interrupt!"
  14. exit 0
  15. fi
  16. echo "I don't know what you choice is " && exit 0
  1. [gyy@localhost bin]$ chmod 777 ans_yn-2.sh
  2. [gyy@localhost bin]$ ./ans_yn-2.sh
  3. Please input (Y/N): n
  4. OK,interrupt!
  5. [gyy@localhost bin]$ ./ans_yn-2.sh
  6. Please input (Y/N): y
  7. OK,continue
  8. [gyy@localhost bin]$ ./ans_yn-2.sh
  9. Please input (Y/N): g
  10. I don't know what you choice is

    多重复杂条件判断式

        加上else

        还可以 elif [ 条件判断式二 ]; then

        常见的port与相关网络服务的关系

        

        示例程序:网络端口侦测脚本

  1. #!/bin/bash
  2. #Program:
  3. # Using netstat and grep to detect WWW,SSH,FTP and Mail services.
  4. #2018.1.29 GYY First release
  5. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  6. export PATH
  7. echo "Now ,I will detect your Linux server's services!"
  8. echo -e "The www, ftp, ssh, and mail(smtp) will be detect!\n"
  9. testfile=/dev/shm/netstat_checking.txt
  10. netstat -tuln > ${testfile}
  11. testing=$(grep ":80" ${testfile})
  12. if [ "${testing}" != "" ]; then
  13. echo "WWW is running in your system."
  14. fi
  15. testing=$(grep ":22" ${testfile})
  16. if [ "${testing}" != "" ]; then
  17. echo "SSH is running in your system."
  18. fi
  19. testing=$(grep ":21" ${testfile})
  20. if [ "${testing}" != "" ]; then
  21. echo "FTP is running in your system."
  22. fi
  23. testing=$(grep ":25" ${testfile})
  24. if [ "${testing}" != "" ]; then
  25. echo "Mail is running in your system."
  26. fi
  1. [gyy@localhost bin]$ chmod 777 netstat.sh
  2. [gyy@localhost bin]$ ./netstat.sh
  3. Now ,I will detect your Linux server's services!
  4. The www, ftp, ssh, and mail(smtp) will be detect!
  5. SSH is running in your system.
  6. Mail is running in your system.

    case…case判断

        

        case $变量 in 当中的$变量大致有两种取得方式

            直接下达式(例如例程中的直接给${1})

            交互式(用户输入)

        /etc/init.d 中的很多启动服务就是用case…case的语句写出来的

        示例程序:case...case语句使用

  1. #!/bin/bash
  2. #Program:
  3. # This program shows "Hello World!" in your screen
  4. #History:
  5. #2019.1.28 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. case ${1} in
  9. "hello")
  10. echo "hello, how are you ?"
  11. ;;
  12. "")
  13. echo "You Must input parameters, ex> {${0} someword}"
  14. ;;
  15. *)
  16. echo "Usage ${0} {hello}"
  17. ;;
  18. esac
  1. [gyy@localhost bin]$ chmod 777 hello2.sh
  2. [gyy@localhost bin]$ ./hello2.sh
  3. You Must input parameters, ex> {./hello2.sh someword}
  4. [gyy@localhost bin]$ ./hello2.sh hello
  5. hello, how are you ?

    函数功能

        function也是拥有内建变量的,它的内变量与shell script很类似,函数名称为$0,后续接的变量依次为$1 $2

        示例程序:function功能练习

  1. #!/bin/bash
  2. #Program:
  3. # Use function to repeat information
  4. #History:
  5. #2019.1.28 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. function printit(){
  9. echo "Your choice is ${1}"
  10. }
  11. echo "This program will print your selection !"
  12. case ${1} in
  13. "one")
  14. printit 1
  15. ;;
  16. "two")
  17. printit 2
  18. ;;
  19. "three")
  20. printit 3
  21. ;;
  22. *)
  23. echo "Usage ${0} {one|two|three}"
  24. ;;
  25. esac
  1. [gyy@localhost bin]$ chmod 777 show123.sh
  2. [gyy@localhost bin]$ ./show123.sh two
  3. This program will print your selection !
  4. Your choice is 2
  5. [gyy@localhost bin]$

五、循环

     不定循环

        两种结构

        

        

        类比C前者while型 后者do…while型

        示例程序:计算1-100加和

  1. #!/bin/bash
  2. #Program:
  3. # Use loop to calculate "1+2+3+...+100"result
  4. #History:
  5. #2019.1.28 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. #while do done
  9. s=0
  10. i=0
  11. while [ "${i}" != "100" ]
  12. do
  13. i=$(($i+1))
  14. s=$(($s+$i))
  15. done
  16. echo "The result1 of '1+2+3+...+100' is ==> $s"
  17. #until do done
  18. s=0
  19. i=0
  20. until [ "${i}" == "100" ]
  21. do
  22. i=$(($i+1))
  23. s=$(($s+$i))
  24. done
  25. echo "The result2 of '1+2+3+...+100' is ==> $s"
  1. [gyy@localhost bin]$ chmod 777 cal_1_100.sh
  2. [gyy@localhost bin]$ ./cal_1_100.sh
  3. The result1 of '1+2+3+...+100' is ==> 5050
  4. The result2 of '1+2+3+...+100' is ==> 5050

    for…do…done(固定循环)

        两种结构

        

        

        第一种类似于Python的for 第二种类似于C的for

        示例程序1:利用for抓取用户id

  1. #!/bin/bash
  2. #Program:
  3. # Use id,finger command to check system account's information.
  4. #History:
  5. #2019.1.28 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. users=$(cut -d ':' -f1 /etc/passwd)
  9. for username in ${users}
  10. do
  11. id ${username}
  12. done
  1. [gyy@localhost bin]$ chmod 777 userid.sh
  2. [gyy@localhost bin]$ ./userid.sh
  3. uid=0(root) gid=0(root) groups=0(root)
  4. uid=1(bin) gid=1(bin) groups=1(bin)
  5. uid=2(daemon) gid=2(daemon) groups=2(daemon)
  6. uid=3(adm) gid=4(adm) groups=4(adm)
  7. uid=4(lp) gid=7(lp) groups=7(lp)
  8. uid=5(sync) gid=0(root) groups=0(root)
  9. uid=6(shutdown) gid=0(root) groups=0(root)
  10. uid=7(halt) gid=0(root) groups=0(root)
  11. uid=8(mail) gid=12(mail) groups=12(mail)
  12. uid=11(operator) gid=0(root) groups=0(root)
  13. uid=12(games) gid=100(users) groups=100(users)
  14. uid=14(ftp) gid=50(ftp) groups=50(ftp)
  15. uid=99(nobody) gid=99(nobody) groups=99(nobody)
  16. uid=192(systemd-network) gid=192(systemd-network) groups=192(systemd-network)
  17. uid=81(dbus) gid=81(dbus) groups=81(dbus)
  18. uid=999(polkitd) gid=998(polkitd) groups=998(polkitd)
  19. uid=74(sshd) gid=74(sshd) groups=74(sshd)
  20. uid=89(postfix) gid=89(postfix) groups=89(postfix),12(mail)
  21. uid=1000(gyy) gid=1000(gyy) groups=1000(gyy)
  22. uid=1001(user1) gid=1001(user1) groups=1001(user1)
  23. uid=1002(git) gid=1002(git) groups=1002(git)
  24. uid=998(nginx) gid=995(nginx) groups=995(nginx)
  25. uid=27(mysql) gid=27(mysql) groups=27(mysql)

        示例程序2:使用for...do...done进行数值处理

  1. #!/bin/bash
  2. #Program:
  3. # Try do calculate 1+2+...+${your_input}
  4. #History:
  5. #2019.1.28 GYY First release
  6. PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH
  8. read -p "Please input a number, I will count for 1+2+...+your_input: " nu
  9. s=0
  10. for(( i=1; i<=${nu}; i=i+1 ))
  11. do
  12. s=$((${s}+${i}))
  13. done
  14. echo "The result of '1+2+3+...+${nu}' is ==> ${s}"
  1. [gyy@localhost bin]$ chmod 777 cal_1_100-2.sh
  2. [gyy@localhost bin]$ ./cal_1_100-2.sh
  3. Please input a number, I will count for 1+2+...+your_input: 10
  4. The result of '1+2+3+...+10' is ==> 55

六、追踪与debug

    

    使用-x可以将指令的执行过程显示出来,如此可以判断程序具体执行到了哪一步

    示例:代码追踪

  1. [gyy@localhost bin]$ sh -n cal_1_100-2.sh
  2. [gyy@localhost bin]$ sh -x cal_1_100-2.sh
  3. + PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:/home/gyy/bin
  4. + export PATH
  5. + read -p 'Please input a number, I will count for 1+2+...+your_input: ' nu
  6. Please input a number, I will count for 1+2+...+your_input: 5
  7. + s=0
  8. + (( i=1 ))
  9. + (( i<=5 ))
  10. + s=1
  11. + (( i=i+1 ))
  12. + (( i<=5 ))
  13. + s=3
  14. + (( i=i+1 ))
  15. + (( i<=5 ))
  16. + s=6
  17. + (( i=i+1 ))
  18. + (( i<=5 ))
  19. + s=10
  20. + (( i=i+1 ))
  21. + (( i<=5 ))
  22. + s=15
  23. + (( i=i+1 ))
  24. + (( i<=5 ))
  25. + echo 'The result of '\''1+2+3+...+5'\'' is ==> 15'
  26. The result of '1+2+3+...+5' is ==> 15

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/877066
推荐阅读
相关标签
  

闽ICP备14008679号