Cron 无法运行 bash 脚本
Posted
技术标签:
【中文标题】Cron 无法运行 bash 脚本【英文标题】:Cron fails to run bash script 【发布时间】:2011-08-10 04:19:35 【问题描述】:我有 bash 脚本
#!/bin/sh
DTFILE=/etc/daytime.addr
DTPORT=13
DAYTIME_ERROR=/tmp/dtm.err
function daytime_error()
if [[ -z $1 ]]
then
exit 1
fi
if [[ -e $DAYTIME_ERROR ]]
then
echo "Error already reported"
else
logger "$1"
touch $DAYTIME_ERROR
fi
exit 1
if [[ -s $DTFILE ]]
then
ADDR=$(head -n1 $DTFILE)
DAYTIME=$(telnet $ADDR $DTPORT | time_conv.awk)
if [[ -z $DAYTIME ]]
then
daytime_error "Daytime client: no connection to $ADDR"
else
date -s "$DAYTIME"
hwclock -w
rm $DAYTIME_ERROR
fi
else
daytime_error "Daytime client: no daytime server address in file $DTFILE"
fi
从命令行调用时它可以工作,但在 cron 调用它时会失败。特别是带有 telnet 命令的行给出了零字节的输出。 Telnet 有 755 掩码,所以每个用户都应该可以使用它。有什么想法吗?
更新,time_conv.awk的内容:
#! /usr/bin/awk -f
/[0-9]+:[0-9]+:[0-9]+/
if ($2~/Jan/) $2=1;
else if ($2~/Feb/) $2=2;
else if ($2~/Mar/) $2=3;
else if ($2~/Apr/) $2=4;
else if ($2~/May/) $2=5;
else if ($2~/Jun/) $2=6;
else if ($2~/Jul/) $2=7;
else if ($2~/Aug/) $2=8;
else if ($2~/Sep/) $2=9;
else if ($2~/Oct/) $2=10;
else if ($2~/Nov/) $2=11;
else if ($2~/Dec/) $2=12;
print $5 "-" $2 "-" $3 " " $4
【问题讨论】:
你是如何运行它的?是bash <script>
还是sh <script>
还是./<script>
。可能是因为您使用#!/bin/sh
而不是#!/bin/bash
。尝试使用-x
键运行它。
time_conv.awk 的内容是什么?
@Draco Alter 我尝试使用 /bin/bash 而不是 /bin/sh,结果相同。
@bmk #! /usr/bin/awk -f /[0-9]+:[0-9]+:[0-9]+/ if ($2~/Jan/) $2=1;否则如果 ($2~/Feb/) $2=2;否则 if ($2~/Mar/) $2=3;否则如果 ($2~/Apr/) $2=4;否则 if ($2~/May/) $2=5;否则 if ($2~/Jun/) $2=6;否则 if ($2~/Jul/) $2=7;否则 if ($2~/Aug/) $2=8;否则如果 ($2~/Sep/) $2=9;否则 if ($2~/Oct/) $2=10;否则 if ($2~/Nov/) $2=11;否则 if ($2~/Dec/) $2=12;打印 $5 "-" $2 "-" $3 " " $4
用bash -x <script>
运行它怎么样?它应该打印一些调试信息。
【参考方案1】:
我猜有些路径丢失了...您是否尝试使用 /usr/bin/telnet 而不是 telnet?
要查找 telnet 的路径,您可以使用which telnet
。
【讨论】:
是的,我用 /usr/bin/telnet 代替了 telnet,它的行为是一样的。 这是一个简单的 awk 脚本,用于将白天服务器给出的时间格式转换为 yyyy-mm-dd hh:mm:ss。在脚本的调试版本中,我将bash脚本中的每个调用都分开了,唯一失败的是telnet,它甚至不输出错误(在这种情况下,我用telnet $ADDR $DTPORT调用它2>&1 | tee /tmp/garbage.tmp,从 cron 调用时给定文件为空,但从命令行调用时包含正常数据。 是的,你能不能试试那个文件的绝对路径? 是的,我有,还是一样。简而言之,我尝试使用绝对文件名调用此脚本中的所有程序,结果是一样的。【参考方案2】:您应该提及您收到的具体错误消息。无论如何,既然你说 telnet 线路会导致错误,我假设以下常见陷阱:
您的脚本需要 Bash shell 才能正常运行。 您系统的默认外壳不是/bin/bash
。看看/bin/sh
指的是什么,例如与ls -l /bin/sh
不过,您的帐户设置为将 /bin/bash
作为默认 shell(可能是在 /etc/passwd
或通过变量 $SHELL
为您的帐户设置的。
解决方案:
更改系统的默认 shell(取决于您的系统,不是我推荐的)。 让您的 cronjobs 使用 Bash 作为默认值:在 crontab 中设置SHELL=/bin/bash
。
更改脚本的第一行以明确提及 Bash:#!/bin/bash
(我的建议)
【讨论】:
【参考方案3】:好的。疯狂的猜测时间......
您使用的是.rhosts
文件吗?这样,当您远程登录时,您不必输入密码。你不能在 crontab 脚本中这样做。
如果是这个原因,你必须做三件事:
找出运行 crontab 的用户。 对于该用户,运行ssh-keygen
程序,并生成公钥和私钥。对远程机器执行相同操作。现在,在远程机器上创建一个 authorized_hosts 文件并添加您的公钥。
完成后,从 telnet 切换到 ssh。无论如何,SSH 更安全。
【讨论】:
以上是关于Cron 无法运行 bash 脚本的主要内容,如果未能解决你的问题,请参考以下文章