1. 前言

1.1 为什么学习shell编程

Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具,Linux/UNIX系统的底层及基础应用软件的核心大部分涉及Shell脚本的内容。
每一个合格的Linux系统管理员或运维工程师,都需要熟练的编写Shell脚本语言,并能够阅读系统及各类软件附带的Shell脚本内容。只有这样才能提升运维人员的工作效率,适应日益复杂的工作环境,减少不必要的重复工作,从而为个人的职场发展奠定较好的基础。

1.2 学好Shell编程所需的基础知识

    • 能够熟练使用vim编辑器,熟悉SSH终端。
    • 有一定的Linux命令基础,至少需要掌握80个以上Linux常用命令,并能够熟练使用它。
    • 要熟练掌握Linux正则表达式及三剑客命令(grep,sed,awk)
    • 常见的Linux网络服务部署、优化以及排错。
      • 例如:crond, nfs, rsync, inotify, lanmp, sersync, ssh, Memcached, MySQL等。

2. Shell脚本入门

2.1 什么是shell

  • Shell是一个命令解释器,它在操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出屏幕返回给用户。

这种对话方式可以是:

  1. 交互的方式:从键盘输入命令,通过/bin/bash的解释器,可以立即得到shell的回应
  2. 非交互的方式:脚本

Shell的英文意思是贝壳的意思,命令解释器Shell像一个贝壳一样包住系统核心。

Shell执行命令分为两种方式:

  • 内置命令:如讲过的cd,pwd,exit和echo等命令,当用户登录系统后,shell以及内置命令就被系统载入内存,并且一直运行。
  • 一般命令:如ls,磁盘上的程序文件-->调入-->执行命令

2.2 什么是shell脚本

当Linux命令或语句不在命令行下执行(严格说,命令行也是shell),而是通过一个程序文件执行时,该程序就被称为Shell脚本或Shell程序。

用户可以在Shell脚本中敲入一系列的命令及语句组合。

这些命令,变量和流程控制语句等有机的结合起来就形成一个功能强大的Shell脚本。

 

shell程序很类似DOS系统下的批处理程序(扩展名*.bat)。

2.3 一个简单的shell脚本

首先先带领大家写一个清空/var/log/messages日志的脚本

我们需要先想明白几个问题:

  1. 日志文件在哪?

    • /var/log/messages
  2. 用什么命令可以清空文件?
    • 重定向>
  3. 写一个简单的shell脚本。
 
  • 将所有命令放在一个文件里堆积起来就形成了脚本,下面就是一个最简单的命令堆积形成的shell脚本。
  • 要使用root身份来运行这个脚本
  • 清除日志脚本
  1. [root@oldboy scripts]# cat clear_log_messages.sh
  2. #!/bin/sh
  3.  
  4. cd /var/log
  5. cat /dev/null > messages
  6. echo "Logs cleaned up."

上述脚本的问题:

  1. 如果不是root用户就无法执行清理日志
  2. 没有任何流程控制语句,简单的说,就是顺序操作,没有成功判断和逻辑严密性。
  1. # 如果不是root用户,就无法修改日志文件/var/log/messages
  2. [root@oldboy scripts]# ll /var/log/messages
  3. -rw------- 1 root root 81192 Oct 15 15:24 /var/log/messages
  4.  
  5. # 如果不是root用户就无法执行清理日志脚本
  6. [root@oldboy scripts]# ls -l clear_log_messages.sh
  7. -rw-r--r-- 1 root root 72 Oct 15 15:34 clear_log_messages.sh
  • 有没有脚本放在统一的目录下

    • /server/scripts
  • 授权:用那个用户执行文件
    • 需要对用户做判断
  • 清空错文件怎么办?
  • 错误提示:有没有成功?
  • 脚本的通用性

范例:包含命令,变量和流程控制的清空/var/log/messages日志的shell脚本

  1. #!/bin/bash
  2. # 清除日志脚本,版本2
  3.  
  4. LOG_DIR = /var/log
  5. ROOT_UID = 0 # $UID 为0的时候,用户才具有root用户的权限
  6.  
  7. # 优雅提示:要使用root用户来运行
  8. # $UID 系统变量,不需要定义
  9. if ["$UID" -ne "$ROOT_UID"]
  10. then
  11. echo "Must be root to run this script."
  12. exit 1 # 退出脚本,返回值1
  13. fi
  14.  
  15. cd $LOG_DIR || {
  16. echo "Cannot change to necessary directory.">&2
  17. exit 1
  18. }
  19.  
  20. cat /dev/null > messages && echo "Logs cleaned up."
  21. exit 0
  22.  
  23. # 退出之前返回0 表示成功,返回1 表示失败。

