Linux Shell Script

所需环境

  • Bash

参考文件

大家都知道,Linux 里的各种指令,都代表著一种专门的小工具,以 ls 来说,这是每位 Linux User 都知道的小小指令,要列出目前目录里的物件,都使用 ls 就可以了,但你绝不会想要用 ls 帮你算出目前这个目录占多少空间!相对的,你会去使用 du 命令来算出目前所在目录下所有物件所占的容量!

如果说 Linux 世界里是所有小型工具的集散地,那么你的 Shell Script 就是整合这些小工具的“特定工具”,再拿出刚刚的列子来说,我想要先印出目前目录里的元件,再把所占的空间都算出来,那么你就要下两道指令:

# ls
# du -s

这样就可以达到目标。当然,你可以把两个小指令写在一个档案里,再去执行他也一样可以达到效果,假设我们现在来建立一个小小的 script,叫作 print_dir.sh,你可以用 vi,也可以用其它的文字编辑工具来写你的 Shell Script。

# vi print_dir.sh
__________________________
#!/bin/bash
ls
du -sh
:_________________________
 

好了,只要三行就可以了,然后来再执行他就可以达到效果!
# sh print_dir.sh

你可以使用 sh 指令去执行这个 Script 档,也可以直接打 ./print_dir.sh 来执行,但是一旦你选择后者之后,您必需让这个 print_dir.sh 有执行的权限,使用以下命令调整。
# chmod a+x print_dir.sh

如此就可以了!

了解了简单的 Script 概念之后,再接下来,就要开始谈谈 Shell Script 了!

Shell Script

在 Linux 下我们可以直接下达指令,比方说 ls、tar、df、du ... 等等的指令,其实都是下达给 Shell,然后 Shell 再依指令行事。目前 Shell 有 rsh、csh 和 bash 这三种比较有人使用,其中又以 bash shell 最为普级,Bash Shell 是有 GNU 来维护的,并且可以在各平台使用。假如您之前有看过相关的 Linux 入门书籍,你可能会跳过 Shell Script 章节,但现在您又在这里看到了关於 Shell Script 的章节,相信您一定会提出一个疑问:Shell Script 到底是什么?

Shell Script 介绍

什么叫 Shell Script,其实 Shell Script 也没有什么,就是一个脚本,说白一点,就是把所有一系列的指令都写在同一个档案里,叫做 Script,Script 有很多种,JavaScript、VB Script ... 喔,不要超出主题了,在这里指的是为 Shell 所设计的 Script。

为什么要写 Script?可以不写吗?简单来说,写 Script 会让管理者节省很多时间,打个比方来说,今天为了要开帐号,然后就下达 useradd 这个指令,一个人还好,但是上百个人可能会要了管理者的命,也许从此对管理工作会产生一种厌恶感,如果现在使用 Script 来达成,那么一次新增上百个使用者帐号就会非常简单,也许只需要准备帐号/密码档就可以了。

再一个例子,拿备份动作来讲好了,要备份一个目录可能没什么,备份完之后再确认是否有成功也不算什么。现在试想看看,一间公司有很多单位,每个单位都有其重要的资料需要备份,那么这个时候就要考虑是否要使用程式来代替人工一条一条的下指令了,因为这种重复性的工作可以会让人发疯的!

初级 Bash Shell Script

初级 Shell Script,说实在的也没有什么,就是把所有一系列的指令都丢到一个档案里,然后执行它就好了!Shell Script 就是这样!

在撰写 Script 一点要注意的就是事情处理的先后顺序,也就是说当您在下达指令时,一定会有先后顺序,总该不可能还没有前头就想要看尾巴吧!因此您可以把 Script 看成您在下的指令,这样应该会比较好理解。

在选写 Script 时,首先要注意几件事:

  • 文件要使用 Unix 格式
  • 选择编辑工具
  • 写完之后要注意权限问题

    文件要使用 Unix 格式

    在撰写 Script 时,您或许会想要先在 Windows 下撰写,但是千万要记得一点,请您要使用 Unix 的格式来写,依经验,如果使用 DOS 格式来写的话,最后执行时会发生错误。假若您在 Windows 下使用 UltraEdit 这个软体来编辑您的 Shell Script 的话,那么请记得转换格式(DOS to Unix),万一您真的不知如何转换,那么也没有关系,在 Linux 下会有相关的指令可以帮助您来转换,只要您下达 dos2unix 这个转换指令就 OK 了!

    选择编辑工具

    在 Windows 下,可以使用记事本、UltraEdit ... 等文字编辑器来写,当然,如果您想要用 Word 也可以,That's OK!

    如果您已经习惯在 Linux 文字模式下使用 vi 工具来设定档案,那么您也只需要 vi 就可以了,撰写 Script 不需要使用什么具有特异功能的文字处理程式来写,简单就好!

    写完之后要注意权限问题

    这个理由很简单,当您写好好精心设计的 Script 档案时,总是希望这个 Script 可以跑吧,不过一般在新增建立一个 Script 时,只有读和写的权限,无法执行,所以可以使用 chmod 让这个档案变成可执行的。

好,现在就使用上一章的备份为例子,做出备份的 Script。

