在应用程序中有时候需要调用第三方的应用,这是常见的需求。此时可以使用linux下的exec命令或system命令达到目的。但是这两个该选择哪个呢?有什么区别?下面总结介绍下。
exec和system介绍
在Linux中,`exec`命令用于在当前进程中执行一个新的程序。它会取代当前进程的内容,并用新的程序来替换它。`exec`命令接受两个参数,第一个参数是要执行的程序的路径,第二个参数是一个字符串数组,用于传递给新程序的命令行参数。
`system`命令也用于在当前进程中执行一个新的程序,但它是通过调用shell来实现的。`system`命令接受一个字符串参数,该字符串包含要执行的命令。它会创建一个新的shell进程,并在该进程中执行指定的命令。
`exec`和`system`的主要区别在于它们的实现方式和用途。`exec`直接在当前进程中执行一个新程序,而`system`通过调用shell来执行命令。因此,`exec`更加高效,因为它避免了创建新的进程和shell的开销。另外,`exec`通常用于在当前进程中执行其他可执行程序,而`system`则更适用于执行shell命令和脚本。exec是一系列函数接口的总称,其实分为多个函数接口版本。
exec族函数:
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
如何选择
在Linux中,exec和system是两个不同的命令,用于执行外部程序。
exec是一个系统调用,它可以用来执行一个新的程序,并替换当前进程的内容。它需要提供一个可执行文件的路径以及命令行参数,然后它会将当前进程替换为指定的程序。execvp命令是一个低级别的命令,它可以更好地控制执行的过程,但是它不会创建新的进程。
system是一个库函数,它可以用来执行一个命令。它接收一个字符串参数,该参数是要执行的命令,然后它会创建一个新的进程来执行该命令。system命令是一个高级别的命令,它更简单易用,但是它的控制能力较弱。
选择使用exec还是system取决于你的需求。如果你需要更细粒度的控制可以使用exec。例如如果你需要替换当前进程的内容,或者需要在子进程中执行一些特定的操作,那么exec可能更适合。另一方面,如果你只是简单地执行一个命令,并希望获得执行结果,那么system可能更方便。
void set_gpio64_low(void)
{
system("echo 64 > /sys/class/gpio/export");
system("echo out > /sys/class/gpio/gpio64/direction");
system("echo 0 > /sys/class/gpio/gpio64/value");
}
`exec`命令的基本用法
#include <unistd.h>
int execvp(const char *file, char *const argv[]);
要执行一个shell脚本,可以将shell解释器的路径作为第一个参数,将脚本文件的路径作为第二个参数,并将其他参数作为字符串数组传递。
下面是一个示例,演示如何使用`execvp`命令执行一个shell脚本:
#include <unistd.h>
#include <stdio.h>
int main() {
char *const argv[] = {"./script.sh", NULL};
execvp("/bin/sh", argv);
printf("execvp failed\n");
return 0;
}
在上面的示例中,`./script.sh`是要执行的shell脚本的路径。`/bin/sh`是shell解释器的路径。`NULL`表示参数数组的结束。
请注意,`execvp`命令执行成功后,当前进程将被替换为新的程序,因此后续代码不会被执行。如果`execvp`命令执行失败,它将返回-1,并且可以使用`perror`函数打印错误信息。
确保在执行`execvp`命令之前,脚本文件具有执行权限。可以使用`chmod`命令为脚本文件添加执行权限。
`execvp`命令执行成功后的当前进程将被替换为新的程序,后续代码不会被执行。如果想要在`execvp`命令执行后继续执行代码,可以使用`fork`函数创建一个子进程,在子进程中调用`execvp`命令,而父进程则可以继续执行后续代码。
下面是一个示例代码:
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
// 子进程中执行新的程序
char *args[] = {"ls", "-l", NULL};
execvp("ls", args);
} else if (pid > 0) {
// 父进程中继续执行后续代码
printf("This is the parent process.\n");
// 可以添加其他代码
} else {
// fork失败
printf("Fork failed.\n");
return 1;
}
return 0;
}
在上述代码中,子进程中调用了`execvp`命令来执行`ls -l`命令,而父进程则继续执行后续代码。
如果你想在应用程序中满足条件时调用其他应用程序,可以考虑使用fork和execvp的组合。使用fork创建一个子进程,在子进程中使用execvp执行其他应用程序,这样可以避免替换当前进程,同时在父进程中可以继续执行后续代码。
system与execl的区别
system会新起一个子进程来调用要执行的命令。而exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。
int system(const char * cmdstring){
pid_t pid;
int status;
if(cmdstring == NULL){
return (1);
}
if((pid = fork())<0){
status = -1;
}else if(pid == 0){
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);//底层就是execl
exit(127); //子进程正常执行则不会执行此语句
}else{
while(waitpid(pid, &status, 0) < 0){
if(errno != EINTER){
status = -1;
break;
}
}
}
return status;
}
正确处理 execvp 函数调用错误方案和相应的输出消息
需要注意的是,exec
系列函数只有在发生错误时才会返回,所以要实现错误检查例程,并根据需要处理相应的代码路径。
其中 execvp
在失败时返回 -1
,而且它还会设置 errno
变量。不过要注意,errno
应该在函数调用前明确设置为 0,只有在给定的调用返回后才检查该值。execvp
函数可以接受没有斜线的文件名,这意味着文件是在 PATH
环境变量指定的目录中搜索的。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(void) {
const char *args[] = { "vim", "/home/ben/tmp3.txt", NULL };
execvp("vim", args);
exit(EXIT_SUCCESS);
}
假设用户需要创建一个新的进程,并执行给定的程序代码,那么在这种情况下我们可以利用 fork
函数调用与 execvp
相结合。在这种情况下,我们可以利用 fork
函数调用与 execvp
相结合。fork
复制调用的进程,并创建一个新的进程,称为-子进程。在下面的例子中,我们实现了一个自定义函数包装器来创建一个新的进程并加载/执行给定的程序代码。注意,一旦创建了子进程,它就会执行不同的代码,而父进程则会等待,直到子进程退出。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
pid_t spawnChild(const char* program, char** arg_list)
{
pid_t ch_pid = fork();
if (ch_pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (ch_pid > 0) {
printf("spawn child with pid - %d\n", ch_pid);
return ch_pid;
} else {
execvp(program, arg_list);
perror("execve");
exit(EXIT_FAILURE);
}
}
int main(void) {
const char *args[] = { "vim", "/home/ben/tmp3.txt", NULL };
pid_t child;
int wstatus;
child = spawnChild("vim", args);
if (waitpid(child, &wstatus, WUNTRACED | WCONTINUED) == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
其他资源
Linux -- system、.(source)、exec的区别_青椒*^_^*凤爪爪的博客-CSDN博客
exec和system函数_execl system_Lawrence_121的博客-CSDN博客
Linux -- system、.(source)、exec的区别_青椒*^_^*凤爪爪的博客-CSDN博客
exec族函数、system()函数和popen函数_exec函数 system_基尔霍夫原来是码农的博客-CSDN博客 https://www.cnblogs.com/armsom/articles/17523386.html文章来源:https://www.toymoban.com/news/detail-615096.html
Linux下对GPIO的操作控制(基于GPIO子系统)_linux 通过按钮控制gpio de_金城孤客的博客-CSDN博客 Linux系统应用层GPIO控制_echo 268 > export增加gpio268_技术の宅的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-615096.html
到了这里,关于linux的exec和system函数介绍及选择的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!