编写shell的步骤:

  1. 必须是root才能执行脚本,否则退出
  2. 成功切换目录 cd /var/log,否则退出
  3. 清理日志 cat /dev/null > messages,清理成功,在输出
  4. 上述条件都确认ok,echo输出。
 

清空日志的三种方法:

  1. echo >test.log
  2. >test.log
  3. cat /dev/null > test.log

shell脚本在运维工作中的作用和地位:

shell脚本擅长处理文本类型的数据,而Linux中几乎所有的配置文件,日志文件等都是纯文本类型文件。 多数启动文件都是纯文本类型的文件。

因此,学好shell脚本语言,就可以利用它在linux系统中发挥巨大的作用。

 

运维的服务,通过shell管理和配置:

  • 基础命令
  • 定时任务
  • NFS服务
  • Rsync服务
  • ssh key服务
  • Nagios监控服务
  • Apache服务
  • MySQL服务
  • Php服务
  • Nginx服务
  • Lvs+keepalive服务
  • Cacti/Mrtg流量及监控
  • iptables防火墙

2.4 shell脚本语言的种类

在Unix和Linux中主要有两大类shell:

  • Bourne shell,包括sh,ksh,and bash

    • Bourne shell,sh,已经被bash取代
    • Korn shell,ksh
    • Bourne Again shell,bash
    • Posix shell,sh
  • C shell,包括csh和 tcsh
    • C shell,csh
    • TENEX/TOPS C shell, tcsh
 

shell脚本语言是弱类型语言

  • 较为通用的shell有标准的Bourne shell(sh)和C shell(csh)。
  • 其中Bourne shell(sh)已经被bash shell取代,
    • bourne Again shell(bash)是从sh发展而来的
    • bash和sh稍有不同,它还包含了csh和ksh的特色,但大多数脚本都可以不加修改地在bash上运行。
  1. [root@oldboy scripts]# cat /etc/shells
  2. /bin/sh # 最常用的
  3. /bin/bash # 常用的,第二个的功能要比sh的功能更强
  4. /sbin/nologin # 常用,
  5. /bin/dash
  6. /bin/tcsh
  7. /bin/csh

其他语言:

  • php

    • php是网页程序,也是脚本语言。更专注于web页面开发,如:dedecms, discuz.
  • perl
    • perl脚本语言,比shell强大的多,语法灵活,复杂,实现方式很多,不易读,团队协作困难
  • python
    • 可以做脚本开发,也可以实现web开发。中等以上的公司都要求会python
 

shell脚本与php,perl,python语言的区别?

  • shell的优势在于处理操作系统底层的业务(大量的命令为它做支撑,2000多个命令都是shell支持,grep,awk,sed)
  • 一键安装,报警脚本,常规的业务应用,shell开发更简单快速。

  • php,python的优势在于开发运维工具,web界面的管理工具

 

常用操作系统的默认shell

  • linux 是 Bourne Again shell(bash)
  • solaris 是freeBSD 缺省的是 Bourne shell(sh)
  • AIX 下是 Korn Shell(ksh)
  • HP-UX 缺省的是POSIX shell(sh)

3. shell脚本的建立和执行

3.1 shell脚本的建立

shell脚本(bash shell程序)通常是在编辑器(如:vi/vim)中编写,由 Unix/Linux 命令、bash shell命令、程序结构控制语言和注释等内容组成。

 

3.1.1 脚本开头(第一行)

一个规范的shell脚本的第一行会指出由哪个程序(解释器)来执行脚本中的内容,在Linux bash办成中一般为:

  1. #!/bin/bash
  2.  

  3. #!/bin/sh

查看服务脚本的开头:

  1. [root@oldboy scripts]# head -1 /etc/init.d/mysqld
  2. #!/bin/sh

#!

"#!" 又称为幻数,在执行bash脚本的时候,内核会根据它来确定该用哪个程序来解释脚本中的内容。

这一行必须在脚本顶端的第一行,如果不是第一行则为注释。

3.1.2 bash和sh的区别

  1. [root@chensiqi1 scripts]# ll /bin/sh
  2. lrwxrwxrwx. 1 root root 4 Dec 23 20:25 /bin/sh -> bash

