5-27课堂笔记

1.1 为什么要学Shell编程?

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

1.2  学好Shell编程所需的Linux基础

1)熟练使用vim编辑器。

2)熟练掌握120个左右Linux运维基础命令。

3)熟练掌握Linux正则表达式及三剑客。

1.3  如何才能学好Shell编程

1)掌握Shell脚本基本语法的方法。

2)掌握Shell脚本的各种常见语法。

3)从简单做起,简单判断,简单循环。

4)锻炼编程思维,形成自己的脚本开发风格,要多试着去解决企业实际问题。切记拿来主义。

1.3  学好Shell编程最关键的条件

1)多练习,多敲。学好Shell编程,没有捷径可走。

2.  Shell脚本初步入门

2.1  什么是Shell

Shell就是一个命令解释器,它的作用就是解释执行用户输入的命令及程序等,用户输入的每一条命令,Shell就解释执行一条。这种从键盘一输入命令,就可以立即得到回应的对话方式,称为交互式的方式。下图就是一个命令解释器Shell在操作系统中所处位置的基本图解。

2.2  什么是Shell脚本

当命令或程序语句不在命令行执行,而是通过一个程序文件来执行时,该程序就被称为Shell脚本,也就是说,Shell脚本就是由命令、变量、流程控制语句等组成的。

初学者如果想要快速的掌握Shell脚本的编写方法,最有效的思路就是采用电子游戏中过关的方式,如下:

第一关:必须是root才能执行脚本,否则给出友好提示并终止脚本运行。

第二关:切换目录的时候,必须要成功切换才行,否则给出友好提示并终止脚本运行。

第三关:清理日志文件时,若清理成功,则给出正确提示。

第四关:通关成功或通关失败,分别给出相应的提示。

2.3  Shell脚本在Linux运维工作中的地位

Shell脚本语言很适合用于处理纯文本类型的数据,在Linux系统中几乎所有的配置文件、日志文件及绝大多数的启动文件都是纯文本类型的文件。那么可想而知,Shell脚本在Linux运维中的地位有多重要了,就如下图所示一样:

2.4  脚本语言的种类

2.4.1  Shell脚本语言的种类

Shell脚本语言是弱类型语言(无须定义变量的类型即可使用),在Unix\Linux中主要有两大类Shell:一类是Bourne shell,另一类是C  shell。

1.  Bourne shell

Bourne shell 又包括了Bourne shell(sh)、Korn shell(ksh)、Bourne Again shell(bash)三种类型。

2.  C shell

C  shell 又包括csh、tcsh两种类型。

可以通过以下命令查看CentOS7系统的Shell支持情况。

[root@web01 ~]# cat /etc/shells /bin/sh/bin/bash/usr/bin/sh/usr/bin/bash

2.4.2  其他常用的脚本语言种类

1.  PHP语言

PHP是网页程序语言,同时也是脚本语言。它是一款更专注于Web页面开发(前端展示)的语言。

2.  Perl语言

Perl脚本语言比Shell脚本语言更加强大,它的语法灵活、复杂,在实现不同的功能时可以用多种不同的方式,缺点是不易读,团队协作困难。

3.  Python语言

Python不但可以用于脚本程序开发,还可以实现Web页面程序开发,甚至还可以实现软件的开发、游戏开发、大数据开发、移动端开发。

2.4.3  Shell脚本语言的优势

Shell脚本语言的优势在于处理偏操作系统底层的业务。对于一些常见的系统脚本,使用Shell脚本开发会更简单、更快速,例如:让软件一键自动化安装、优化,监控报警脚本,软件启动脚本,日志分析脚本等。

2.5  常用操作系统默认的Shell

Linux系统下默认的Shell是Bourne Again shell(bash);Solaris和FreeBSD下默认的是Bourne(sh);AIX下默认的是Korn Shell(ksh)。

通过以下两种方法可以查看CentOS Linux系统默认的Shell。

方法1:

[root@web01 ~]# echo $SHELL/bin/bash

方法2:

[root@web01 ~]# grep"^root"/etc/passwd|awk -F":"'{print $NF}'/bin/bash

2.6  Shell脚本的建立和执行

2.6.1  Shell脚本的建立

1.  脚本开头(第一行)

一个规范的Shell脚本在第一行会指出由哪个程序(解释器)来执行脚本中的内容,如下:

