【问题标题】:Program (nload) runs as a daemon when executed in shell but not in startup/automation script程序 (nload) 在 shell 中执行但不在启动/自动化脚本中时作为守护进程运行
【发布时间】:2015-12-31 18:53:29
【问题描述】:

我想在启动时将 nload(网络吞吐量监视器)作为守护程序运行(或者一般只是自动化)。我可以通过键入以下内容从命令行成功地将其作为守护进程运行:

nload eth0 >& /dev/null &

只是一些背景知识:除了输出到屏幕之外,我稍微修改了 nload 源代码(用 C++ 编写)以写入文件。我想从 nload 写入的文件中读取吞吐量值。我输出到 /dev/null 的原因是我不需要担心 stdout 输出。

奇怪的是,当我手动运行它时,它运行得很好,我可以从文件中读取吞吐量值。但每次自动化尝试都失败了。我试过 init.d、rc.local、cron 但没有运气。我编写的自动化运行脚本是:

#!/bin/bash
echo "starting nload"
/usr/bin/nload eth0 >& /dev/null &
if [ $? -eq 0 ]; then
    echo started nload
else
    echo failed to start nload
fi

我可以确认,当自动化时,脚本确实会运行,因为我尝试记录输出。它甚至会记录“已启动的 nload”,但是当我查看运行 nload 的进程列表时,它并不是其中之一。我还可以确认,当脚本从 shell 手动运行时,nload 可以作为守护进程正常启动。

有谁知道当通过自动化脚本运行时,是什么阻止了这个程序运行?

【问题讨论】:

    标签: c++ linux bash shell automation


    【解决方案1】:

    如果不是从终端运行,看起来 nload 会崩溃。

    viroos@null-linux:~$ cat /etc/rc.local
    #!/bin/sh -e
    #
    # rc.local
    #
    # This script is executed at the end of each multiuser runlevel.
    
    strace -o /tmp/nload.trace /usr/bin/nload
    
    exit 0
    

    看起来缺少 HOME env var:

    viroos@null-linux:~$ cat /tmp/nload.trace
    brk(0x1f83000)                          = 0x1f83000
    write(2, "Could not retrieve home director"..., 34) = 34
    write(2, "\n", 1)                       = 1
    exit_group(1)                           = ?
    +++ exited with 1 +++
    

    让我们解决这个问题:

    #!/bin/sh -e
    #
    # rc.local
    #
    # This script is executed at the end of each multiuser runlevel.
    
    export HOME=/tmp
    strace -o /tmp/nload.trace /usr/bin/nload
    
    exit 0
    

    我们还有一个问题:

    viroos@null-linux:~$ cat /tmp/nload.trace
    read(3, "\32\1\36\0\7\0\1\0\202\0\10\0unknown|unknown term"..., 4096) = 320
    read(3, "", 4096)                       = 0
    close(3)                                = 0
    munmap(0x7f23e62c9000, 4096)            = 0
    ioctl(2, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7ffedd149010) = -1 ENOTTY (Inappropriate ioctl for device)
    ioctl(2, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7ffedd148fb0) = -1 ENOTTY (Inappropriate ioctl for device)
    write(2, "Error opening terminal: unknown."..., 33) = 33
    exit_group(1)                           = ?
    +++ exited with 1 +++
    

    我看到你提到你修改了 nload 代码,但我猜你没有删除处理丢失的终端。您可以尝试进一步编辑 nload 代码或在分离模式下使用屏幕:

    viroos@null-linux:~$ cat /etc/rc.local
    #!/bin/sh -e
    #
    # rc.local
    #
    # This script is executed at the end of each multiuser runlevel.
    
    export HOME=/tmp
    screen -S nload -dm /usr/bin/nload
    
    
    exit 0
    

    【讨论】:

    • 非常感谢您花时间解决这个问题!你很准。它现在就像一个魅力! strace 看起来是一个非常有用的工具。我以后会用的。
    猜你喜欢
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多