C system()偶尔返回2
我使用C system()偶尔返回2,c,shell,system,C,Shell,System,我使用system()library函数编写了一个函数,如下所示: 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); // loggin
system()
library函数编写了一个函数,如下所示:
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;
}
#!/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
[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
bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated)
然后,我用shell脚本调用它,如下所示:
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;
}
#!/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
[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
bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated)
但有时会有一个奇怪的返回码2,如下所示:
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;
}
#!/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
[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
bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated)
我想了解为什么返回代码为2
=====================新的2015/06/12 13:54============================
我发现当system()返回2时,有一条bash错误消息,如下所示:
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;
}
#!/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
[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
bash: xmalloc: locale.c:73: cannot allocate 2 bytes (0 bytes allocated)
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
状态返回码是八位无符号值;换句话说,合法返回码的范围从0到255-1不在该范围内,您不应该在调用exit
时使用它
Bash的exit
内置(与Cexit
函数类似)只使用提供的返回代码的低位字节,因此使用Bash时,您将看到255的返回代码。但是dash内置的exit
期望它的参数是一个无符号的数字,并抱怨-1不是一个有效的数字
由于
exit
是一个特殊的内置项,并且shell不是交互式的,因此该错误会导致shell退出,如所示。由于shell错误退出时,Dash将退出代码设置为2。这是一个格式非常好的问题。不需要改进。作为旁注,原因可能在return ret
后面,其中ret=system(cmd)
system(cmd)
可能等于2
@jamesmith,如果system
返回2
,那么他就会点击!=-1
case和WIFEXITED
应该返回false,而ret
应该设置为-1
,我认为,作为旁白。查看pgrep
而不是您的管道,eval
是完全不必要的。@EtanReisner抱歉,我一定忽略了这一点。但是,WEXITEDSTATUS(ret)
return 2?@EtanReisner如果eval失败,那么这个脚本将提前退出并返回2?啊,我想255在被记录之前被截断了。这更有意义。但是,即使我只重置脚本的内容。/admin/trystart.sh“exit 1”,问题也会再次发生。我发现,当system()返回2时,bash会显示一条错误消息:“bash:xmalloc:locale.c:73:无法分配2个字节(已分配0个字节)”@Hetiu:interest。好吧,我当时猜错了。我编辑了答案,但我没有什么真正可靠的补充。您使用的bash版本是什么?您是从centos存储库更新bash还是以其他方式更新bash?@rici最后,当我使用gcc-m32构建调用方c代码并在64位系统中运行时,出现了此问题。如本节所述: