好的,所以我是bash脚本的初学者,我知道这个问题可能有点笨拙,但我会尽可能清楚!
我编写了以下脚本来创建文件夹中的存储库备份。脚本如下:
#!/bin/bash
SVNREPO="/var/svn"
TEMP="/var/tmp"
BACKUP="/home/helix/backups"
cd $SVNREPO
if [ $# -eq 0 ]; then
for REPO in *; do
ARRAY+=($REPO)
done
else
for REPO in $@; do
ARRAY+=($REPO)
done
fi
for REPO in ${ARRAY[@]}; do
svnadmin dump $SVNREPO/$REPO -r HEAD | gzip > $TEMP/$REPO.svn.gzip sd
cp $TEMP/$REPO.svn.gzip $BACKUP/$REPO.svn.gzip
rm $TEMP/$REPO.svn.gzip
done
当没有参数调用脚本时,此脚本成功生成'var / svn'中所有存储库的.gzip备份,并创建作为参数调用的特定存储库的.gzip备份。太好了!
但是,如果使用与存在的存储库不对应的参数运行脚本,则程序将崩溃并显示错误消息:svnadmin: E000002: Can't open file '/var/svn/ada/format': No such file or directory
。我想要实现的是捕获此错误并将更友好的用户输出打印到控制台。我一直试图用“陷阱”来做到这一点。
首先我添加了以下行:
trap 'echo ERROR! The repository or repositories that you are trying to backup do not exist!' ERR
...然后我在最后的for循环中将错误推送到/ dev / null:
svnadmin dump $SVNREPO/$REPO -r HEAD 2>/dev/null | gzip > $TEMP/$REPO.svn.gzip
我在我所做的地方推送到/ dev / null文件,因为这是程序错误的地方。但是,该脚本似乎不再起作用。我在这做错了什么?将2>/dev/null
放在一条线的中间是一个问题吗?如果是这样,我怎么能重构这个代码,以便它不需要管道中间的管道?
非常感谢您的帮助,我希望我的问题相当清楚!为了确认,最终的非工作代码如下:
#!/bin/bash
SVNREPO="/var/svn"
TEMP="/var/tmp"
BACKUP="/home/helix/backups"
cd $SVNREPO
if [ $# -eq 0 ]; then
for REPO in *; do
ARRAY+=($REPO)
done
else
for REPO in $@; do
ARRAY+=($REPO)
done
fi
trap 'echo ERROR! The repository or repositories that you are trying to backup do not exist!' ERR
for REPO in ${ARRAY[@]}; do
svnadmin dump $SVNREPO/$REPO -r HEAD 2>/dev/null | gzip > $TEMP/$REPO.svn.gzip sd
cp $TEMP/$REPO.svn.gzip $BACKUP/$REPO.svn.gzip
rm $TEMP/$REPO.svn.gzip
done
答案 0 :(得分:1)
我不确切知道trap
命令是如何工作的,但我会建议另一种可以用另一种方式解决问题的方法:
首先,在for
循环之前,添加以下行:
set -o pipefail
这意味着当管道中的任何命令失败时,最后一个退出代码($?
)将包含错误代码(如果有任何失败)。
在svnadmin
来电后,我会建议添加:
if [ $? -ne 0 ]; then
echo "ERROR! Received error code $? for repository '$REPO'."
continue
fi
您当然可以根据自己的喜好更改错误消息。功能应该是明确的:如果svnadmin
或bzip
失败,它将打印错误消息并继续for
循环中的下一个项目。
希望这有帮助。
答案 1 :(得分:1)
使用@cdarke建议检查文件是否存在,我现在让它使用以下代码:
#!/bin/bash
SVNREPO="/var/svn"
TEMP="/var/tmp"
BACKUP="/home/helix/backups"
cd $SVNREPO
if [ $# -eq 0 ]; then
for REPO in *; do
ARRAY+=($REPO)
done
else
for REPO in $@; do
ARRAY+=($REPO)
done
fi
for REPO in ${ARRAY[@]}; do
if [ -f $SVNREPO/$REPO/format ]; then
vnadmin dump $SVNREPO/$REPO -r HEAD 2>/dev/null | gzip > $TEMP/$REPO.svn.gzip
cp $TEMP/$REPO.svn.gzip $BACKUP/$REPO.svn.gzip
rm $TEMP/$REPO.svn.gzip
else
echo ERROR! The repository $REPO does not exist. No backup has been made for this argument.
fi
done