ITEEDU

11.2. 函数在脚本中的例子

11.2.1. 循环利用

在你的系统中有大量的脚本使用函数来以结构化的方法处理一系列命令。在某些linux系统上,比如,你可以找到 /etc/rc.d/init.d/functions 定义文件,source在所有的初始化脚本中。使用这个方法通常只需要编写一次,常见的任务比如检查进程是否运行,开始或者停止一个守护进程等等。如果某些任务还需要一次,代码就可以重新循环使用。从这个 functions 文件中的checkpid函数:

# Check if $pid (could be plural) are running
checkpid() {
        local i

        for i in $* ; do
                [ -d "/proc/$i" ] && return 0
        done
        return 1
}

这个函数在相同的脚本中在重用于其他脚本的其他函数中被重用。 守护进程 ,比如,多数使用在启动一个服务进程的起始脚本中。

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 得到了一些包含系统命令的额外目录。使用完毕后,函数就进行unset所以就不存在了。

11.2.3. 远程备份

以下的例子是用来我用来备份我的文件的。使用SSH密钥来启用远程连接。其中定义了2个函数,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

可能引起争论的是所有的分开的步骤可以组合到类似下列的命令:

tar c dir_to_backup/ | bzip2 | ssh server "cat > backup.tar.bz2"

然而,如果你对能恢复脚本错误的中间的结果感兴趣,这不是你想要的。

表达式

command &> file

等价于

command > file 2>&1