Shel脚本-初步入门之《06》

Shel脚本-初步入门-06 Shell 脚本的建立和执行

6、Shell 脚本的建立和执行

6.1 Shell脚本的建立

Linux 系统中,Shell 脚本(bash Shell 程序)通常是在编辑器 vi/vim 中编写的。推荐使用 vim 编辑器来编写。

事先做一个别名 alias vi='vim',使其永久生效,方法如下:

echo "alias vi='vim'" >>/etc/profile
tail -1 /etc/profile
source /etc/profile
alias

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

1. 脚本开头(第一行)

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

#!/bin/bash
or
#!/bin/sh # 255 个字符以内

注意:这一行必须位于每个脚本顶端的第一行,如果不是第一行则为脚本注释行,例如:

cat mine.sh

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

2. bash 与 sh 的区别

早期的bashsh 稍有不同,它还包含了 cshksh 的特色,但大多数脚本都可以不加修改地在 sh 上 运行,比如:

ll /bin/sh
ll /bin/bash

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

提示:shbash 的软连接,大多数情况下,脚本的开头使用 #!/bin/bash#!/bin/sh 是没有区别的,但更规范的写法是在脚本的开头使用 #!/bin/bash

一般情况下,在安装 Linux 系统时会自动安装好 bash 软件,查看系统的 bash 版本的命令如下:

cat /etc/redhat-release
bash --version 

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

检测系统是否存在漏洞:

env x='() { :;}; echo be careful' bash -c "echo this is a test"

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

如果返回如下两行,则表示需要尽快升级 bash 了:

be careful
this is a test

升级方法为:

yum -y update bash
rpm -qa bash

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

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

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

  1 #!/bin/sh
  2 #!/bin/bash
  3 #!/usr/bin/awk
  4 #!/bin/sed
  5 #!/usr/bin/tcl
  6 #!/usr/bin/expect # expect 解决交互式的语言开头解释器
  7 #!/usr/bin/perl # Perl 语言解释器
  8 #!/usr/bin/env python # Python 语言解释器

3. 脚本注释

Shell 脚本中,跟在 # 后面的内容表示注释,用来对脚本进行注释说明,注释部分不会被当作程序来执行,仅仅是给开发者和使用者看的,系统解释器是看不到的,更不会执行。提示:注释尽量不要用中文,在脚本中最好也不要有中文。

6.2 Shell脚本的执行

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

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

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

特殊技巧:设置 Linuxcrond 任务时,最好能在定时任务脚本中重新定义系统环境变量,否则,一些系统环境变量将不会被加载。

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

  • 1)bash/sh script-name:这是当脚本文件本身没有可执行权限时常使用的方法,或者脚本文件开头没有指定解释器时需要使用的方法。
  • 2)path/script-name 或者 ./script-name:指在当前路径下执行脚本(脚本需要有执行权限)方法为:chmod +x script-name
  • 3)source script-name 或者 . script-name:这种方法通常使用 source. (点号)读入或加载指定的 Shell 脚本文件,然后,依次执行指定的 Shell 脚本文件中的所有语句。这些语句将在当前父 Shell 脚本 father.sh 进程中运行(其他几种模式都会启动新的进程执行子脚本)。因此,使用 source. (点号)可以将指定的 Shell 脚本文件中的变量值或函数等的返回值传递到当前父 Shell 脚本 father.sh 中使用。
  • 4)sh<script-namecat script-name | sh :同样适用于 bash,不过这种用法不是很常见,但有时也可以有出奇制胜的效果。

范例1:创建模拟脚本 mine.sh ,并输入如下内容:

cat mine.sh

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

使用第 1 种方法实践,命令如下:

cat mine.sh
sh mine.sh
bash mine.sh

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

使用第 2 种方法实践,命令如下:

ll mine.sh
./mine.sh

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

虽然没有权限的 mine.sh 脚本不能直接被执行,但是可以用 source. (点号)来执行,如下:

ll mine.sh
. mine.sh
source mine.sh

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

提示: source. (点号)的功能相同,都是读入脚本并执行脚本。

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

ll mine.sh
chmod +x mine.sh
!ll
 ./mine.sh

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

