如何编写 C 程序来执行另一个程序?

2024-11-13 08:36:00
admin
原创
24
摘要:问题描述:在 Linux 中,我想编写一个启动另一个程序的 C 程序。当程序运行时,shell 将等待您输入您在程序中定义的命令。此命令将启动第二个程序。例如,假设在调用程序所在的目录中有一个名为“hello”的简单 C 程序。“hello”程序打印输出“hello, world”。第一个程序将运行,用户将输...

问题描述:

在 Linux 中,我想编写一个启动另一个程序的 C 程序。当程序运行时,shell 将等待您输入您在程序中定义的命令。此命令将启动第二个程序。

例如,假设在调用程序所在的目录中有一个名为“hello”的简单 C 程序。“hello”程序打印输出“hello, world”。第一个程序将运行,用户将输入命令“hello”。“hello”程序将被执行,并将“hello, world.”输出到 shell。

我搜索了一下,有人建议使用“fork()”和“exec()”函数。其他人建议使用“system()”。我不了解这些函数。我该如何调用这些函数?它们适合使用吗?

带有解释的示例代码将非常有帮助。也欢迎其他答案。非常感谢您的帮助。


解决方案 1:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* for fork */
#include <sys/types.h> /* for pid_t */
#include <sys/wait.h> /* for wait */

int main()
{
    /*Spawn a child to run the program.*/
    pid_t pid=fork();
    if (pid==0) { /* child process */
        static char *argv[]={"echo","Foo is my name.",NULL};
        execv("/bin/echo",argv);
        exit(127); /* only if execv fails */
    }
    else { /* pid!=0; parent process */
        waitpid(pid,0,0); /* wait for child to exit */
    }
    return 0;
}

解决方案 2:

如果你是 fork 新手,那么有关 fork 和 exec 的图形表示可能会对你有帮助。

描述fork()

  +-------------+  
  |main program |  
  +-------------+    (fork())
        |___________________________  
  +-------------+                   |
  |main program |           +-------------+ 
  +-------------+           |main program |
        |                   +-------------+  
  +-------------+                   |        (exec())
  |main program |           +-------------+
  +-------------+           |hello program|
                            +-------------+  

您可能已经在教程中读到过,调用后fork()会创建现有程序的副本,之后exec()会用您作为参数传递给它的新程序替换该副本。之后将运行两个程序的两个执行单元fork()

解决方案 3:

对你来说还不够吗system()

/* ... */
if (!strcmp(cmd, "hello")) system("hello.exe");
/* ... */

解决方案 4:

我搜索了一下,有人建议使用fork()exec()函数。其他人建议使用system()。我不了解这些函数。我该如何调用这些函数?它们适合使用吗?

是的。首先阅读文档(man页面),例如fork(2)、exec(3)、system(3)。很可能您在本地计算机上有该文档,使用man(1)。请注意system使用sh(通过bash(1)或dash(1)),因为它是fork-ing、execve(2) -ing 和waitpid(2) -ing /bin/shPOSIX shell。

我认为这fork很难理解,因为成功时它会返回“两次”。我不会在这里解释它(我需要很多页才能解释)。我建议首先阅读fork(系统调用) wikipage。然后,阅读一些好的 Linux 编程书籍,例如《高级 Linux 编程》(可免费下载)。

另请阅读有关虚拟地址空间和proc(5)的内容。

您还可以阅读《操作系统:三个简单的部分》以获得更全面的了解。

解决方案 5:

对于最简单的情况,你应该将两个编译好的程序放在一个目录中:

> ls
.
hello
second

在第二个程序中你只需要调用system("hello");

解决方案 6:

您的问题的答案取决于您是否要在执行第二个(或子)程序后在父程序中执行其他语句。

如果您想在执行第二个(或子)程序后在父程序中执行其他语句,我会使用system()

如果在执行第二个(或子)程序后不需要从父程序执行其他语句,我只需使用execv()。不会创建第二个进程。父程序将终止,第二个程序将使用与父程序相同的进程 ID 运行。

PS 在这种情况下,您也可以使用system()。但是,如果使用system(),则会创建两个具有不同进程 ID 的进程 - 一个进程 ID 用于主程序,另一个进程 ID 用于第二个程序。

在您的示例中,您可以使用system()函数或execv()函数。

这是一个简单的、不言自明的示例system()

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello from the parent process
");

    if ( system("echo 'Hello from the child process' > test.txt") != 0 )
    {
        printf("ERROR executing system() command
");
    }

    if ( system("cat test.txt") != 0 )
    {
        printf("ERROR executing system() command
");
    }

    printf("Executing from the parent process again!
");
}

输出如下:

Grinchs-MBP:Downloads rob$ ./parent3
Hello from the parent process
Hello from the child process
Executing from the parent process again!

stdlib.h如果您打算使用,请记得包含头文件system()

如果您在子程序或第二个程序完成后不需要在父程序中执行其他语句,我只会execv()父程序中使用。

在这种情况下,您不需要使用 创建 fork fork()。您只需要使用execv()。如果您想使用execv(),请记住包含unistd.h头文件。

execv()被调用时,调用它的进程将被终止,并由分配的内存部分中具有相同 ID 的新进程替换。

如果execv()执行成功,则不会返回。如果返回,则是因为发生了错误。换句话说,execv()应该是您打算从父程序执行的最后一条语句,因为execv()只有在发生错误的情况下才会返回到父程序。

再说一遍——如果您想从父程序执行另一个程序,并且想在第二个(或子)程序完成后在父程序中执行其他语句,那么我会使用system()它。

这是一个使用 的简单示例execv()

父进程代码

#include  <stdio.h>
#include  <unistd.h>
#include  <errno.h>

int main ()
{
printf ("I am the parent process

");

char *arg_Ptr[4];
arg_Ptr[0] = "child.c";
arg_Ptr[1] = "Hello from the child process";
arg_Ptr[2] = "Good-Bye from the child process!";
arg_Ptr[3] = NULL;

execv("/Users/rob/Downloads/child.bin", arg_Ptr);
printf ( "Error:  %i
", errno);
}

子进程代码 (保存在 /Users/rob/Downloads/child.bin)。

#include  <stdio.h>

int main(int argc, char *argv[])
{
 printf ("I am the child process
");

 printf ("Argument 1: %s
", argv[1]);
 printf ("Argument 2: %s
", argv[2]);
 printf ("Argument 3: %s
", argv[3]); 
}

输出如下

Grinchs-MBP:Downloads rob$ ./parent 
I am the parent process

I am the child process
Argument 1: Hello from the child process
Argument 2: Good-Bye from the child process!
Argument 3: (null)
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用