You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用start-stop-daemon的脚本直接运行正常,C++调用时失效求助

问题描述

我有一个使用start-stop-daemon的启动脚本,代码如下:

trap "" 1
(
    echo "INFO Starting $BinName application"
    cd ${APPLICATION_ROOT}
    if [ -e ${DEVOUT} ]; then
        mv ${DEVOUT} ${DEVOUTOLD}
    fi
    if [ -e ${DEVERR} ]; then
        mv ${DEVERR} ${DEVERROLD}
    fi
    if [ -e ${VALGRIND_LOG} ]; then
        mv ${VALGRIND_LOG} ${VALGRIND_LOG_OLD}
    fi
    # rm ${VALGRIND_LOG}
    HASHCODE=$(sha1sum ${APPLICATION_BIN}/${BinName}|cut -b0-40)
    if [ ! -z "$VALGRIND_ENABLE" ]; then
        VALGRIND_CMD="$VALGRIND --log-file=$VALGRIND_LOG"
    fi
    start-stop-daemon -S -b -m -p ${PidFileName} -c service:c10 --startas /bin/bash -- -c "/usr/bin/nohup $VALGRIND_CMD ${APPLICATION_BIN}/${BinName} -j 8019 -O -H $HASHCODE 2>${DEVERR}  > ${DEVOUT}  &"
)
sleep 1
pid=$(mypidof $BinName)
echo $pid > $PidFileName
if [ X$pid !=  "X" ]; then
    RETVAL=0;
    echo "INFO $BinName running with pid=${pid}"
else
    RETVAL=11;
    echo "ERROR Start $BinName failed !!!"
fi  

直接运行该脚本时,start-stop-daemon能正常启动目标进程,但通过C++的system()/popen()/execv()调用脚本时,目标进程并未启动,不清楚哪里出了问题。

排查与解决方案

1. 环境变量缺失

终端运行脚本会继承当前shell的环境变量,但C++程序调用时(尤其是execv这类函数),环境变量可能被清空或不完整:

  • 脚本中依赖的BinName、APPLICATION_ROOT等变量,要么在脚本开头显式定义,要么在C++调用时通过execve()传递完整环境变量数组,或用system()前先设置好环境变量;
  • 给start-stop-daemon、mypidof等命令加上绝对路径(比如/sbin/start-stop-daemon),避免因PATH环境变量缺失找不到命令。

2. 权限不足

脚本中start-stop-daemon用了-c service:c10切换用户,若C++程序运行用户权限不够,会导致切换失败:

  • 检查C++程序的运行用户是否和手动执行脚本时一致;
  • 若需要切换用户,确保C++程序以root运行,或给程序设置SUID位获取对应权限。

3. 上下文与输出重定向问题

C++调用时可能因stdout/stderr被重定向或关闭,导致子进程无法正常启动:

  • 调用脚本时显式重定向输出到日志文件,比如system("./your_script.sh > /tmp/script_run.log 2>&1"),查看日志里start-stop-daemon的错误信息;
  • 去掉start-stop-daemon命令末尾的&,因为-b参数已经指定后台运行,重复加&会导致进程管理混乱。

4. execv()参数错误

使用execv()时参数构造必须规范:

  • 第一个参数必须是脚本的绝对路径;
  • 参数数组最后必须以NULL结尾,示例:
char* args[] = {"/full/path/to/your_script.sh", NULL};
execv(args[0], args);

5. 脚本逻辑冲突

脚本中start-stop-daemon已经通过-m -p ${PidFileName}生成PID文件,后续用mypidof查找并覆盖PID文件的逻辑可能导致混乱:

  • 注释掉echo $pid > $PidFileName这一行,测试启动是否正常;
  • 查看DEVOUT、DEVERR日志文件,里面可能有nohup或目标进程的启动错误信息。

内容的提问来源于stack exchange,提问作者pinxpoong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 20:22:53