我有以下脚本
#!/bin/bash
#Purpose = Backup
#Created on 15-10-2015
#START
#cp -b /etc/rc.local $DESDIR$MKDIRNAME/rc.local
TIME=`date +"%d%b%y_%H%M%S"`
MKDIRNAME=`date +"%d%b%y"`
FOBACKUP=$(date +'%d%b%y' -d 'last month')
DESDIR="/usr/local/backup/"
FILENAME1="filebin_$TIME.tar.gz"
FILENAME2="openvpn_$TIME.tar.gz"
FILENAME3="script_$TIME.tar.gz"
SRCDIR1="/usr/local/bin/"
SRCDIR2="/etc/openvpn/"
SRCDIR3="/var/script/"
mkdir -m 0755 $DESDIR$MKDIRNAME
tar -cpzf $DESDIR$MKDIRNAME/$FILENAME1 $SRCDIR1
tar -cpzf $DESDIR$MKDIRNAME/$FILENAME2 $SRCDIR2
tar -cpzf $DESDIR$MKDIRNAME/$FILENAME3 $SRCDIR3
cp -b /etc/rc.local $DESDIR$MKDIRNAME/rc.local
cp -b /etc/crontab $DESDIR$MKDIRNAME/crontab
if [ -d "$DESDIR$FOBACKUP" ]; then
echo "file $FOBACKUP exist and was deleted!"
rm -rf $DESDIR$FOBACKUP
fi
#END
但是,我每天都会收到邮件 - 在 cron 运行此脚本之后 - 包含以下消息:
tar: Removing leading `/' from member names
我如何对此脚本进行更改才能不收到此警报?
答案1
tar
出于安全原因,发出此警告并删除前导斜线。即使没有 root 权限,提取包含绝对路径的存档也可能会产生用旧文件覆盖当前文件的意外后果。
以下步骤应该消除不需要的输出,更正tar
警告的问题,并继续允许您看到重要的错误消息。由于变量正确反映了存档的内容,因此脚本变得更加一致。
从源目录名称中删除所有前导“/”字符。
SRCDIR1="usr/local/bin/" SRCDIR2="etc/openvpn/" SRCDIR3="var/script/"
使用
-C /
选项tar
导致tar
将目录更改为/
存档之前。如果此选项不可用,您需要/
在发出tar
命令之前将目录更改为。tar -C / -cpzf $DESDIR$MKDIRNAME/$FILENAME1 $SRCDIR1 tar -C / -cpzf $DESDIR$MKDIRNAME/$FILENAME2 $SRCDIR2 tar -C / -cpzf $DESDIR$MKDIRNAME/$FILENAME3 $SRCDIR3
答案2
调查管道重定向和之间的区别标准输入、标准输出和标准错误。
下面将解决这个问题;
tar -cpzf $DESDIR$MKDIRNAME/$FILENAME1 $SRCDIR1 2> /dev/null
编辑:由于使用 '2> /dev/null' 将 stderr 重定向到 /dev/null 的“安全”问题,这里有一些其他可能的方法,可以在不使用 '-C /' 选项的情况下“安全”执行 tar 操作首先移动到 fs 内的“/”。恕我直言,这是一个安全问题,因为就好像从“/”中提取存档一样,它会用存档的内容覆盖当前文件系统。
一些替代方案:
RobertL 建议的替代方案(首先移至 $SRCDIR)
%> tar -cpzf -C $SRCDIR1 $DESDIR$MKDIRNAME/$FILENAME1 $SRCDIR1
对 stderr 使用重定向,捕获 stdout 但仍使用以下命令检查错误$?
%> output=$((tar -cpzf $DESDIR$MKDIRNAME/$FILENAME1 $SRCDIR1) 2> /dev/null)
%> [ $? -ne 0 ] && echo "An error occurred with tar"
%> echo $output
或者您始终可以使用相对和/或绝对路径(请参阅 man pwd
)
%> $((tar -cpzf $DESDIR$MKDIRNAME/$FILENAME1 $(pwd)/$SRCDIR1) 2&>1)