#!/bin/bash或#!/bin/sh

期中,开头的#号又称为幻数符,在执行bash脚本的时候,内核会根据“#!”后的解释器来确定用哪个程序解释这个脚本中的内容。

2.  bash与sh的区别

sh为bash的软连接,大多数情况下,脚本开头使用“#!/bin/bash”和“#!/bin/sh”是没有区别的,但更加规范的写法是在脚本的开头使用“#!/bin/bash”。

[root@m01 ~]# ll /bin/shlrwxrwxrwx.1root root4Apr2819:23/bin/sh -> bash

Linux中常用脚本开头的写法如下:

#!/bin/sh#!/bin/bash#!/usr/bin/awk#!/bin/sed#!/usr/bin/tcl#!/usr/bin/expect      #<===expect语言解释器#!/usr/bin/perl        #<===perl语言解释器#!/usr/bin/env python  #<===python语言解释器

如果在脚本开头的第一行不指定解释器,那么就要用对应的解释器来执行脚本,这样才能确保脚本正确执行。例如:

Shell脚本,用bash或sh test.sh来执行。

Python脚本,用python test.py来执行。

expect脚本,用expect test.exp来执行。

3.  脚本注释

在Shell脚本中,#号后面的内容表示注释,用来对脚本进行注释说明,注释部分不会被当做程序来执行,仅仅是给开发者和使用者看的。注释的时候尽量不要用中文,脚本内容中也不要有中文。

2.6.2  Sehll脚本的执行

当Shell脚本运行时,它会先查找系统环境变量ENV,该变量指定了环境变量文件(加载顺序通常是/etc/profile、~/.bash_profile、~/.bash、/etc/bashrc等),在加载了上述环境变量文件后,Shell就开始执行Shell脚本中的内容。

Shell脚本执行的顺序是从上至下、从左至右依次执行每一行的命令及语句的,即执行完了一个命令后再执行下一个,如果在Shell脚本中遇到子脚本(即脚本嵌套)时,就会先执行子脚本的内容,完成后再返回父脚本继续执行父脚本内后续的命令及语句。

通常情况下,在执行Shell脚本时,会向系统内核请求启动一个新的进程,以便在该进程中执行脚本的命令及子Shell脚本,基本流程如下所示:

特别注意:设置Linux的crond任务时,最好能在定时任务脚本中重新定义系统环境变量,否则,一些系统环境变量将不会被加载。

Shell脚本执行的方式

1)bash  script-name 或 sh script-name:这是当脚本文件本身没有可执行权限时常用的方法。

2)cat script-name|sh

3)sh

4)./script-name:在当前路径下执行脚本文件,需要脚本文件本身有可执行权限。

5)source script-name 或 . script-name:不需要脚本文件有可执行权限。

范例2-4:创建模拟脚本test.sh。

第1种方法执行:

[root@m01 ~]# echo 'echo I am oldboy' > test.sh

[root@m01 ~]# cat test.shecho I am oldbo

y[root@m01 ~]# sh test.shI am oldboy

[root@m01 ~]# bash test.shI am oldboy

第2种方法执行:

[root@m01 ~]# ll test.sh -rw-r--r--1root root17May2719:50test.sh

[root@m01 ~]# ./test.sh  -bash:./test.sh:Permission denied#<===由于没有可执行权限,所以执行失败,甚至连tab补全都不可以

[root@m01 ~]# . test.sh #<===虽然没有可执行权限,但是可以用.或source来执行I am oldboy[root@m01 ~]# source test.sh  #<===.或source命令功能相同,都是读入脚本并执行脚本I am oldboy

给test.sh添加可执行权限,命令如下:

[root@m01 ~]# chmod u+x test.sh

 [root@m01 ~]# ./test.sh I am oldboy

第3种方法执行:

[root@m01 ~]# echo 'userdir=`pwd`' > testsource.sh

[root@m01 ~]# cat testsource.shuserdir=`pwd`

[root@m01 ~]# sh testsource.sh  #<===执行后没有内容显示

[root@m01 ~]# echo $userdir  #<===echo 变量也没有内容显示,解决方法如下

[root@m01 ~]# source testsource.sh

[root@m01 ~]# echo $userdir/root

上述结果总结:

