【问题标题】:Different results when running a script by cron than manually executed通过 cron 运行脚本与手动执行时的结果不同
【发布时间】:2020-12-26 05:37:49
【问题描述】:

我有一个脚本,它使用 keys.txt 中的键对 list.txt 文件中的目标列表进行一些 curl 调用,每个调用结果都保存在以服务器名称 +_show_counters 开头的不同 txt 文件中。当我手动运行此脚本时,它会正确运行并从 list.txt 中找到的正确服务器给我正确的响应,但是当由 cron 运行时,提供的信息与正确的服务器不对应,而是与列表中后面 4 个位置的另一个服务器相对应.

这是代码:

#!/bin/bash
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/puppetlabs/bin
temp=/local/scripts/shell/checker/temp/
timestamp=$(date +'%Y_%m_%d--%H:%M:%S')

paste $temp"list.txt" $temp"keys.txt" > $temp"combined.txt"
awk '{ printf "https://%s//api/?type=op&cmd=blablabla&key=%s\n", $1, $2}' $temp"combined.txt" > $temp"allCurls.txt"

count=1
for crl in `more +1 ${temp}allCurls.txt`
do
        filename=`awk -v count=$count 'NR==count{print $1}'  ${temp}list.txt`
        filekey=${filename}
        filename="$temp${filename}_show_counters.txt"
        curl -k $crl > ${filename}
        echo curl -k   $crl  >> $temp"curls_debug.txt"
        count=$((count+1))
done

这是 cron 内容:

0,10,20,30,40,50 * * * * /local/scripts/shell/checker/checker.sh > /dev/null 2>&1

我已经尝试编辑 cron 以从以下命令开始,但没有任何区别。

SHELL=/bin/bash
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/puppetlabs/bin 

我在 /var/spool/mail/ 下面发现错误,然后所有连续的卷曲都正确执行,这导致提供的结果中的顺序错误。

curl: (6) Couldn't resolve host '::::::::::::::'
curl: (3) <url> malformed
curl: (6) Couldn't resolve host '::::::::::::::'

于是我在for中添加了echo curls_debug.txt,发现:

curl -k ::::::::::::::
curl -k /local/scripts/shell/checker/temp/allCurls.txt
curl -k ::::::::::::::

这仅在由 cron 执行时发生,如果我手动运行此脚本,则 curls_debug.txt 以预期格式显示 curl -k https://server_name+command+key 自第一次 curl 以来的卷曲,因此带来正确的结果。

谁能帮我看看这里出了什么问题以及如何解决它?非常感谢。

【问题讨论】:

    标签: bash shell cron


    【解决方案1】:

    这是一个猜测,但我怀疑这是由于使用more 来读取文件——more 是一个交互式工具,不应该在非交互式脚本中使用。使用cat 会更好,但while read ... done &lt;file 循环通常是最好的方法。而不是使用一组凌乱的中间文件,我只使用一个组合的while read循环来并行读取两个文件(通过文件描述符#3和#4,只是为了保持干净),然后把信息直接从两个文件一起:

    #!/bin/bash
    PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/puppetlabs/bin
    temp=/local/scripts/shell/checker/temp
    timestamp=$(date +'%Y_%m_%d--%H:%M:%S')
    
    while read domain <&3 && read key <&4; do
        crl="https://${domain}//api/?type=op&cmd=blablabla&key=${key}"
        filename="${temp}/${domain}_show_counters.txt"
        curl -k "$crl" > "${filename}"
    done 3<"${temp}/list.txt" 4<"${temp}/keys.txt"
    

    注意:我还清理了引号(通常,变量引用应该用双引号引起来),并在 temp 变量中留下了尾随的/(我发现在使用时添加它更清晰变量 -- 清楚地表明我们指的是该目录中的文件)。

    【讨论】:

    • 你好,戈登,谢谢你的建议。好吧,不确定“更多”是否是问题所在,但我用建议的 while 替换了那部分代码并纠正了问题,非常感谢您的帮助。
    猜你喜欢
    • 2014-09-06
    • 2017-05-09
    • 2015-12-19
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 2019-07-27
    • 2017-01-21
    • 1970-01-01
    相关资源
    最近更新 更多