该脚本从命令行运行但 crontab 失败
我仍在学习 Bash,但我的脚本有问题。我想用这个脚本来过滤一些呼叫,该脚本正在分析呼叫日志,每 2 分钟作为 cronjob 一次。问题是我可以手动运行它,但从 cron 自动运行时会失败。我不知道为什么。它喊出了一些关于权限的内容,所以我对脚本进行了一些修补,所以如果它看起来很脏,我很抱歉。
#!/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
这是系统打印的内容:
/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
I'm still learning Bash and I'm having a problem with my script. I want to filter some calls with this script that is analyzing a call log, every 2 minutes as cronjob. The problem is that I can run it manually but it fails when run automatically from cron. I don't know why. It shouts something about permissions, so I kinda patched the script, so if it seems dirty I'm sorry.
#!/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=
and this is what the system prints:
/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
:'
while read line
do
DATOS=($line)
LINE_NUMBER=${DATOS[0]}
echo $LINE_NUMBER > "tmp/$FECHA.lnum"
done < "tmp/$FILE_LINE"
unset IFS
and this is what the system prints:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的脚本假定它是从特定目录运行的(请注意,几乎每个路径都是相对路径,而不是绝对路径)。
cron
恰好从另一个目录运行它。修复
如果从所在目录运行脚本时该脚本有效,请将以下内容添加到脚本顶部:
说明
$0
是正在执行的 shell 脚本的(可能是相对的)文件名。给定文件名,dirname
命令返回包含该文件名的目录。因此,该行会将目录更改为包含脚本的目录,或者如果
dirname
或cd
失败,则退出并显示错误代码。Your script assumes that it is being run from a particular directory (note that almost every path is a relative path, not an absolute path).
cron
happens to be running it from another directory.The Fix
If the script works when you run it from the directory it lives in, add the following to the top of your script:
Explanation
$0
is the (possibly relative) filename of the shell script being executed. Given a filename, thedirname
command returns the directory containing the filename.So, that line changes directories to the directory containing the script or exits with an error code if either
dirname
orcd
fails.看来您正在假设某个起始目录,并在那里创建一个 tmp 目录。但是,当您将其作为 cron 作业运行时,它会在不同的位置启动。因此 bash 启动脚本中的 CD 命令可能会让您感到困惑。当您使用
cd
或rm
或其他方式时,您可以使用完整路径名轻松进行测试。例如,
等等。
It seems that you are assuming a certain starting directory, and creating a
tmp
directory there. But when you run it as a cron job, it starts in a different place. So a CD command in your bash startup script might mess you up. You can easily test by using the full path names when youcd
orrm
or whatever.For example,
and so on.
看起来您可能需要在脚本开始时
cd
进入正确的目录。将
pwd
放在开头,然后是exit
并观察 cron 输出以了解您从哪里执行。在 cron 下运行时,您也有可能拥有较短的PATH
,但它仍然应该可以访问tail
和grep
。Looks like you may need to
cd
into the correct directory at the start of your script.Put a
pwd
at the beginning, followed byexit
and watch the cron output to see where you're executing from. There's also a chance that you have a shorterPATH
when running under cron, but it should still have access totail
andgrep
.