通过source或“.”加载执行过的脚本,由于是在当前Shell中执行脚本,因此脚本运行结束后,脚本中的变量(包括函数)值在当前Shell依然存在,而sh和bash执行脚本都会启动新的子Shell执行,执行完后回退到父Shell。  因此,变量(包括函数)值等无法保留。在进行Shell脚本开发时,如果脚本中有引用或执行其他脚本的内容或配置文件需求时,最好用“.”或source先加载该脚本或配置文件,处理后,再将它们加载到脚本下面,就可以调用source加载的脚本及配置文件中的变量函数等内容了。

第4种方法执行:

[root@web01 /server/scripts]# ll oldboy.sh-rw-r--r-- 1 root root 246 May 31 15:24 oldboy.sh

[root@web01 /server/scripts]# cat oldboy.sh

#!/bin/bash

##############################################################

# File Name: test.sh

# Version: V1.0

# Author: oldboy

# Organization: www.oldboyedu.com

##############################################################

echo'I am oldboy.'

[root@web01 /server/scripts]# sh < oldboy.sh    <===不推荐使用这种方法I am oldboy.

[root@web01 /server/scripts]# cat oldboy.sh|bashI am oldboy.

已知如下命令返回结果,请问echo $used的返回结果为()?

[root@web01 /server/scripts]# cat test.sh

#!/bin/bash

##############################################################

# File Name: test.sh

# Version: V1.0

# Author: oldboy

# Organization: www.oldboyedu.com

##############################################################

user=`whoami`

[root@web01 /server/scripts]

# sh test.sh

[root@web01 /server/scripts]# echo $user

参考答案如下:

a)当前用户

b)root

c)没有内容输出

通过上述面试题得出如下结论:

子Shell脚本会直接继承父Shell脚本的变量、函数等,反之则不能。

如果希望父Shell也能够继承子Shell的脚本变量、函数等,就要使用source或.在父Shell脚本中事先加载子Shell脚本,也就是先把结果弄出来。

2.6.3 Shell脚本开发的基本习惯推荐

1)Shell脚本的第一行是指定脚本解释器,通常为:

#!/bin/bash或#!/bin/sh                                                                                                                              ~                                                                                                                                      ~

2)Shell脚本的开头会加版本、版权等信息:

#!/bin/bash

##############################################################

# File Name: 1.sh

# Version: V1.0

# Author: oldboy

# Organization: www.oldboyedu.com

############################################################## 

3)在Shell脚本中尽量不要用中文(不限于注释)。

4)Shell脚本的命名应以.sh为扩展名。

[root@web01 /server/scripts]#ls1.sh222.sh9_1.sh9_2_2.sh9_2_3.sh9_2.sholdboy.sholdgirl.shplush_color.shtest.sh

5)Shell脚本应存放在固定的路径下。

[root@web01 /server/scripts]#

以下则是Shell脚本代码书写的良好习惯。

1)成对的符号应尽量一次性写出来,然后退格在符号里增加内容,以防止遗漏。这些成对的符号包括:

{ }[ ]' '` `" "

2)中括号([ ])两端至少要有一个空格。

[ $a -eq0]

3)对于流程控制语句,应一次性将格式写完,再添加内容。

比如,一次性完成if语句的格式,应为:

#!/bin/bash

##############################################################

# File Name: 5.sh

# Version: V1.0

# Author: oldboy

# Organization: www.oldboyedu.com

##############################################################

if

then

fi

一次性完成for循环语句的格式,应为:

#!/bin/bash

###############################################################

# File Name: 5.sh

# Version: V1.0

# Author: oldboy

# Organization: www.oldboyedu.com

##############################################################

for

do

done

4)通过缩进让代码更易读,比如:

#!/bin/bash

############################################################### 

#File Name: 5.sh

# Version: V1.0

# Author: oldboy

# Organization: www.oldboyedu.com

##############################################################

if[ 条件内容 ]then内容fi

5)对于常规变量的字符串定义变量应加双引号,并且等号前后不能有空格,需要强引用的(指所见即所得的字符引用),则用单引号(’’),如果是命令的引用,则用反引号(``)。例如:

#!/bin/bash

###############################################################

# File Name: 5.sh

# Version: V1.0

# Author: oldboy

# Organization: www.oldboyedu.com

##############################################################

OLDBOY="test.txt"

a=`who`

6)脚本中的单引号、双引号及反引号必须为英文状态下的符号,其实所有的Linux字符及符号都应该是英文状态下的符号,这点需要特别注意

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容