脚本中的cp不能与incron一起使用?

时间:2017-04-28 10:02:25

标签: linux bash incron

我为/var/www/usr/lib/cgi-bin创建了备用脚本。每次编辑或添加文件时,都应通过incron调用脚本。

root@corkea:~# incrontab -l
/usr/lib/cgi-bin IN_ATTRIB,IN_CREATE,IN_DELETE,IN_CLOSE_WRITE,IN_NO_LOOP create_incremental_backup_of_http_documents_and_cgi.sh
/var/www/html IN_ATTRIB,IN_CREATE,IN_DELETE,IN_CLOSE_WRITE,IN_NO_LOOP create_incremental_backup_of_http_documents_and_cgi.sh

我在shell中测试了脚本并且它工作正常,但是当使用incron时,脚本总是返回错误。

我通过Mail收到的错误消息..

Apr 27 22:57:49 corkea create_incremental_backup_of_http_documents_and_cgi.sh[15011]: cp: regulÀre Datei â/var/tmp/http-documents-and-cgi-of-corkea.gtarâ kann nicht angelegt werden: Die Datei existiert bereits
Apr 27 22:57:49 corkea create_incremental_backup_of_http_documents_and_cgi.sh[15011]: Beende Skript, aufgrund vorheriger Fehler.

翻译

cp: cant create file /var/tmp/http-documents-and-cgi-of-corkea.gtar, because it exist already.
Stopping script because of previous error(s).

只有在使用incron启动脚本时才会出现此错误。

不知何故,脚本在以下if else命令失败...

if [ -d "${BackupDirectory}/${SubDir}" ]
then
        cp -f "$FileIncremental" "$TmpDir"
else
        mkdir -p "${BackupDirectory}/${SubDir}"
fi

我在&& [ -e "$FileIncremental" ]命令中添加了if,但它也没有帮助。

这是脚本......

#!/bin/bash
# Create an incremental GNU-standard backup of Files for the http-Server.
# This script works with Debian Jessie and newer systems.
# Created for my corekea GW 2016-11-27.

MailTo="xxx@web.de"

Source=('/usr/lib/cgi-bin' '/var/www')
BackupDirectory=/media/nas_backups/corkea
TmpDir=/var/tmp

cd /

SubDir="http_documents_and_cgi.d"
FileTimeStamp=$(date "+%Y%m%d%H%M%S")
FileName="http-documents-and-cgi-of-$(uname -n)"
File="${BackupDirectory}/${SubDir}/${FileName}-${FileTimeStamp}.tgz"
FileIncremental="${BackupDirectory}/${SubDir}/${FileName}.gtar"

TimeStamp=$(date "+%F %T")              # This format "2011-12-31 23:59:59" is needed to read the journal
exec 1> >(logger -i -s -t "${0##*/}" -p 3) 2>&1 # all error messages are redirected to syslog journal and after that to stdout
trap "BriefExit" ERR        # Provide information for an admin (via sendmail) when an error occurred and exit the script

function BriefExit(){
    rm -f "$File" "$FileIncremental"
    mv "${TmpDir}/${FileIncremental##*/}" "${BackupDirectory}/${SubDir}" >/dev/null 2>&1
    case "$LANG" in
    de_DE.UTF-8)
        echo "Beende Skript, aufgrund vorheriger Fehler." 1>&2
    ;;
    *)
        echo "Stopping script because of previous error(s)." 1>&2
    ;;
    esac
    MailContent=$(journalctl -p 3 -o "short" --since="$TimeStamp" --no-pager)
    ScriptName="${0##*/}"
    SystemName=$(uname -n)
    MailSubject="${SystemName}: ${ScriptName}"
    printf 'Subject: %s\n\n%s\n' "$MailSubject" "$MailContent" | sendmail "$MailTo"
    exit 1
}

SourceCount="${#Source[@]}"
for ((Index=0;Index<=$SourceCount-1;Index++))
do
    FormatedSource[$Index]="${Source[$Index]#/}"
done

LoopCount=0
OpenFiles=1
while [ "$OpenFiles" -ne 0 ]
do
    if [ "$LoopCount" -le 30 ]
    then
        sleep 1
        OpenFiles=$(lsof "${Source[@]}" | wc -l)
        LoopCount=$((LoopCount + 1))
    else
        case "$LANG" in
        de_DE.UTF-8)
            echo "Es kann keine inkrementelle Sicherheitskopie erstellt werden, weil betroffene Dateien im Schreibemodus sind." 1>&2
        ;;
        *)
            echo "Can't create incremental backup, because some files are open." 1>&2
        ;;
        esac
        BriefExit
    fi
done

if [ -d "${BackupDirectory}/${SubDir}" ] && [ -e "$FileIncremental" ]
then
        cp -f "$FileIncremental" "$TmpDir"
else
        mkdir -p "${BackupDirectory}/${SubDir}"
fi

tar -cpzf "$File" -g "$FileIncremental" "${FormatedSource[@]}"
chmod 0700 "$File"

rm -f "${TmpDir}/${FileIncremental##*/}"

exit 0

我错了什么,你能帮助我吗?

2 个答案:

答案 0 :(得分:0)

if [ -d "${BackupDirectory}/${SubDir}" ]
then
    cp -f "$FileIncremental" "$TmpDir"
else
    mkdir -p "${BackupDirectory}/${SubDir}"
fi

使用的命令cpmkdir可能是别名或在PATH中找到的第一个。 您可以在添加type cptype mkdir之前添加信息以输出使用的命令。 您可以显式指定可执行文件的路径:

/usr/bin/cp
/usr/bin/mkdir

答案 1 :(得分:0)

我找到了解决方案。 incron即使激活IN_NO_LOOP也会运行我的脚本两次。我必须删除IN_ATTRIB,然后删除了IN_DELETE。现在它的工作原理应该如此。