我有一个使用 curl 完成该任务的脚本,并将其设置到 crontabs 中。在 redhat 7.5+ 或 CentOS 7 上一切正常。
但是在 redhat 7.2 中,该脚本变成了垃圾,并且从未从 curl 结果中输出任何东西。
OUTPUT=/tmp/apm.log; touch $OUTPUT && truncate -s 0 $OUTPUT
[[ -f tmp/curl.tmp ]] && rm -f /tmp/curl.tmp
curl -s --connect-timeout 2 -XGET "http://www.google.com" -H Content-Type:application/json -d @/tmp/apm.json -o /tmp/curl.tmp
cat /tmp/curl.tmp >> $OUTPUT
echo >> $OUTPUT
导致的结果:脚本在shell下运行正常,但在cronjob中无法运行,/tmp/curl.tmp生成了,但是$OUTPUT /tmp/apm.log的大小为0。经过一晚上的试验,我找到了一个潜在的解决方案。
OUTPUT=/tmp/apm.log; touch $OUTPUT && truncate -s 0 $OUTPUT
[[ -f tmp/curl.tmp ]] && rm -f /tmp/curl.tmp
curl -s --connect-timeout 2 -XGET "http://www.google.com" -H Content- Type:application/json -d @/tmp/apm.json -o /tmp/curl.tmp
while :
do
[ -f /tmp/curl.tmp ] && break
sleep 1
done**
cat /tmp/curl.tmp >> $OUTPUT
echo >> $OUTPUT
我在 curl 后面加了一个 while 循环,等待确定输出文件,直到找到文件后才会执行后面的步骤。然后脚本就可以在 cronjob 中按预期正常运行了。
看来 cron 环境不会等待 curl 完成其任务。所以我的问题是,如何解决这个问题?
Red Hat Enterprise Linux Server 7.2 (Maipo)
CPE OS Name: cpe:/o:redhat:enterprise_linux:7.2:GA:server
Kernel: Linux 3.10.0-327.el7.x86_64
Architecture: x86-64
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.16.2.3 Basic ECC
zlib/1.2.7 libidn/1.28 libssh2/1.4.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3
pop3s rtsp scp sftp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL lib
答案1
我认为这是环境问题,crontab 使用 /bin/sh 作为默认 shell,sh 不理解双括号,在较新版本的 centos 中,/bin/sh 也可能被 /bin/bash 的符号链接替换
尝试在 crontab 文件的开头添加此行:SHELL=/bin/bash
答案2
尝试以下方法
[1] 给出curl的绝对路径
[2] 将标准输出和错误重定向到日志并从命令中删除超时。这样,您可以更好地挖掘问题。
[3] 使用 Shebang 通过您的输出我可以说 curl 没有产生任何输出或者命令本身存在问题。
希望它会有所帮助。
答案3
您可能必须为脚本指定直接路径。此外,将 shell 分配给 bash 的 shebang 也会有所帮助。
#!/bin/bash
OUTPUT=/tmp/apm.log; /usr/bin/touch $OUTPUT && /usr/bin/truncate -s 0 $OUTPUT
[[ -f tmp/curl.tmp ]] && /usr/bin/rm -f /tmp/curl.tmp
/usr/bin/curl -s --connect-timeout 2 -XGET "http://www.google.com" -H Content- Type:application/json -d @/tmp/apm.json -o /tmp/curl.tmp
/usr/bin/cat /tmp/curl.tmp >> $OUTPUT
/bin/echo >> $OUTPUT