首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >脚本从命令行运行,但crontab失败

脚本从命令行运行,但crontab失败
EN

Stack Overflow用户
提问于 2011-07-13 01:41:42
回答 3查看 3.7K关注 0票数 2

我还在学习Bash,我的脚本有问题。我想用这个脚本过滤一些呼叫,该脚本每隔2分钟作为cronjob分析一个呼叫日志。问题是我可以手动运行它,但从cron自动运行时它会失败。我也不知道原因。它说了一些关于权限的东西,所以我给脚本打了补丁,所以如果它看起来很脏,我很抱歉。

代码语言:javascript
运行
复制
#!/bin/bash

YESTERDAY=$((`date +'%s'`-86400))
AYER=`date -d "1970-01-01 $YESTERDAY sec" +"%Y%m%d"`
FECHA=`date +"%Y%m%d"`

FILENAME="$FECHA.log"
FILE_LINE="$FECHA.last"
FILE="/apps/sittel/rawdata/mitel.$FECHA"

# Limpiar carpeta tmp

if [ -e "tmp/$AYER.lnum" ]; then
    rm tmp/${AYER}.*
fi

# Si existe el archivo con el numero de laultima linea se procesa

if [ -e "tmp/$FECHA.lnum" ]; then

    # Se lee el numero de la linea y se extrae un archivo con las lineas apartir
    # de la ultima busqueda que se hizo, posteriormente se les hace un grep

    while read line
    do
            tail -n +$line $FILE > "tmp/$FECHA.hal"
    done < "tmp/$FECHA.lnum"
    cd tmp

    grep -n " 00[0|2-9][0-9]\{4,\}" "tmp/$FECHA.hal" > "tmp/${FECHA}.new"

    grep -n " 900[0|2-9][0-9]\{4,\}" "tmp/$FECHA.hal" >> "tmp/${FECHA}.new"

    cd ..
    echo `pwd`
    cat tmp/${FECHA}.new >> logs/$FILENAME

else
    # Este caso es la primera vez que se ejecuta, verifica si el log ya existe
    # de ser asi, lo elimina para evitar duplicados

    if [ -e "logs/$FILENAME" ]; then
            rm "logs/$FILENAME"
    fi

    # Se realiza un grep en el archivo indicado y se marca el archivo de salida
    # se busca todos los numeros k empiecen con 00 seguidos de 0 a 9 execpto el 1

    cd tmp

    grep -n " 00[0|2-9][0-9]\{4,\}" $FILE>"${FECHA}.new"

    grep -n " 900[0|2-9][0-9]\{4,\}" $FILE>>"${FECHA}.new"

    cat ${FECHA}.new >> $FILENAME

    mv $FILENAME ../logs

    cd ..
fi

    cp "tmp/${FECHA}.new" "tmp/message.txt"

    echo "Mensaje" | mail -s "$SUBJECT" "$EMAIL" < "tmp/message.txt"

fi

if [ -e "tmp/${FECHA}.new" ]; then
    rm "tmp/${FECHA}.new"
fi

tail -n1 "logs/$FILENAME" > "tmp/$FILE_LINE"   

IFS=$':'
while read line
do
    DATOS=($line)
    LINE_NUMBER=${DATOS[0]}   
    echo $LINE_NUMBER > "tmp/$FECHA.lnum"
done < "tmp/$FILE_LINE"
unset IFS

这是系统打印的内容:

代码语言:javascript
运行
复制
/apps/sittel/Alarma/callAlarm: line 56: cd: tmp: No such file or directory
mv: cannot move `20110712.log' to `../logs': Permission denied
/apps/sittel/Alarma/callAlarm: line 69: tmp/20110712.last: No such file or directory
/apps/sittel/Alarma/callAlarm: line 77: tmp/20110712.last: No such file or directory
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-13 11:38:28

您的脚本假定它是从特定目录运行的(请注意,几乎每个路径都是相对路径,而不是绝对路径)。cron恰好从另一个目录运行它。

解决之道

如果脚本在它所在的目录中运行时可以正常工作,请将以下内容添加到脚本顶部:

代码语言:javascript
运行
复制
mydir=$(dirname "$0") && cd "${mydir}" || exit 1

解释

$0是正在执行的外壳脚本的(可能是相对的)文件名。给定一个文件名,dirname命令将返回包含该文件名的目录。

因此,如果dirnamecd失败,该行将目录切换到包含脚本的目录,或者退出并返回错误代码。

票数 2
EN

Stack Overflow用户

发布于 2011-07-13 02:10:40

您似乎假设了一个特定的起始目录,并在其中创建了一个tmp目录。但是,当您将其作为cron作业运行时,它会在不同的位置启动。因此,bash启动脚本中的CD命令可能会把您搞得一团糟。当您使用cdrm或其他任何工具时,您可以通过使用完整的路径名轻松地进行测试。

例如,

代码语言:javascript
运行
复制
if [ -e "tmp/$AYER.lnum" ]; then
    rm /home/username/tmp/${AYER}.*
fi

# Si existe el archivo con el numero de laultima linea se procesa

if [ -e "/home/username/tmp/$FECHA.lnum" ]; then

    # Se lee el numero de la linea y se extrae un archivo con las lineas apartir
    # de la ultima busqueda que se hizo, posteriormente se les hace un grep

    while read line
    do
            tail -n +$line $FILE > "/home/username/tmp/$FECHA.hal"
    done < "/home/username/tmp/$FECHA.lnum"
    cd /home/username/tmp

    grep -n " 00[0|2-9][0-9]\{4,\}" "/home/username/tmp/$FECHA.hal" > "/home/username/tmp/${FECHA}.new"

诸若此类。

票数 1
EN

Stack Overflow用户

发布于 2011-07-13 02:05:13

看起来您可能需要在脚本的开始处使用cd进入正确的目录。

在开头放一个pwd,然后放入exit,然后观察cron输出,看看您是从哪里执行的。在cron下运行时,您也有可能拥有较短的PATH,但它应该仍然可以访问tailgrep

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6668588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档