system()偶尔会返回2

Het*_*tiu 8 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;
}
Run Code Online (Sandbox Code Playgroud)

然后,我使用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
Run Code Online (Sandbox Code Playgroud)

但有时会有一个奇怪的返回码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
Run Code Online (Sandbox Code Playgroud)

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

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

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

bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated)
Run Code Online (Sandbox Code Playgroud)

ric*_*ici 8

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

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

bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated)
Run Code Online (Sandbox Code Playgroud)

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

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

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

for i in {0..999}; do sh -c 'exit 0' || echo Failure $?; done
Run Code Online (Sandbox Code Playgroud)

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

的dash壳,作为一个/bin/sh由一个数分布的实现,返回状态码2时shell退出作为一个错误条件的结果.

上述脚本的一个可能的罪魁祸首是

 exit -1
Run Code Online (Sandbox Code Playgroud)

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

Bash的exit内置exit函数(比如C 函数)只使用提供的返回代码的低位字节,所以使用bash你会看到返回代码为255.但是内置的破折号exit期望它的参数是一个无符号数,并抱怨 - 1不是有效数字.

由于exit是一个特殊的内置函数,并且shell不是交互式的,因此根据Posix标准,错误会导致shell退出.由于shell错误,Dash在退出时将退出代码设置为2.