sh是bash的软链接,推荐标准写法#!/bin/bash

 

不同语言脚本的开头写法

下面是linux中常用脚本语言开头的编码写法,不同语言脚本的开头一般都要加上如下相应语言的开头标识内容。

  1. #!/bin/bash
  2. #!/bin/sh
  3. #!/usr/bin/awk
  4. #!/bin/sed
  5. #!/usr/bin/tcl
  6. #!/usr/bin/expect
  7. #!/usr/bin/perl
  8. #!/usr/bin/env python

ash 是GNU/Linux 默认的shell,和Bourne shell(sh)兼容,Bash采用了Korn shell(ksh)和C Shell(csh)的特色。符合 IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools 标准。

 

CentOS和RedHat Linux下默认的Shell 均为shell。

因此,在写shell脚本的时候,我们的脚本的开头也可以不加#!/bin/bash。

但如果当前的shell非你默认的shell时,比如tcsh,那么就必须要写#!。

否则脚本文件就只能执行一些命令的集合,不能够使用shell内建的指令。

所以,不管什么脚本最好都加上开头语言标识。

 

如果脚本的开头不指定解释器,那么,就要用对应的解释器来执行脚本。

例如:

  • bash test.sh
  • python test.py

下面是linux中启动文件的脚本的第一行的示例:

  1. [root@oldboy scripts]# head -1 /etc/init.d/*
  2. ==> /etc/init.d/abrt-ccpp <==
  3. #!/bin/bash
  4.  
  5. ==> /etc/init.d/abrt-oops <==
  6. #!/bin/bash
  7.  
  8. ==> /etc/init.d/atd <==
  9. #!/bin/sh
  10.  
  11. ==> /etc/init.d/auditd <==
  12. #!/bin/bash
  13.  
  14. ==> /etc/init.d/blk-availability <==
  15. #!/bin/bash
  16.  
  17. ==> /etc/init.d/chktestd <==
  18. # chkconfig:23456 66 33
  19.  
  20. ...
  21.  
  22. ==> /etc/init.d/udev-post <==
  23. #!/bin/bash

bash版本:

  1. [root@oldboy /]# bash --version
  2. GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
  3. Copyright (C) 2009 Free Software Foundation, Inc.
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  5.  
  6. This is free software; you are free to change and redistribute it.
  7. There is NO WARRANTY, to the extent permitted by law.

bash漏洞【破壳漏洞】

如果是比较老的系统,需要注意shell的版本太低,有漏洞,需要升级shell

  1. [root@chensiqi1 scripts]# yum -y update bash
  2.  
  3. #验证方法
  4. [root@chensiqi1 scripts]# env x='(){ :;};echo be careful' bash -c "echo this is a test"
  5. this is a test
  6.  
  7. 如果返回2
  8. be careful
  9. this is a test
  10. 这样的结果的话,请尽快升级。

3.1.3 脚本注释 "#"

在shell脚本中,跟在"#"后面的内容表示注释,用来对脚本进行注释说明。

 

3.2 shell脚本的执行

当shell脚本以非交互的方式运行时,它会先查找环境变量ENV,该变量指定了一个环境文件(通常是.bashrc),然后从该环境变量文件开始执行,当读取了ENV文件后,SHELL才开始执行shell脚本中的内容。

 

Shell脚本的执行通常可以采用以下三种方式:

  1. bash script-name 或 sh script-name(推荐使用)

    • 这种方法是当脚本本身没有可执行权限"x"时常使用的方法。
    • 或者文件开头没有指定解释器
  2. path/script-name 或 ./script-name (当前路径下执行脚本)
    • 这种方法首先需要给脚本文件可执行权限。

      • chmod +x script-name
  3. source script-name 或 . script-name 
    • source 或.在执行这个脚本的同时,可以将脚本中的函数和变量加载到当前Shell
    • 不会产生子shell
    • 又有点像nginx的include功能。
 

第三种方法通常是使用source 或"."点号读入或加载指定的shell脚本文件,然后,依次执行指定shell脚本文件 san.sh 中的所有语句。

这些语句将作为当前 父shell脚本 father.sh 进程的一部分运行。

因此,使用source 或者"."点号可以将 san.sh 自身脚本中的变量的值或函数等的返回值传递到当前的父shell脚本father.sh中使用。

这是第三种方法和前两种办法的最大区别。

 

