11.2. 脚本中函数的例子

11.2.1. 重用

在您的系统上有很多脚本使用函数作为处理一系列命令的结构化方法。例如,在某些 Linux 系统上,您会找到/etc/rc.d/init.d/functions定义文件,该文件在所有 init 脚本中被引用。使用这种方法,诸如检查进程是否运行、启动或停止守护进程等等的常见任务,只需要以通用的方式编写一次。如果再次需要相同的任务,则可以重用代码。

您可以创建自己的/etc/functions文件,其中包含您在系统上不同脚本中经常使用的所有函数。只需将以下行放在

. /etc/functions

脚本的开头某处,您就可以重用函数。

11.2.2. 设置路径

本节可能在您的/etc/profile文件中找到。函数 pathmunge 被定义,然后用于设置 root 和其他用户的路径

pathmunge () {
        if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
           if [ "$2" = "after" ] ; then
              PATH=$PATH:$1
           else
              PATH=$1:$PATH
           fi
        fi
}

# Path manipulation
if [ `id -u` = 0 ]; then
        pathmunge /sbin
        pathmunge /usr/sbin
        pathmunge /usr/local/sbin
fi

pathmunge /usr/X11R6/bin after

unset pathmunge

该函数将其第一个参数作为路径名。如果此路径名尚未在当前路径中,则会将其添加进去。该函数的第二个参数定义了路径将添加到当前的PATH定义的前面还是后面。

普通用户只获得/usr/X11R6/bin添加到他们的路径中,而 root 则获得几个包含系统命令的额外目录。在使用后,该函数将被取消设置,以便不被保留。

11.2.3. 远程备份

以下示例是我用于备份我的书籍文件的示例。它使用 SSH 密钥来启用远程连接。定义了两个函数,buplinuxbupbash,它们各自创建一个.tar文件,然后将其压缩并发送到远程服务器。之后,本地副本将被清除。

在星期日,仅执行 bupbash

#/bin/bash

LOGFILE="/nethome/tille/log/backupscript.log"
echo "Starting backups for `date`" >> "$LOGFILE"

buplinux()
{
DIR="/nethome/tille/xml/db/linux-basics/"
TAR="Linux.tar"
BZIP="$TAR.bz2"
SERVER="rincewind"
RDIR="/var/www/intra/tille/html/training/"

cd "$DIR"
tar cf "$TAR" src/*.xml src/images/*.png src/images/*.eps
echo "Compressing $TAR..." >> "$LOGFILE"
bzip2 "$TAR"
echo "...done." >> "$LOGFILE"
echo "Copying to $SERVER..." >> "$LOGFILE"
scp "$BZIP" "$SERVER:$RDIR" > /dev/null 2>&1
echo "...done." >> "$LOGFILE"
echo -e "Done backing up Linux course:\nSource files, PNG and EPS images.\nRubbish removed." >> "$LOGFILE"
rm "$BZIP"
}

bupbash()
{
DIR="/nethome/tille/xml/db/"
TAR="Bash.tar"
BZIP="$TAR.bz2"
FILES="bash-programming/"
SERVER="rincewind"
RDIR="/var/www/intra/tille/html/training/"

cd "$DIR"
tar cf "$TAR" "$FILES"
echo "Compressing $TAR..." >> "$LOGFILE"
bzip2 "$TAR"
echo "...done." >> "$LOGFILE"
echo "Copying to $SERVER..." >> "$LOGFILE"
scp "$BZIP" "$SERVER:$RDIR" > /dev/null 2>&1
echo "...done." >> "$LOGFILE"

echo -e "Done backing up Bash course:\n$FILES\nRubbish removed." >> "$LOGFILE"
rm "$BZIP"
}

DAY=`date +%w`

if [ "$DAY" -lt "2" ]; then
  echo "It is `date +%A`, only backing up Bash course." >> "$LOGFILE"
  bupbash
else
  buplinux
  bupbash
fi


echo -e "Remote backup `date` SUCCESS\n----------" >> "$LOGFILE"

此脚本从 cron 运行,意味着没有用户交互,因此我们将来自 scp 命令的标准错误重定向到/dev/null.

可能会有人争辩说,所有单独的步骤都可以组合在一个命令中,例如

tarc dir_to_backup/| bzip2 | sshserver"cat >backup.tar.bz2"

但是,如果您对中间结果感兴趣,这些结果可能会在脚本失败时恢复,那么这不是您想要的。

表达式

command &>file

等效于

command >file 2>&1