【问题标题】:system() and popen() not availablesystem() 和 popen() 不可用
【发布时间】:2014-03-14 10:55:48
【问题描述】:

我需要在 Linux 机器上从 C++ 代码运行 shell 脚本。我试过使用 system() 和 popen() 函数。当我在开发机器上测试它们时一切正常,但是当我在实际设备上尝试相同的功能时 - 我收到错误 127。从到目前为止的信息来看,这意味着该脚本解释器不可用,但实际上机器安装了带有 ash 的busybox里面的翻译。我可以通过命令行运行相同的命令——完全没有问题。当我尝试从代码中执行此操作时,我得到:

Command: sh -n '/home/test/test.sh' Status: 127

这种行为的原因可能是什么? 我是否有可能达到某种内核限制?

代码示例1:

int Files::CallShell( std::string& command )
{
    int status = 0;
    char buff[512] = { 0 };
    FILE *in;

    if ( !(in = popen( command.c_str(), "r") ) )
    {
        printf( "Can't execute: %s\n", command.c_str() );
        status = -1;
    }

    while ( fgets( buff, sizeof(buff), in) != NULL )
    {
        printf( "Result: %s\n", buff );
    }

    status = pclose( in );
    status = ( WIFEXITED( status ) )? WEXITSTATUS( status ) : status;

    printf("Command: %s Status: %d\n", command.c_str(), status );

    return status;
} 

代码示例2:

int Files::CallShell2( std::string& command )
{
    int status = 0;

    status = system( command.c_str() );
    status = ( WIFEXITED( status ) )? WEXITSTATUS( status ) : status;
    printf("Command: %s Status: %d\n", command.c_str(), status );

    return status;
} 

【问题讨论】:

  • 开发机器和目标机器上安装了哪个操作系统?另外,您的安装脚本还在做什么?也就是说,您如何确定是您的代码导致了问题?
  • 开发:x64 Xubuntu 机器。目标:带有 ARM6 的嵌入式系统、带有一些 RT 补丁的 Linux 3.0.9、busybox 1.21 和一些定制服务。我确实知道目标设备非常具体,但任何线索都可以。
  • 你是否包含了相关的标题?
  • 检查/bin/sh 是否在目标机器上工作。或者考虑使用fork + execve;也在目标机器上使用strace
  • 据我所知 system 是在 stdlib 中定义的,所以它当然被包含在内。此外 - 缺少标头会导致编译错误,而不是运行时错误。

标签: c++ linux bash busybox


【解决方案1】:

system() 库函数执行/bin/sh -c 以运行传递的命令。如果/bin/sh 不存在,或者ash 没有以同样的方式解析参数,你会得到这个错误。您可以将/bin/sh 链接到/bin/ash,或者使用fork()exec 系列函数之一更好地实现您自己的system() 版本,它可以调用ash 而不是@ 987654331@.

【讨论】:

  • ...好吧,既然是busybox ash,它甚至可能不是/bin/ash。最好将busybox调用为sh——它会识别argv[0]并采取适当的行动。
【解决方案2】:

“-n”开关用于检查 shell 脚本的语法...如果“-i”未设置。检查外壳的手册页。至于退出状态检查。从手册页:

退出状态

shell 检测到的错误,例如语法错误,将导致 shell 以非零退出状态退出。如果外壳不是 交互式 shell,shell 文件的执行将被中止。其他- 否则,shell 将返回最后一个命令 exe- 的退出状态 cuted,或者如果 exit 内置函数与数字参数一起使用,它将 返回参数。

【讨论】:

  • 这一行只是一个例子。任何其他命令都返回相同的状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多