source或者"."点号命令的功能:

  • 在当前shell中执行source或者"."点号,加载并执行相关脚本文件中的命令及语句
  • 而不是产生一个子shell来执行命令中的文件。
 

示例:

  1. # 文件准备
  2. [oldboy@oldboy scripts]$ cat test.sh
  3. echo 'I am oldboy'
  4.  
  5. # 使用第一种方法,指定解释器去执行shell脚本
  6. [oldboy@oldboy scripts]$ sh test.sh
  7. I am oldboy
  8. [oldboy@oldboy scripts]$ bash test.sh
  9. I am oldboy
  10.  
  11. # 第二种方法,需要给文件添加执行权限后,才能成功执行
  12. [oldboy@oldboy scripts]$ ./test.sh
  13. -bash: ./test.sh: Permission denied
  14. [oldboy@oldboy scripts]$ sudo chmod +x test.sh
  15. [oldboy@oldboy scripts]$ ./test.sh
  16. I am oldboy
  17.  
  18. # 第三种方法:source和.
  19. [oldboy@oldboy scripts]$ source test.sh
  20. I am oldboy
  21. [oldboy@oldboy scripts]$ . test.sh
  22. I am oldboy

下面用示例说明source或 . 执行shell脚本文件和前两种执行方式的区别:

  1. # 文件准备
  2. [root@oldboy scripts]# echo 'userdir=`pwd`' >testsource.sh
  3. [root@oldboy scripts]# cat testsource.sh
  4. userdir=`pwd`
  5.  
  6. # 第一种方法执行,执行echo $userdir 输出结果为空
  7. [root@oldboy scripts]# sh testsource.sh
  8. [root@oldboy scripts]# echo $userdir
  9.  
  10. # 第三种方法执行,执行echo $userdir 输出结果为 /server/scripts
  11. [root@oldboy scripts]# source testsource.sh
  12. [root@oldboy scripts]# echo $userdir
  13. /server/scripts

3.3 Shell脚本开发的规范和习惯

  1. 开头指定脚本解释器
  2. 开头加版本版权等信息,可配置~/.vimrc文件自动添加
  3. 脚本不要用中文注释,尽量用英文注释
  4. 脚本以.sh为扩展名
  5. 放在统一的目录
  6. 代码书写优秀习惯
    • 成对的内容一次性写出来,防止遗漏,如[],'',""等
    • []两端要有空格,先输入[]退格,输入2个空格,再退格写。
    • 流程控制语句一次书写完,再添加内容。
    • 通过缩进让代码易读
    • 脚本中的引号都是英文状态下的引号,其他字符也是英文状态。
 

1. 开头指定脚本解释器

  1. [root@oldboy scripts]# head -1 /etc/init.d/mysqld
  2. #!/bin/sh
  3.  
  4. [root@oldboy scripts]# head -1 /etc/init.d/svnserve
  5. #!/bin/bash

2. 开头加版本版权等信息,可配置~/.vimrc文件自动添加

可配置vim编辑文件时自动加上以上信息,方法是修改~/.vimrc配置文件

  1. #!/bin/bash
  2. # Date 2019-10-16
  3. # Author: Created by Zoe
  4. # Mail: 740466595@qq.com
  5. # Func: This script is for MySQL backup
  6. # V2.1

3. 脚本中不用中文注释,尽量用英文注释

4. 脚本以.sh扩展名

5. 放在统一的目录

6. 代码书写优秀习惯

  • 成对的内容一次性写出来,防止遗漏,如[],'',""等

    • (), [], '',"", ``
  • []两端要有空格,先输入[]退格,输入2个空格,再退格写。

    • [ contents ]
  • 流程控制语句一次书写完,再添加内容。
    1. if 条件语句
    2. then
    3. 内容
    4. fi
    1. for
    2. do
    3. 内容
    4. done
  • 通过缩进让代码易读
  • 脚本中的引号都是英文状态下的引号,其他字符也是英文状态。

3.4 shell脚本开发制度及规范

