在應(yīng)用程序中有時(shí)候需要調(diào)用第三方的應(yīng)用,這是常見的需求。此時(shí)可以使用linux下的exec命令或system命令達(dá)到目的。但是這兩個(gè)該選擇哪個(gè)呢?有什么區(qū)別?下面總結(jié)介紹下。
exec和system介紹
在Linux中,`exec`命令用于在當(dāng)前進(jìn)程中執(zhí)行一個(gè)新的程序。它會(huì)取代當(dāng)前進(jìn)程的內(nèi)容,并用新的程序來(lái)替換它。`exec`命令接受兩個(gè)參數(shù),第一個(gè)參數(shù)是要執(zhí)行的程序的路徑,第二個(gè)參數(shù)是一個(gè)字符串?dāng)?shù)組,用于傳遞給新程序的命令行參數(shù)。
`system`命令也用于在當(dāng)前進(jìn)程中執(zhí)行一個(gè)新的程序,但它是通過(guò)調(diào)用shell來(lái)實(shí)現(xiàn)的。`system`命令接受一個(gè)字符串參數(shù),該字符串包含要執(zhí)行的命令。它會(huì)創(chuàng)建一個(gè)新的shell進(jìn)程,并在該進(jìn)程中執(zhí)行指定的命令。
`exec`和`system`的主要區(qū)別在于它們的實(shí)現(xiàn)方式和用途。`exec`直接在當(dāng)前進(jìn)程中執(zhí)行一個(gè)新程序,而`system`通過(guò)調(diào)用shell來(lái)執(zhí)行命令。因此,`exec`更加高效,因?yàn)樗苊饬藙?chuàng)建新的進(jìn)程和shell的開銷。另外,`exec`通常用于在當(dāng)前進(jìn)程中執(zhí)行其他可執(zhí)行程序,而`system`則更適用于執(zhí)行shell命令和腳本。exec是一系列函數(shù)接口的總稱,其實(shí)分為多個(gè)函數(shù)接口版本。
exec族函數(shù):
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是兩個(gè)不同的命令,用于執(zhí)行外部程序。
exec是一個(gè)系統(tǒng)調(diào)用,它可以用來(lái)執(zhí)行一個(gè)新的程序,并替換當(dāng)前進(jìn)程的內(nèi)容。它需要提供一個(gè)可執(zhí)行文件的路徑以及命令行參數(shù),然后它會(huì)將當(dāng)前進(jìn)程替換為指定的程序。execvp命令是一個(gè)低級(jí)別的命令,它可以更好地控制執(zhí)行的過(guò)程,但是它不會(huì)創(chuàng)建新的進(jìn)程。
system是一個(gè)庫(kù)函數(shù),它可以用來(lái)執(zhí)行一個(gè)命令。它接收一個(gè)字符串參數(shù),該參數(shù)是要執(zhí)行的命令,然后它會(huì)創(chuàng)建一個(gè)新的進(jìn)程來(lái)執(zhí)行該命令。system命令是一個(gè)高級(jí)別的命令,它更簡(jiǎn)單易用,但是它的控制能力較弱。?
選擇使用exec還是system取決于你的需求。如果你需要更細(xì)粒度的控制可以使用exec。例如如果你需要替換當(dāng)前進(jìn)程的內(nèi)容,或者需要在子進(jìn)程中執(zhí)行一些特定的操作,那么exec可能更適合。另一方面,如果你只是簡(jiǎn)單地執(zhí)行一個(gè)命令,并希望獲得執(zhí)行結(jié)果,那么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[]);
要執(zhí)行一個(gè)shell腳本,可以將shell解釋器的路徑作為第一個(gè)參數(shù),將腳本文件的路徑作為第二個(gè)參數(shù),并將其他參數(shù)作為字符串?dāng)?shù)組傳遞。
下面是一個(gè)示例,演示如何使用`execvp`命令執(zhí)行一個(gè)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`是要執(zhí)行的shell腳本的路徑。`/bin/sh`是shell解釋器的路徑。`NULL`表示參數(shù)數(shù)組的結(jié)束。
請(qǐng)注意,`execvp`命令執(zhí)行成功后,當(dāng)前進(jìn)程將被替換為新的程序,因此后續(xù)代碼不會(huì)被執(zhí)行。如果`execvp`命令執(zhí)行失敗,它將返回-1,并且可以使用`perror`函數(shù)打印錯(cuò)誤信息。
確保在執(zhí)行`execvp`命令之前,腳本文件具有執(zhí)行權(quán)限??梢允褂胉chmod`命令為腳本文件添加執(zhí)行權(quán)限。
`execvp`命令執(zhí)行成功后的當(dāng)前進(jìn)程將被替換為新的程序,后續(xù)代碼不會(huì)被執(zhí)行。如果想要在`execvp`命令執(zhí)行后繼續(xù)執(zhí)行代碼,可以使用`fork`函數(shù)創(chuàng)建一個(gè)子進(jìn)程,在子進(jìn)程中調(diào)用`execvp`命令,而父進(jìn)程則可以繼續(xù)執(zhí)行后續(xù)代碼。
下面是一個(gè)示例代碼:
#include <stdio.h>
#include <unistd.h>
int main() {
? ? pid_t pid = fork();
? ? if (pid == 0) {
? ? ? ? // 子進(jìn)程中執(zhí)行新的程序
? ? ? ? char *args[] = {"ls", "-l", NULL};
? ? ? ? execvp("ls", args);
? ? } else if (pid > 0) {
? ? ? ? // 父進(jìn)程中繼續(xù)執(zhí)行后續(xù)代碼
? ? ? ? printf("This is the parent process.\n");
? ? ? ? // 可以添加其他代碼
? ? } else {
? ? ? ? // fork失敗
? ? ? ? printf("Fork failed.\n");
? ? ? ? return 1;
? ? }
? ? return 0;
}
在上述代碼中,子進(jìn)程中調(diào)用了`execvp`命令來(lái)執(zhí)行`ls -l`命令,而父進(jìn)程則繼續(xù)執(zhí)行后續(xù)代碼。
如果你想在應(yīng)用程序中滿足條件時(shí)調(diào)用其他應(yīng)用程序,可以考慮使用fork和execvp的組合。使用fork創(chuàng)建一個(gè)子進(jìn)程,在子進(jìn)程中使用execvp執(zhí)行其他應(yīng)用程序,這樣可以避免替換當(dāng)前進(jìn)程,同時(shí)在父進(jìn)程中可以繼續(xù)執(zhí)行后續(xù)代碼。
system與execl的區(qū)別
system會(huì)新起一個(gè)子進(jìn)程來(lái)調(diào)用要執(zhí)行的命令。而exec只是用另一個(gè)新程序替換了當(dāng)前進(jìn)程的正文、數(shù)據(jù)、堆和棧段。
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); //子進(jìn)程正常執(zhí)行則不會(huì)執(zhí)行此語(yǔ)句
}else{
while(waitpid(pid, &status, 0) < 0){
if(errno != EINTER){
status = -1;
break;
}
}
}
return status;
}
正確處理?execvp?函數(shù)調(diào)用錯(cuò)誤方案和相應(yīng)的輸出消息
需要注意的是,exec
?系列函數(shù)只有在發(fā)生錯(cuò)誤時(shí)才會(huì)返回,所以要實(shí)現(xiàn)錯(cuò)誤檢查例程,并根據(jù)需要處理相應(yīng)的代碼路徑。
其中?execvp
?在失敗時(shí)返回?-1
,而且它還會(huì)設(shè)置?errno
?變量。不過(guò)要注意,errno
?應(yīng)該在函數(shù)調(diào)用前明確設(shè)置為 0,只有在給定的調(diào)用返回后才檢查該值。execvp
?函數(shù)可以接受沒(méi)有斜線的文件名,這意味著文件是在?PATH
?環(huán)境變量指定的目錄中搜索的。
#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);
}
假設(shè)用戶需要?jiǎng)?chuàng)建一個(gè)新的進(jìn)程,并執(zhí)行給定的程序代碼,那么在這種情況下我們可以利用?fork
?函數(shù)調(diào)用與?execvp
?相結(jié)合。在這種情況下,我們可以利用?fork
?函數(shù)調(diào)用與?execvp
?相結(jié)合。fork
?復(fù)制調(diào)用的進(jìn)程,并創(chuàng)建一個(gè)新的進(jìn)程,稱為-子進(jìn)程。在下面的例子中,我們實(shí)現(xiàn)了一個(gè)自定義函數(shù)包裝器來(lái)創(chuàng)建一個(gè)新的進(jìn)程并加載/執(zhí)行給定的程序代碼。注意,一旦創(chuàng)建了子進(jìn)程,它就會(huì)執(zhí)行不同的代碼,而父進(jìn)程則會(huì)等待,直到子進(jìn)程退出。
#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的區(qū)別_青椒*^_^*鳳爪爪的博客-CSDN博客
exec和system函數(shù)_execl system_Lawrence_121的博客-CSDN博客
Linux -- system、.(source)、exec的區(qū)別_青椒*^_^*鳳爪爪的博客-CSDN博客
exec族函數(shù)、system()函數(shù)和popen函數(shù)_exec函數(shù) system_基爾霍夫原來(lái)是碼農(nóng)的博客-CSDN博客?https://www.cnblogs.com/armsom/articles/17523386.html文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-615096.html
Linux下對(duì)GPIO的操作控制(基于GPIO子系統(tǒng))_linux 通過(guò)按鈕控制gpio de_金城孤客的博客-CSDN博客?Linux系統(tǒng)應(yīng)用層GPIO控制_echo 268 > export增加gpio268_技術(shù)の宅的博客-CSDN博客文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-615096.html
到了這里,關(guān)于linux的exec和system函數(shù)介紹及選擇的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!