【问题标题】:How does the C++ interpret the return value of system()C++如何解释system()的返回值
【发布时间】:2018-02-14 23:23:05
【问题描述】:

我需要让我的 C++ 程序执行一个 bash 脚本。所以我想我需要使用system(),这里是一个例子:

bash 脚本test.sh:

#!/bin/sh
exit 1

C++:

int main()
{
    std::cout << system("./test.sh") << std::endl;
    return 0;
}

令我惊讶的是,我收到了256 等。这是我发现的:

 test.sh | C++
---------|-----
 exit 0  | 0
 exit 1  | 256
 exit 2  | 512
...

我不知道为什么。是否有可能获得 0、1、2 等?值是否取决于机器?

【问题讨论】:

  • 根据手册,返回值(大部分)是实现定义的en.cppreference.com/w/cpp/utility/program/system
  • @Galik:我假设他正在使用 Linux,其中:The value returned is -1 on error (e.g., fork(2) failed), and the return status of the command otherwise. 成立。见Linux manpage of system
  • @AndreKampling 然而,重要的是要提到命令的返回状态不是从main 返回的值。
  • 你检查过你的shell脚本在c++之外产生了什么状态吗?

标签: c++ linux bash system


【解决方案1】:

值是否取决于机器?

是的(至少就 C++ 标准而言)。

有可能得到 0、1、2 等吗?

C++ 标准没有提供获取子进程返回值的方法,但是POSIX 提供了,这适用于你,因为你使用的是 Linux。

返回值

如果 command 是一个空指针,system() 将返回非零值以指示命令处理器可用,如果没有可用的,则返回零。 [CX] [选项开始] 当命令为 NULL 时,system() 函数应始终返回非零值。 [选项结束]

[CX] [Option Start] 如果command 不是空指针,system() 将返回命令语言解释器的终止状态以waitpid() 指定的格式。终止状态应与 sh 实用程序的定义相同;否则,终止状态未指定。如果在创建子进程后某些错误阻止命令语言解释器执行,则 system() 的返回值应该就像命令语言解释器已使用 exit(127) 或 _exit(127) 终止一样。如果无法创建子进程,或者无法获得命令语言解释器的终止状态,system() 将返回 -1 并设置 errno 以指示错误。 [选项结束]

waitpid() 指定一个宏,可用于提取从main() 返回的值。

WEXITSTATUS(stat_val)

如果 WIFEXITED(stat_val) 的值非零,则此宏计算为子进程传递给 _exit() 或 exit() 的状态参数的低 8 位,或子进程的值从 main() 返回。

【讨论】:

    【解决方案2】:

    正如 cmets 中所说,return value of system() is implementation defined.
    但我假设您在 Linux 上,以下内容成立 (see manpage of system()):

    返回值

    错误时返回的值为-1(例如,fork(2) 失败),否则返回命令的状态。后一种返回状态采用 wait(2) 中指定的格式。因此,该命令的退出代码将是 WEXITSTATUS(status)。如果 /bin/sh 无法执行,退出状态将是执行 exit(127) 的命令的状态。

    也就是说要获取命令的退出状态使用WEXITSTATUS():

    std::cout << WEXITSTATUS(system("./test.sh")) << std::endl;
    

    manpage of wait() 解释了在 stdlib.h 头文件中定义的WEXITSTATUS()

    WEXITSTATUS(状态)

    返回孩子的退出状态。这由子级在调用 exit(3) 或 _exit(2) 时指定的 status 参数的最低有效 8 位组成或作为 main() 中的 return 语句的参数。仅当 WIFEXITED 返回 true 时才应使用此宏。

    【讨论】:

      猜你喜欢
      • 2014-07-27
      • 2012-01-29
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多