【shell】shell脚本入门的更多相关文章

  1. Linux Shell脚本入门--cut命令

    Linux Shell脚本入门--cut命令 cut cut 命令可以从一个文本文件或者文本流中提取文本列. cut语法 [root@www ~]# cut -d'分隔字符' -f fields &l ...

  2. linux的shell脚本入门

    Linux shell脚本入门教程 为什么要进行shell编程 在Linux系统中,虽然有各种各样的图形化接口工具,但是sell仍然是一个非常灵活 的工具.Shell不仅仅是命令的收集,而且是一门非常 ...

  3. (一)shell脚本入门

    shell脚本入门 1.脚本格式 脚本以#!/bin/bash 开头(指定解析器) 2.第一个shell脚本:helloworld (1)需求:创建一个shell脚本,输出helloworld 运行: ...

  4. Linux Shell脚本入门--wget 命令用法详解

    Linux Shell脚本入门--wget 命令用法详解 wget是在Linux下开发的开放源代码的软件,作者是Hrvoje Niksic,后来被移植到包括Windows在内的各个平台上.它有以下功能 ...

  5. Shell脚本 (一) 概述、解析器、脚本入门

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一. Shell 脚本概述 1. Shell 的 含义: Shell 是一个用C语言编写的程序,它是用户 ...

  6. SHELL (1) —— shell脚本入门

    摘自:Oldboy Linux运维——SHELL编程实战 SHELL Shell是一个命令解释器,解释执行用户输入的命令及程序等,用户每输入一条命令,Shell就解释执行一条.这种从键盘以输入命令,就 ...

  7. shell脚本 入门 —— 符号篇

    shell Shell就是一个命令行解释器,它的作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行一条,这种方式称为交互式(Interactive). Shell还有一种执行命令的方式称 ...

  8. shell脚本入门笔记

    转载:http://mp.weixin.qq.com/s?__biz=MzA3MTIxNzkyNg==&mid=204081791&idx=1&sn=27bb1d827e0f8 ...

  9. 简单的 Shell 脚本入门教程

    Shell脚本 运作方式与解释型语言相当,如果有语言基础,学起 Shell 脚本就非常容易,但是 Shell 与常见的语言不同,一些常见的函数在 Shell 中需要组合一些命令得以实现 工具推荐 Sh ...

随机推荐

  1. C# 快速开发框架搭建—开发工具介绍

    C# 快速开发框架搭建—开发工具介绍 一.VS2013,SQL SERVER R22008 以上两种工具如有不会者自行百度学习下. 二.动软代码生成器 对于经典的三层架构框架来说,使用动软代码生成器会 ...

  2. Codeforces - Watermelon

    A. Watermelon time limit per test 1 second memory limit per test 64 megabytes input standard input o ...

  3. Shell脚本的编写及测试

                                                      Shell脚本的编写及测试 1.1问题 本例要求两个简单的Shell脚本程序,任务目标如下: 编写一 ...

  4. 关于wget下载jdk问题解决

    问题: 直接从jdk官网下载会出现: 正在解析主机 login.oracle.com (login.oracle.com)... 156.151.58.18正在连接 login.oracle.com ...

  5. 如何增加Tomcat内存

    有时候在开发中,常常遇到内存溢出问题,很有可能项目过大,导致Tomcat内存不足问题,那么此时就要给Tomcat添加内存了,如,操作如下 1. 先找到Tomcat目录下的catalina.bat文件

  6. python 判断一个字符串是否是小数

    """练习判断一个小数1.判断是否合法2.合法需要有一个小数点3.小数点左边必须是个整数,右边必须是个正整数 """ def xiaoshu ...

  7. 全方位认识HBase:一个值得拥有的NoSQL数据库(一)

    前言:说起HBase这门技术,在认知上对于稍微接触或使用过它的人来讲,可能只是百千数据库中一个很普通的库,大概就像我对Redis的认知一样:缓存嘛!可对于HBase,我确实是带着某些感情在的.今日突然 ...

  8. 【Java】【设计模式 Design Pattern】单例模式 Singleton

    什么是设计模式? 设计模式是在大量的实践中总结和理论化之后的最佳的类设计结构,编程风格,和解决问题的方式 设计模式已经帮助我们想好了所有可能的设计问题,总结在这些各种各样的设计模式当中,也成为GOF2 ...

  9. 模仿NetFlix首页效果

    之前写过UWP 带左右滚动按钮的横向ListView———仿NetFlix首页河的设计,讲述了如何设计一个带有左右滚动按钮横向的ListView. 不过我在半年之前挖了一个坑,由于工作关系,没时间来填 ...

  10. 学习Salesforce | 带你解锁Superbadge的真正作用

    Superbadges是对专业知识和技能的一种认可,通过解决企业在实际业务场景中遇到的复杂问题,展示你的Salesforce专业技能. 要想获得Superbadge,首先需要完成Trailhead徽章 ...