建立一个 Shell Script 档案

我们用 vi 编辑了一个 sample.sh 的 Script 档,目的就是在做完备份后还能显示出 /backup 里有没有 source_code.tar.gz 这个备份完之后的档案。
[root@test root]# vi sample.sh
______________________________
#!/bin/sh
#备份 /source_code 里的资料都压缩到 /backup/source_code.tar.gz 里。
tar -zcvf /backup/source_code.tar.gz /source_code/
cd /backup/
ls -l
~
~
~
~
:________________________
 

编辑好之后就储存起来。

更改权限

修改一下 sample.sh 的权限,让这个档案有"可执行"的权限。

[root@test root]# chmod 700 sample.sh
[root@test root]# ls -l
total 4
-rwx------ 1 root root 81 May 22 16:53 sample.sh
[root@test root]#

执行第一个 Shell Script

如果要执行已写好的 Script 档,请输入完整的路径,假如档案是在目前的工作目录下,那么请输入 ./sample.sh 就可以直接执行了。
[root@test root]# ./sample.sh

好了,以上就是三行搞定的简单 Script,然而这算是最阳春的了,并不包含程式部份。简单来讲就是把一系列的动作都塞到 Script 里,然后让它自己执行,您要做的就是等待最后 ls -l 的最后结果。

程式化 Bash Shell

到底需不需要程式化 Bash Shell,这个问题就依管理者自己所处的环境而定,如果需要对资料做条件式判断、同一时间重覆多次命令或条件式回应,那么这就需要让 Shell Script 程式化了。

基本上 Bash Shell 本身就提供了程式功能,以便管理者能便有弹性的去强化 Script 档,让主机的管理便方便。当然,您不必觉得太惶恐,因为这不像写 C 一样这种大工程,写 Bash Script 的成就感可能会大於写 C 的成就感,因为你可以很容易的就上手,不用 include 什么标头档,如果出错时也会很容易的知道自已错的地方在那里。在本章,我们只讨论 if ... elif ... else ...fi 、for ... do ... done、case ... esac 的常用语法。

判断式

if [ 条件一 ]; then
     执行一
elif [ 条件一 ]; then
    执行二
else
    执行三
fi

多个条件

在 if 里的条件式里,同一个判断行可以有很多的条件,可以使用逻辑运算符号来表示:

  • && 且
  • || 或
  • == 等於
if [ "$TEST1" == "1234" ] && [ "$TEST2" == "45678" ]; then

上面这句话的意思就是说当变数 $TEST1 等於 1234 并且 变数 $TEST2 等於 45678 的时候才做动作,否则跳到下一个条件式。

if [ "$TEST1" == "1234" ] || [ "$TEST2" == "45678" ]; then

上面这句话的意思就是说当变数 $TEST1 等於 1234 或变数 $TEST2 等於 45678 的时候(亦即两个条件只要一个成立)就做动作,否则跳到下一个条件式

档案判断

以下是常用的档案判断

档案、目录的类型判断

  • -f:检查档案是否存在
  • -d:检查目录是否存在
  • -e:检查档案或目录是否存在

范例

if [ -f /etc/fstab ]; then

if [ -d /etc ]; then

if [ -e /etc ]; then

档案、目录的权限判断

  • -r:检查该档案、目录是否可读
  • -w:检查该档案、目录是否可写
  • -x:检查该档案、目录是否可执行

范例

if [ -r /etc/fstab ]; then
    echo "You can read this file."
fi
if [ -w /etc/fstab ]; then
    echo "You have the \"write\" permission for this file."
fi
if [ -x /etc/fstab ]; then
    echo "You have the \"execute\" permission for this file."
fi

解释

上面的三个列子,会逐一简查 /etc/fstab 这个档案是否可以读取、写入和执行,如果符合就显示相关讯息。如果您是以 root 身份来执行的话,那么结果应该会显示

You can read this file.
You have the "write" permission for this file.

的样示。

选择式判断

case 值 in
参考值一)
    执行一
    ;;
参考值二)
     执行二
    ;;
参考值三)
    执行三
    ;;
*)
    执行预设动作
    exit 1
esac

case 可以读取所给的值,然后再依序寻找相符的条件,如果符合就执行动作,若都没有找到符合的,就执行预设动作。

范列

test=1
case $test in
1)
    echo "Value 1"
    ;;
2)
    echo "Value 2"
    ;;
3)
    echo "Value 3"
    ;;
*)
    echo "Can not find the value."
    exit 1
esac

解释

首先先设定一个变数 test,然后在使用 case 读到 test 的变数值,再依续判断是否有符合条件的,如果有就执行动作,若没有就执行预设动作。在本例中,会显示
Value 1

的字样。

回圈

for 变数 in 已宣告的变数集值
do
    要重覆的动作
done

范列

NAME="Steven Tom Lisa Sandy"

for i in $NAME
do
    echo $i
done

 

解释

首先先设定 NAME 的字串集合,然后在 for 里建立一个变数 i 去读取 NAME 的变数值,再依续显示出来。在本列中,会显示

Steven
Tom
Lisa
Sandy

的字样。

Index