linux环境下主函数到底能不能linux select返回负值值

Shell中函数返回值超出问题
投稿:junjie
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Shell中函数返回值超出问题,shell中通过return返回是有限制的,最大返回255,超过255,则从0开始计算,需要的朋友可以参考下
  快半年没有写博客了,荒废了很久,工作中的杂事太多,自己越来越懒了。为了鞭策自己成长,还是要坚持写写博客,记录自己的成长。
2、shell函数介绍
&[ function ] funname [()]
(1)可以带function fun()& 定义,也可以直接fun() 定义,不带任何参数。
(2)参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255),还可以通过echo 直接返回。
&&&&& shell中通过return返回是有限制的,最大返回255,超过255,则从0开始计算。
今天在工作中犯了这个错误,导致输出的值不对,被测试部提bug。
shell脚本调用例子:
echo "shell function operation"
&&& local num1=100
&&& local num2=100
&&& let sum=$num1+$num2
&&& return $sum
&&& local num1=100
&&& local num2=155
&&& let sum=$num1+$num2
&&& return $sum
&&& local num1=100
&&& local num2=156
&&& let sum=$num1+$num2
&&& return $sum
&&& local num1=100
&&& local num2=156
&&& let sum=$num1+$num2
&&& echo $sum
echo "called func1:$?"
echo "called func2:$?"
echo "called func3:$?"
sum=`func4`
echo "called func4:$sum"
执行结果如下所示:
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具linux中函数test_bit :简单地返回这个位的当前值.
我的图书馆
linux中函数test_bit :简单地返回这个位的当前值.
网上说:#if 0 /* Fool kernel-doc since it doesn't do macros yet */ &/**&&* test_bit - Determine whether a bit is set&&* @nr: bit number to test&&* @addr: Address to start counting from&&*/ &static int test_bit(int nr, const volatile void * addr); &#endif &static __always_inline int constant_test_bit(int nr, const volatile unsigned long *addr) &{ && & return ((1UL && (nr & 31)) & (addr[nr && 5])) != 0; &} &&1.对于编译时的常数使用上面的函数进行判断假设我们要测试的数为test = 0x,它的第三位是否为1(位数是从0数起),即nr = 3 = 0x,addr就是我们测试的数的地址addr = & 对于运算addr[nr && 5] = addr[0] 也就是test的值对于前面部分 1UL左移3位,其值就是0x,它们&运算后,结果是0x != 0,所以return的结果返回是1即0x的第3位是1,其结果也确实是1。其他的情况照样子可以这样子验证。问题:1.什么是原子的位操作?为什么说函数test_bit是唯一一个不需要是原子的位操作?2.如果test =0x,函数_test_bit还能测出第7位为1吗?addr[nr && 5] = addr[7&&5]= addr[7&&5]=addr[0]=0x,故((1UL && (nr & 31)) & (addr[nr && 5])) --&((0x) & (0x) != 0,即:返回值仍为1!正确!另:test_bit (int nr, const volatile void *addr){ return 1 & (((const volatile __u32 *) addr)[nr && 5] && (nr & 31));}static inline int test_bit(int nr, const unsigned long *vaddr){ return (vaddr[nr && 5] & (1UL && (nr & 31))) != 0;}
发表评论:
TA的最新馆藏[转]&[转]&[转]&[转]&linux下system函数错误返回-1 错误原因NO child processes
调用system函数执行一个shell命令,返回-1,错误提示no child processes 但system可以执行成功
原因是调用system之前有放置忽略SIGCHLD的语句
signal(SIGCHLD, SIG_IGN);
如果SIGCHLD信号行为被设置为SIG_IGN时,waitpid()函数有可能因为找不到子进程而报ECHILD错误。似乎我们找到了问题的解决方案:在调用system()函数前重新设置SIGCHLD信号为缺省值,即signal(SIGCHLD, SIG_DFL)。
解决办法 用pox_system()函数替代system(),只需要修改此处一个函数,其他调用处都不需要改。
typedef void (*sighandler_t)(int);
int pox_system(const char *cmd_line)
int ret = 0;
sighandler_t old_
old_handler = signal(SIGCHLD, SIG_DFL);
ret = system(cmd_line);
signal(SIGCHLD, old_handler);
SIG_DFL:默认信号处理程序
SIG_IGN:忽略信号的处理程序
测试过确实很奏效,感谢帖子的作者!
参考文章:http://my.oschina.net/renhc/blog/54582
原文如下:
今天,一个运行了近一年的程序突然挂掉了,问题定位到是system()函数出的问题,关于该函数的简单使用在我上篇文章做过介绍:&http://my.oschina.net/renhc/blog/53580
先看一下问题
简单封装了一下system()函数:
int&pox_system(const&char&*cmd_line)
&&&&return&system(cmd_line);
函数调用:
= pox_system(&gzip
-c /var/opt/I00005.xml & /var/opt/I00005.z&);
&&&&Log(&zip
file failed\n&);
问题现象:每次执行到此处,都会zip failed。而单独把该命令拿出来在shell里执行却总是对的,事实上该段代码已运行了很长时间,从没出过问题。
糟糕的日志
分析log时,我们只能看到“zip file failed”这个我们自定义的信息,至于为什么fail,毫无线索。
那好,我们先试着找出更多的线索:
= pox_system(&gzip
-c /var/opt/I00005.xml & /var/opt/I00005.z&);
&&&&Log(&zip
file failed: %s\n&,&strerror(errno));&
我们增加了log,通过system()函数设置的errno,我们得到一个非常有用的线索:system()函数失败是由于“&No child processes”。继续找Root
谁动了errno
我们通过上面的线索,知道system()函数设置了errno为ECHILD,然而从system()函数的man手册里我们找不到任何有关EHILD的信息。我们知道system()函数执行过程为:fork()-&exec()-&waitpid()。很显然waitpid()有重大嫌疑,我们去查一下man手册,看该函数有没有可能设置ECHILD:
(for waitpid() or waitid()) The process specified by pid (waitpid()) or idtype and id (waitid()) does not exist or is not a child of
the calling process. (This can happen for one's own child if the action for SIGCHLD is set to SIG_IGN. See also the Linux Notes section about threads.)
果然有料,如果SIGCHLD信号行为被设置为SIG_IGN时,waitpid()函数有可能因为找不到子进程而报ECHILD错误。似乎我们找到了问题的解决方案:在调用system()函数前重新设置SIGCHLD信号为缺省值,即signal(SIGCHLD, SIG_DFL)。我们很兴奋,暂时顾不上看Linux Notes部分,直接加上代码测试!乖乖,问题解决了!
如此处理问题是你的风格吗
正当我们急于check in 代码时,一个疑问出现了:“这个错误为什么以前没发生”?是啊,运行良好的程序怎么突然就挂了呢?首先我们代码没有改动,那么肯定是外部因素了。一想到外部因素,我们开始抱怨:“肯定是其他组的程序影响我们了!”但抱怨这是没用的,如果你这么认为,那么请拿出证据!但静下来分析一下不难发现,这不可能是其他程序的影响,其他进程不可能影响我们进程对信号的处理方式。
system()函数之前没出错,是因为systeme()函数依赖了系统的一个特性,那就是内核初始化进程时对SIGCHLD信号的处理方式为SIG_DFL,这是什么什么意思呢?即内核发现进程的子进程终止后给进程发送一个SIGCHLD信号,进程收到该信号后采用SIG_DFL方式处理,那么SIG_DFL又是什么方式呢?SIG_DFL是一个宏,定义了一个信号处理函数指针,事实上该信号处理函数什么也没做。这个特性正是system()函数需要的,system()函数首先fork()一个子进程执行command命令,执行完后system()函数会使用waitpid()函数对子进程进行收尸。
通过上面的分析,我们可以清醒的得知,system()执行前,SIGCHLD信号的处理方式肯定变了,不再是SIG_DFL了,至于变成什么暂时不知道,事实上,我们也不需要知道,我们只需要记得使用system()函数前把SIGCHLD信号处理方式显式修改为SIG_DFL方式,同时记录原来的处理方式,使用完system()后再设为原来的处理方式。这样我们可以屏蔽因系统升级或信号处理方式改变带来的影响。
我们公司采用的是持续集成+敏捷开发模式,每天都会由专门的team负责自动化case的测试,每次称为一个build,我们分析了本次build与上次build使用的系统版本,发现版本确实升级了。于是我们找到了相关team进行验证,我们把问题详细的描述了一下,很快对方给了反馈,下面是邮件回复原文:
LIBGEN 里新增加了SIGCHLD的处理。将其ignore。为了避免僵尸进程的产生。
看来我们的猜想没错!问题分析到这里,解决方法也清晰了,于是我们修改了我们的pox_system()函数:
typedef&void&(*sighandler_t)(int);
int&pox_system(const&char&*cmd_line)
&&&int&ret
&&&sighandler_t
&&&old_handler
=&signal(SIGCHLD,
=&system(cmd_line);
&&&signal(SIGCHLD,
old_handler);
&&&return&
我想这是调用system()比较完美的解决方案了,同时使用pox_system()函数封装带来了非常棒的易维护性,我们只需要修改此处一个函数,其他调用处都不需要改。
后来,查看了对方修改的代码,果然从代码上找到了答案:
if&(signal(SIGCHLD,
SIG_IGN) == SIG_ERR) {
&&&&return&-1;
&&&&return&0;
我们公司的代码使用SVN进程管理的,到目前为止有很多branch,逐渐的,几乎每个branch都出现了上面的问题,于是我逐个在各个branchc上fix这个问题,几乎忙了一天,因为有的branch已被锁定,再想merge代码必须找相关负责人说明问题的严重性,还要在不同的环境上测试,我边做这些边想,系统这样升级合适吗?
首先,由于系统的升级导致我们的代码在测试时发现问题,这时再急忙去fix,造成了我们的被动,我想这是他们的一个失误。你做的升级必须要考虑到对其他team的影响吧?何况你做的是系统升级。升级前需要做个风险评估,对可能造成的影响通知大家,这样才职业嘛。
再者,据他们的说法,修改信号处理方式是为了避免僵尸进程,当然初衷是好的,但这样的升级影响了一些函数的使用方式,比如system()函数、wait()函数、waipid()、fork()函数,这些函数都与子进程有关,如果你希望使用wait()或waitpid()对子进程收尸,那么你必须使用上面介绍的方式:在调用前(事实上是fork()前)将SIGCHLD信号置为SIG_DFL处理方式,调用后(事实上wait()/waitpid()后)再将信号处理方式设置为从前的值。你的系统升级,强制大家完善代码,确实提高了代码质量,但是对于这种升级我不是很认同,试想一下,你见过多少fork()-&waitpid()前后都设置SIGCHLD信号的代码?
使用system()函数的建议
上在给出了调用system()函数的比较安全的用法,但使用system()函数还是容易出错,错在哪?那就是system()函数的返回值,关于其返回值的介绍请见上篇文章。system()函数有时很方便,但不可滥用!
1、建议system()函数只用来执行shell命令,因为一般来讲,system()返回值不是0就说明出错了;
2、建议监控一下system()函数的执行完毕后的errno值,争取出错时给出更多有用信息;
3、建议考虑一下system()函数的替代函数popen();其用法在我的另一篇文章有介绍。
文章评论 以下网友留言只代表其个人观点,不代表本网站的观点和立场。}

我要回帖

更多关于 湿疹到底能不能根治 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信