首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

shell脚本或C程序返回值为什么不能大于255

纯粹技术干货,喜欢水的朋友可能看不进去,准备好了没^_^。

我们在linux下编程时,比如说shell脚本或C程序(包括c++)等,程序退出时都会给操作系统传回一个值做为返回值,此值不能超过255,就此问题咱们深入到内核源码看一下。

程序退出时的参数便是返回值,通常父进程或操作系统会根据此返回值判断子程序执行的结果。

退出分为正常退出和异常退出两类。

正常退出有3种:

return返回

调用C库函数exit

调用系统调用_exit

异常退出两种:

主动调用abort函数

信号终止

下面从头说,这是为后面的结论做铺垫。

_exit函数的接口定义如下:

#include

void _exit(int status)

_exit函数中status参数定义了进程的终止状态,父进程可以通过wait()来获取该状态值。需要注意的是返回值,虽然status是int型,但是仅有低8位可以被父进程所用。所以写exit(-1)结束进程时,在终端执行“$?”会发现返回值是255。

return是一种更常见的终止进程的方法。执行return(n)等同于执行exit(n),因为调用main() 的运行时函数会将main的返回值当作exit的参数。

比如如下代码:

#include

int main() {

exit(88);

}

给操作系统的返回值将是88,执行如下:

或者用return也一样:

首先return并不是系统调用和库函数,是纯粹的C语法关键字。

下面用strace跟踪,证明return确实是调用了exit:

最后调用exit_group(99),其中的99就是return 99。这个为什么不是exit(99)?

首先,我们来分析C库的退出函数exit,代码如下:

void exit (int status) {

__run_exit_handlers (status, &__exit_funcs, true);

}

C库的exit主要用来执行所有注册的退出函数,比如使用atexit或on_exit注册的函数。执行完注册的退出函数后,__run_exit_handlers会调用_exit,代码如下:

void _exit (status)

int status;

{

while (1) {

#ifdef __NR_exit_group

INLINE_SYSCALL (exit_group, 1, status); #endif

INLINE_SYSCALL (exit, 1, status); #ifdef ABORT_INSTRUCTION

ABORT_INSTRUCTION; #endif

}

}

上面的代码很简单,当平台有exit_group时,就调用exit_group,否则就调用exit,这两个指的都是系统调用,并不是C库中的exit。从Linux内核2.5.35版本以后,为了支持线程,就有了exit_group。这个系统调用不仅仅是用于退出当前线程,还会让所有线程组的线程全部退出。

如果是shell相关的编程,shell可能需要获取进程的退出值,那么退出值最好不要大于128。如果退出值大于128,会给shell带来困扰。POSIX 标准规定了退出状态及其含义如下:

127以内是命令本身相关的返回值,128以上则是和操作系统相关。

1~125之间是由各个命令自己定义的。

比如脚本中用exit 传递返回值,exit 133表示返回值是133,可以通过$?变量查看返回值。

8位二进制可表示的范围是0~255,超过范围后就会回卷。比如,返回值若为256,二进制就是100000000,那么由于只用低8位,那么返回值则为0.

返回值若为257,二进制就是100000001,那么由于只用低8位,那么返回值则为1.

128以上的返回值,是由内核来管理的,比如用中断信号终止一个程序运行,该程序的返回值就是130,如下:

若用terminate信号杀掉程序,返回值为143.

模拟以上情况,可在执行sleep 99后,在另一窗口向这个程序发15信号即可。

c程序也一样,以下代码:

用strace跟这个程序,运行到最后,如图中,exited with 0,这说明确实以低8位做为返回值。

下面就不跟踪了,直接运行看结果。

看过本文的朋友,给大伙儿拜年啦,过年好!

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180213G13NLZ00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券