V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
cexia
V2EX  ›  问与答

同一个可执行文件, cron 启动和手动启动,程序行为不一样...?

  •  
  •   cexia · 2016-02-01 10:18:52 +08:00 · 2685 次点击
    这是一个创建于 3217 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比较棘手的异常,不知该如何 debug 。
    只能求助大伙了!

    CentOS 6.4 64 上部署了一个文件夹 A ,内有可执行文件 B 。
    B 的代码逻辑是启动后会重复输出日志 C 。

    异常现象:
    crontab 启动 B ,没有日志 C (异常)。
    手动启动 B ,有日志 C (正常)。

    Tips :
    B 的上一个 release 是没有日志 C 的。
    但当前 B 已经用最新版本的文件覆盖了。

    我的疑惑:
    是否 cron 启动的是某个 cache ,而该 cache 没有同步到 A 的最新版本?

    25 条回复    2016-02-05 09:44:22 +08:00
    clino
        1
    clino  
       2016-02-01 10:21:46 +08:00
    会不会是因为环境变量不一样
    tanyuxiang
        2
    tanyuxiang  
       2016-02-01 10:23:50 +08:00 via Android
    环境变量
    lynnworld
        3
    lynnworld  
       2016-02-01 10:25:29 +08:00
    看 cron 日志是否有记录
    k9982874
        4
    k9982874  
       2016-02-01 10:30:50 +08:00
    工作目录(或者日志存储目录)你有设置么?

    cron 的工作目录和你手动 cd 到文件夹 A 再执行 B 的工作目录是不同的。
    你如果设置日志存储目录是当前工作目录(‘,’), cron 运行日志是不会存在文件夹 A 里的。
    cexia
        5
    cexia  
    OP
       2016-02-01 10:31:37 +08:00
    @clino @tanyuxiang 环境变量,在用来启动 B 的脚本中,有如下一行:
    "export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH"
    一直都是没有动过的。
    其他环境变量方面的设置就没有了。
    cexia
        6
    cexia  
    OP
       2016-02-01 10:33:34 +08:00
    @lynnworld cron 确实启动了 B 的进程,这个是没问题的。 cron 日志里也未见异常。
    ck1llc
        7
    ck1llc  
       2016-02-01 10:33:35 +08:00
    1 检查环境变量
    2 检查脚本执行目录
    cexia
        8
    cexia  
    OP
       2016-02-01 10:38:41 +08:00
    貌似没法修改提问了,之前的表述可能有歧义,我重述一下:

    CentOS 6.4 64 上部署了一个文件夹 A ,内有可执行文件 B 。
    B 的代码逻辑是启动后会重复输出日志内容 C 到日志文件 F 。

    异常现象:
    crontab 启动 B ,有日志文件 F , F 内包含其他正常日志内容,但没有日 C (异常)。
    手动启动 B ,有 F ,有 C (正常)。

    Tips :
    B 的上一个 release 是没有 C 的。
    但当前 B 已经用最新版本的文件覆盖了。

    我的疑惑:
    是否 cron 启动的是某个 cache ,而该 cache 没有同步到 A 的最新版本?
    k9982874
        9
    k9982874  
       2016-02-01 10:43:54 +08:00
    1 、 kill 掉已经运行的所有 A 实例,并 PS 检查是否真的全部 kill 掉了
    2 、检查代码逻辑,看看 log 级别的设置,
    3 、检查 log 配置文件中的 log 配置级别,是否包含程序中的 log 级别

    cron 或者系统层就没别要去怀疑了,都是跑了几十年的东西。
    ms2008
        10
    ms2008  
       2016-02-01 11:02:34 +08:00
    C 属于哪个级别? stdout or stderr?

    上传一段代码片段,什么都没有,靠猜?
    cexia
        11
    cexia  
    OP
       2016-02-01 11:02:58 +08:00
    @k9982874 Thanks a lot
    ps -aux | grep 查看过, A 的进程数正常。
    日志并未采用框架, C 的日志代码是 fprintf(stderr, ...)。
    nohup ./B 2>&1 1>nohup.out &
    同样的文件夹 A ,不一样的启动方式, nohup.out 里唯独少了 C 。
    zi
        12
    zi  
       2016-02-01 11:07:20 +08:00
    @cexia corn 执行的 B 没权限写 F
    k9982874
        13
    k9982874  
       2016-02-01 11:18:49 +08:00
    @cexia 疑难杂症,上 GDB 吧
    ms2008
        14
    ms2008  
       2016-02-01 11:18:56 +08:00
    @cexia 我没有记错的话 nohup 默认会将 redirecting stderr to stdout ,所以你没有必要 2>&1 ,直接用 1>> result.log (建议使用追加放到另外一个日志先去调试, nohup.out nohup 会使用的)
    另外在 crontab 建议你用全路径启动看看(crontab 咋写的?)
    ms2008
        15
    ms2008  
       2016-02-01 11:22:48 +08:00
    你也可以直接 nohup ./B & 默认会记录到 nohup.out
    cexia
        16
    cexia  
    OP
       2016-02-01 11:26:08 +08:00
    @ms2008

    用户: pozzi

    crontab -l:
    40 8 * * 1-5 /home/pozzi/start.sh &

    start.h:
    cd ~/X/bin/
    ~/X/bin/run.sh &

    run.sh:
    date=`date +%Y%m%d%H%M%S`
    export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
    cd /home/pozzi/X/bin/
    ulimit -c unlimited
    ulimit -s 102400
    mv -f ./nohup.out ./nohups/nohup_${date}.out
    nohup ./B 2>&1 1>nohup.out &
    linkiosk
        17
    linkiosk  
       2016-02-01 11:28:37 +08:00
    我以前也被类似的问题困扰过,最后确定是环境变量的问题
    cexia
        18
    cexia  
    OP
       2016-02-01 11:29:25 +08:00
    @ms2008
    nohup 用法的提醒,我修改后试试
    leiz
        19
    leiz  
       2016-02-01 11:33:51 +08:00
    重定向一下试试?
    cexia
        20
    cexia  
    OP
       2016-02-01 11:39:17 +08:00
    @linkiosk 能否帮忙回忆一下是什么环境变量的设置?
    linkiosk
        21
    linkiosk  
       2016-02-01 11:42:10 +08:00
    @cexia 好像是 PATH
    402124773
        22
    402124773  
       2016-02-01 11:45:04 +08:00
    nohup 的问题把
    nohup 和重定向一起,可能是这个问题导致的。
    可以先用个非常短的脚本试试。
    uuspider
        23
    uuspider  
       2016-02-01 12:26:44 +08:00
    应该是 B 中环境变量设置不当引起的。
    gamexg
        24
    gamexg  
       2016-02-01 13:20:16 +08:00
    碰到过 cron 启动的程序有比较长的控制台输出,跑到一半就被杀掉了。
    未找到原因,重定向保准输出解决。
    cexia
        25
    cexia  
    OP
       2016-02-05 09:44:22 +08:00
    @ms2008 @402124773
    OK ,大伙们,这个问题解决了

    错误的启动脚本命令行是: nohup ./B 2>&1 1>nohup.out &

    修改后,分为两个脚本: run_cron.shrun.sh

    run_cron.sh:
    ./B > nohup.out 2>&1 &

    run.sh:
    nohup ./B &


    参考:
    [0] nohup --help
    ...
    If standard input is a terminal, redirect it from /dev/null.
    If standard output is a terminal, append output to `nohup.out' if possible,
    `$HOME/nohup.out' otherwise.
    If standard error is a terminal, redirect it to standard output.
    To save output to FILE, use `nohup COMMAND > FILE'.
    ...

    [1] http://stackoverflow.com/questions/14145250/cron-job-doesnt-output-to-nohup-out/14146575#14146575

    [2] http://www.cyberciti.biz/faq/redirecting-stderr-to-stdout/
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   912 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 21:58 · PVG 05:58 · LAX 13:58 · JFK 16:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.