Linux system函数返回值

本文详细解析了C语言中system函数的工作原理及其返回值的意义,包括如何判断shell脚本是否正常执行结束,以及如何获取shell脚本的返回值。
例:
status = system("./test.sh");

1、先统一两个说法:
(1)system返回值:指调用system函数后的返回值,比如上例中status为system返回值
(2)shell返回值:指system所调用的shell命令的返回值,比如上例中,test.sh中返回的值为shell返回值。

2、如何正确判断test.sh是否正确执行?
仅判断status是否==0?或者仅判断status是否!=-1? 

都错!

3、man中对于system的说明

RETURN VALUE
       The value returned is -1 on error (e.g.  fork() failed), and the return
       status  of  the command otherwise.  This latter return status is in the
       format specified in wait(2).  Thus, the exit code of the  command  will
       be  WEXITSTATUS(status).   In  case  /bin/sh could not be executed, the
       exit status will be that of a command that does exit(127)
.
看得很晕吧?

system函数对返回值的处理,涉及3个阶段:
阶段1:创建子进程等准备工作。如果失败,返回-1。
阶段2:调用/bin/sh拉起shell脚本,如果拉起失败或者shell未正常执行结束(参见备注1),原因值被写入到status的低8~15比特位中。system的man中只说明了会写了127这个值,但实测发现还会写126等值。
阶段3:如果shell脚本正常执行结束,将shell返回值填到status的低8~15比特位中。
备注1:
只要能够调用到/bin/sh,并且执行shell过程中没有被其他信号异常中断,都算正常结束。
比如:不管shell脚本中返回什么原因值,是0还是非0,都算正常执行结束。即使shell脚本不存在或没有执行权限,也都算正常执行结束。
如果shell脚本执行过程中被强制kill掉等情况则算异常结束。

如何判断阶段2中,shell脚本是否正常执行结束呢?系统提供了宏:WIFEXITED(status)。如果WIFEXITED(status)为真,则说明正常结束。
如何取得阶段3中的shell返回值?你可以直接通过右移8bit来实现,但安全的做法是使用系统提供的宏:WEXITSTATUS(status)。


由于我们一般在shell脚本中会通过返回值判断本脚本是否正常执行,如果成功返回0,失败返回正数。
所以综上,判断一个system函数调用shell脚本是否正常结束的方法应该是如下3个条件同时成立:
(1)-1 != status
(2)WIFEXITED(status)为真
(3)0 == WEXITSTATUS(status)

注意:
根据以上分析,当shell脚本不存在、没有执行权限等场景下时,以上前2个条件仍会成立,此时WEXITSTATUS(status)为127,126等数值。
所以,我们在shell脚本中不能将127,126等数值定义为返回值,否则无法区分中是shell的返回值,还是调用shell脚本异常的原因值。shell脚本中的返回值最好多1开始递增。

判断shell脚本正常执行结束的健全代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>

int main()
{
    pid_t status;


    status = system("./test.sh");

    if (-1 == status)
    {
        printf("system error!");
    }
    else
    {
        printf("exit status value = [0x%x]\n", status);

        if (WIFEXITED(status))
        {
            if (0 == WEXITSTATUS(status))
            {
                printf("run shell script successfully.\n");
            }
            else
            {
                printf("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));
            }
        }
        else
        {
            printf("exit status = [%d]\n", WEXITSTATUS(status));
        }
    }

    return 0;
}

WIFEXITED(stat_val) Evaluates to a non-zero value if status
was returned for a child process that
terminated normally.

WEXITSTATUS(stat_val) If the value of WIFEXITED(stat_val) is
non-zero, this macro evaluates to the
low-order 8 bits of the status argument
that the child process passed to _exit()
or exit(), or the value the child
process returned from main().


### SAP中受托批指令流程订单受托外包装流程订单的区别 在SAP系统中,受托批指令流程订单(Subcontracting Batch Instruction Process Order)和受托外包装流程订单(Subcontracting Packaging Process Order)虽然都涉及外部协作方的参,但在实际业务场景中的应用目的、处理逻辑以及数据流存在显著差异。 #### 1. **定义应用场景** - **受托批指令流程订单** 主要用于生产制造过程中某一特定工序由外部供应商完成的情况。在这种模式下,企业将半成品发送至外部供应商处进行加工,供应商仅负责指定工序的操作[^3]。完成后,加工后的物品返回企业内部继续后续工艺直至最终成品入库。此类型的订单强调的是对外部供应商执行的具体加工作业及其费用核算。 - **受托外包装流程订单** 则专注于产品的包装环节外包给第三方服务商的情形。它通常发生在商品已经完成主要生产和组装之后,但需要额外的专业化包装服务才能满足市场或客户需求时采用的方式之一[^1]。这里更侧重于如何利用外部资源提升物流效率和服务质量而非单纯的技术性加工活动本身。 #### 2. **物料流动方向** - 对于**受托批指令流程订单**, 物料通常是未完全制成的产品部件或者中间状态下的材料被送往合作厂商那里接受进一步改造后再送回来加入到整体生产线当中去形成最终产物的一部分. - 而在**受托外包装流程订单**的情况下, 成品可能已经被制造完毕并准备就绪待运往客户手中之前才交给专门从事此类工作的单位来进行最后一步即适当形式(如按箱装载)以便运输储存更加便捷安全高效地到达目的地. #### 3. **财务管理重点** - 在涉及到成本计算方面,**受托批指令流程订单**更多关注的是基于所消耗时间长度或者其他衡量指标来确定应付予承包者的报酬金额大小等问题;同时还要考虑到原先转移出去那些处于初级形态阶段的商品价值变化情况等因素影响整个供应链的成本构分析过程之中. - 相较之下,**受托外包装流程订单**则把焦点放在因实施这些特殊安排所产生的附加支出上面——比如租赁使用某些专用设备设施之类的开销项目上,并且由于这属于末端处理性质的工作所以一般不会直接影响到核心产品本身的定价策略制定等方面考虑范围之内. #### 4. **系统配置功能支持** - 配合上述两种不同类型的任务需求,SAP软件平台提供了相应定制化的解决方案选项可供选择运用其中: - 当面对类似于前者那样的复杂技术要求较高的作业环境时候就需要启用更为精细复杂的参数设定机制以确保能够准确追踪记录每一个细节步骤进展状况直到顺利完成为止. ```abap CALL TRANSACTION 'CO01' USING itab MODE 'E' EXPORTING SELECTION-TABLE = sel_tab VARIANTS = var_tab[] ``` 上述代码片段展示了调用事务码`CO01`(创建生产订单)的一个例子,在设置条件筛选表(`sel_tab`)及变量列表(`var_tab[]`)的基础上自动化生成目标文档实例. - 至于后者相对简单明了一些的情境条件下,则可以通过简化版界面快速输入必要信息要素从而加快工作效率减少人为错误发生几率的同时保持足够的灵活性适应各种可能出现的变化情形. ```sql SELECT * FROM vbak INTO TABLE @DATA(lt_vbak) WHERE vbeln IN (@lv_belnr_low TO @lv_belnr_high). ``` 此SQL查询语句是从销售凭证头表(VBAK)提取符合条件的数据集存入局部内表@DATA(lt_vbak),适用于批量检索关联记录场合。 --- ### 论 综上所述可以看出尽管两者同属ERP领域内的子模块范畴却各自承担着截然不同的使命角色发挥独特作用贡献自身力量共同构建起现代化企业管理信息化体系大厦基石部分不可或缺的重要组成单元组成部分构成因素等等诸多层面意义非凡值得深入研究
评论 15
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值