我使用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)
答案 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。