system()偶尔会返回2

时间:2015-06-12 01:34:24

标签: c shell system

我使用system()库函数编写了一个函数,如下所示:

int execute(const char* cmd)
{
  int ret = system(cmd);

  if (ret != -1)
  {
    if (WIFEXITED(ret))
      ret = WEXITSTATUS(ret);
    else
      ret = -1;
  }

  LINFO( "execute %s, ret = %d", cmd, ret);  // logging
  return ret;
}

然后,我用shell脚本调用它,如下所示:

#!/bin/sh
PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin
cd $(dirname $0)

agent_name=`grep 'agent_name' ../etc/config.ini |awk '{ print $3 }'`
py='../../python26/bin/python'

check_alive()
{
    status=`ps -ef | grep "$agent_name" | grep -v "grep" |wc -l`

    if [ $status -ne 0 ]; then
        # process exist
        echo "$agent_name already exist"
        exit 1
    fi    

}

check_alive
eval '$py ../bin/agent.py -d'

status=`ps -ef | grep "$agent_name" | grep -v "grep" |wc -l`
if  [ $status -lt 1 ] 
then
    echo "run failed"
    exit -1
else
    echo "run succ"
    exit 0
fi

但有时奇数返回码为2,如下所示:

[INFO]execute ./admin/trystart.sh, ret = 1
[INFO]execute ./admin/trystart.sh, ret = 1
[INFO]execute ./admin/trystart.sh, ret = 2
[INFO]execute ./admin/trystart.sh, ret = 2
[INFO]execute ./admin/trystart.sh, ret = 1
[INFO]execute ./admin/trystart.sh, ret = 1
[INFO]execute ./admin/trystart.sh, ret = 1
[INFO]execute ./admin/trystart.sh, ret = 1
[INFO]execute ./admin/trystart.sh, ret = 1
[INFO]execute ./admin/trystart.sh, ret = 2

我想了解为什么返回代码为2。

================ new 2015/06/12 13:54 ====================== ==

我发现当system()返回2时,bash的错误信息如下:

bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated)

1 个答案:

答案 0 :(得分:8)

shell的状态代码为2。如果没有更多细节,就很难诊断出来。添加shell生成的实际错误消息很有用。

如果shell是bash - 现在看起来是 - 那么状态返回码2表示内存分配错误,由bash生成的错误消息确认:

bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated)

据我所知,第73行是由新启动的bash进程执行的第一个内存分配(由错误消息确认尚未分配任何字节) ),所以似乎问题是malloc无法分配任何内存。

可能确实没有可用内存,特别是如果您在没有配置交换的严重拥塞系统上运行。但是互联网上散布着一些暗示,这可能与内存保护选项有关;特别是sbrk不可用但malloc库希望能够使用它的配置。

您可能希望通过验证是否可以可靠地启动新shell来开始进一步诊断:

for i in {0..999}; do sh -c 'exit 0' || echo Failure $?; done

较早的猜测,可能对其他人有用。建议修改exit的调用,即使它可能与此问题中的特定问题无关。

dash shell,被许多发行版用作/bin/sh实现,当shell因错误条件退出时返回状态码2。

上述脚本的一个可能原因是

 exit -1

状态返回码是8位无符号值;换句话说,合法返回代码的范围是0到255. -1不在该范围内,并且您不应该在调用exit时使用它。

Bash的exit内置函数(如C exit函数)只使用提供的返回码的低位字节,因此使用bash,您会看到返回码为255。但内置exit的破折号要求其参数为无符号数,并抱怨-1不是有效数字。

由于exit是一个特殊的内置函数且shell不是交互式的,因此错误会导致shell退出,如the Posix standard所示。由于shell错误,Dash在退出时将退出代码设置为2。