可以看到,给 mine.sh 加完可执行权限后就能执行了,这种方法在使用前每次都需要给定执行权限,但容易忘记。

使用第 3 种方法实践时,会将 source. 执行的脚本中的变量值传递到当前的 Shell 中,如下:

echo 'userdir=`pwd`' >mine.sh
cat mine.sh
sh mine.sh
echo $userdir

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

通过 sh/bash 命令执行过脚本,变量值不会赋值给当前 Shell 窗口,使用 source. 执行,结果如下:

echo $userdir
source mine.sh
!echo

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

结论: 通过 source. 加载执行过的脚本,由于是在当前 Shell 中执行脚本,因此在脚本结束后,脚本中的变量(包括函数)值在当前 Shell 中依然存在,而 shbash 执行脚本都会启动新的子 Shell 执行,执行完后退回到父 Shell 。因此,变量(包含函数)值等无法保留。

使用第 4 种方法实践,命令如下:

chmod -x mine.sh
ll mine.sh
echo "echo 'I love linux.'" >mine.sh
cat mine.sh
sh <mine.sh
cat mine.sh|bash

Shel脚本-初步入门之《06》

Shel脚本-初步入门之《06》

6.3 Shell脚本开发的基本规范及习惯

Shell 脚本的开发规范及习惯非常重要,虽然这些规范不是必须遵守的但有了好的规范和习惯,可以大大提升开发效率,并能在后期降低对脚本的维护成本。

  • 1)Shell 脚本的第一行是指定脚本解释器,通常为
#!/bin/bash
or
#!/bin/sh
  • 2)Shell 脚本的开头会加版本、版权等信息
# File Name: /server/scripts/backup_rsync.sh
# Version: V1.0
# Author: Mine
# Organization: www.cnblogs.com/wjcLinux/
# Created Time : 2019-05-10 16:24:08
# Description:  deploy the rsync  service

说明:以上两点在 Linux 系统场景中不是必需的,只属于优秀规范和习惯,后面有自动加载此内容的方法。(可以修改 ~/.vimrc 配置文件配置 vim 编辑文件时自动加上以上信息的功能。)

  • 3)在 Shell 脚本中尽量不用中文(不限于注释)。尽量用英文注释,防止本机或切换系统环境后中文乱码的困扰,若非要加中文,请根据自身的客户端对系统进行字符集调整,如:export LANG="zh_CN.UTF-8" ,并在脚本中重新定义字符集设置,和系统保持一致。
  • 4)Shell 脚本的命名应以 .sh 为扩展名。例如:script-name.sh
  • 5)Shell 脚本应存放在固定的路径下。例如:/server/scripts

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

  • 1)成对的符号应尽量一次性写出来,然后退格在符号里增加内容,以防止遗漏,如:
{ }、[ ]、" "、' ' 、` `、( )
  • 2)中括号 [ ] 两端至少有 1 个空格,因此,键入中括号时即可留出空格,然后在退格键入中间的内容,并确保两端都至少有一个空格,即先键入一对中括号,然后退 1 格,输入两个空格,在退 1 格,双中括号 [[ ]] 的写法也是如此。
  • 3)对于流程控制语句,应一次性将格式写完,再添加内容。比如:

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

if 条件内容
  then
    内容
fi

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

for
do
    内容
done

提示:whileuntilcase 等语句也是一样的。

  • 4)通过缩进让代码更易读,比如
if 条件内容
  then
    内容
fi
  • 5)对于常规变量的字符串定义变量值应加双引号,并且等号前后不能有空格,需要强引用的(指所见即所得的字符引用),则用单引号(' '),如果是命令的引用,则用反引号( ` ` ),例如:
TEST_FILE="test.txt"
  • 6)脚本中的单引号、双引号及反引号必须为英文状态下的符号,其实所有的 Linux 字符及符号都应该是英文状态下的符号,这点需要特别注意。

【本文图片下载地址】【003-初步入门之《06》】点我快速打开分享(若异常,请私信,万分感谢) 【提取码:h4c3 】

今天你学习了吗?若有疑问,请留言、私信或加QQ群:647033350,大家一起进步吧!

上一篇:python中的lambda表达


下一篇:[LeetCode] Binary Tree Postorder Traversal 二叉树的后序遍历