shell脚本编写守则

现在centos7中使用的是bash软件,通过以下命令可以查看bash版本:

[root@localhost ~]# cat /etc/redhat-release     #查看系统的版本
CentOS Linux release 7.5.1804 (Core)     #我这里使用的是centos 7.5 1804
[root@localhost ~]# bash --version   #查看bash的版本
GNU bash, 版本 4.2.46(2)-release (x86_64-redhat-linux-gnu) #这一行就是bash版本
Copyright (C) 2011 Free Software Foundation, Inc.
许可证 GPLv3+: GNU GPL 许可证版本3或者更高 <http://gnu.org/licenses/gpl.html>

这是自由软件,您可以自由地更改和重新发布。
在法律允许的范围内没有担保.

若生产环境下的服务器使用的是较老版本的系统及shell,那么建议将其升级到最新版的shell,因为近两年老版本被暴露出存在较严重的安全漏洞。

bash软件曾经爆出了严重漏洞(破壳漏洞),凭借此漏洞,别人可能会接管计算机的整个操作系统,得以访问各种系统内的机密信息,并对系统进行更改等。任何人的计算机系统,如果使用了bash软件,都需要立即打上补丁。检测系统是否存在漏洞的方法为:

#测试系统是否存在漏洞
[root@localhost ~]# env x='() {:;}; echo be careful' bash -c "echo this is a test"
this is a test

返回上面的内容“this is a test”,则表示正常,若返回如下内容,则需要升级bash了,不过,仅仅是用于学习和测试就无所谓了。

[root@localhost ~]# env x='() {:;}; echo be careful' bash -c "echo this is a test"
be careful
this is a test

提示:如果没有输出be careful,则不需要升级。

升级方法如下:

[root@localhost ~]# rpm -qa bash    #升级前的bash版本
bash-4.2.46-30.el7.x86_64
[root@localhost ~]# yum -y update bash    #执行升级命令
[root@localhost ~]# rpm -qa bash  #升级后的bash版本
bash-4.2.46-31.el7.x86_64

编写shell脚本守则:

1、脚本开头一行注明使用的是哪种解释器,如:#!/bin/sh、#!/bin/bash......。
2、规范脚本的后缀名称,如果是Shell脚本,就是“.sh”;如果是Python脚本,就是“.py”;如果是expect脚本,就是“.exp”。
3、写好注释,不挨骂,脚本中,除第一行使用#号后指定shell,以下所有的#号都表示注释,可以和代码共用一行,也可单独写一行,最好不要出现中文,若不写注释,会遭人骂的,可能自己过段时间也看不懂自己写的脚本了。

shell脚本的执行:

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

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

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

  • bash script-name或sh script-name:这是当脚本文件本身没有可执行权限(即文件权限属性x位为-号)时常使用的方法,或者脚本文件开头没有指定解释器时需要使用的方法。这也是推荐使用的方法;
  • path/script-name或./script-name:指在当前路径下执行脚本(脚本需要有执行权限),需要将脚本文件的权限先改为可执行(即文件权限属性加x位),具体方法为chmod+x script-name。然后通过脚本绝对路径或相对路径就可以直接执行脚本了。
  • source script-name或.script-name:这种方法通常是使用source或“.”(点号)读入或加载指定的Shell脚本文件(如san.sh),然后,依次执行指定的Shell脚本文件san.sh中的所有语句。这些语句将在当前父Shell脚本father.sh进程中运行(其他几种模式都会启动新的进程执行子脚本)。因此,使用source或“.”可以将san.sh自身脚本中的变量值或函数等的返回值传递到当前父Shell脚本father.sh中使用。这是它和其他几种方法最大的区别。
  • sh\<script-name或cat scripts-name|sh:同样适用于bash,不过这种用法不是很常见,但有时也可以有出奇制胜的效果,例如:不用循环语句来实现精简开机自启动服务的案例,就是通过将所有字符串拼接为命令的形式,然后经由管道交给bash操作的。

结论:

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

编写shell的守则:

  • shell脚本的第一行是指定脚本解释器(不是必须的);
  • shell脚本的开头会加版本、版权等信息,通常由脚本中的第二行开始写(不是必须的);
  • 在shell脚本中尽量不用中文(不仅仅是说注释);
  • shell脚本的命名应以.sh为扩展名。
  • shell脚本应存放在固定的路径下,一般是“/server/scripts”
    以下则是shell脚本代码书写的良好习惯:
  • 成对的符号应该尽量一次写出来,然后退格在符号里增加内容,以防止遗漏。这些符号一般是“{ }”“[ ]”.......
  • 中括号[ ]两端至少要有一个空格,因此,键入括号时即可留出空格,然后在退格键进入中间的内容,并确保两端都至少有一个空格,也就是说先键入一对中括号,然后退一格,输入两个空格,再退一格,双中括号[ [ ] ]的写法也一样。
  • 对于流程控制语句,应一次性将格式写完,再添加内容,很多语言中都是这样的,如:
    一次性完成if语句的格式:
    if 条件内容
    then
    内容
    fi
    一次性完成for循环语句的格式:
    for
    do
    内容
    done

while和until,case等语句也是一样。

  • 通过缩进让代码更易读,比如上面的if、for语句。
  • 对于常规变量的字符串定义变量值应加双引号,并且等号前后不能有空格,需要强引用的(指所见即得的字符引用),则用单引号'',如果是命令的引用,则用反单引号``(该键位于esc键下面),例如:username="lv jian zhao"
  • 脚本中的单引号、双引号及反引号必须是英文状态下的符号,其实所有的Linux字符及符号,都应该是英文状态下的符号,这点需要特别注意。
    说明:好的习惯可以让我们避免很多不必要的麻烦,提升工作效率。

———————— 本文至此结束,感谢阅读 ————————

猜你喜欢

转载自blog.51cto.com/14154700/2432361