我想在C代碼中執行另一個程序。 例如,我想執行一個命令如何在Linux中使用參數在C代碼中執行外部程序?
./foo 1 2 3
foo
是存在於同一文件夾中的程序,並且是1 2 3
參數。 foo
程序創建一個文件,將在我的代碼中使用。
我該怎麼做?
我想在C代碼中執行另一個程序。 例如,我想執行一個命令如何在Linux中使用參數在C代碼中執行外部程序?
./foo 1 2 3
foo
是存在於同一文件夾中的程序,並且是1 2 3
參數。 foo
程序創建一個文件,將在我的代碼中使用。
我該怎麼做?
使用system()
:
int status = system("./foo 1 2 3");
system()
將等待FOO完成執行,然後返回,你可以用它來檢查例如狀態變量退出碼。 man 2 wait
你的linux系統會列出你可以用它來檢查狀態的不同的宏上,最有趣的是WIFEXITED
和WEXITSTATUS
另外,如果你需要閱讀Foo的輸出到標準輸出,使用popen()
。
system()聲明在哪裏? –
stdlib.h,在另一個答案中找到。 –
請參閱https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132以及本作者發佈的替代答案。 –
在C
#include <stdlib.h>
system("./foo 1 2 3");
在C++
#include <cstdlib>
std::system("./foo 1 2 3");
然後,打開並讀取該文件如常。
這個怎麼樣:
char* cmd = "./foo 1 2 3";
system(cmd);
將字符串文字賦值給char *時,它在C++中被棄用,在C中變成壞主意。 –
我的意思是:它是有效的,而不僅僅是「while」。 :) –
這裏是延伸到可變ARGS當你沒有硬編碼的ARGS(雖然還是在技術上很難在這個例子中編碼的方式,但應該很容易弄清楚如何延長...):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int argcount = 3;
const char* args[] = {"1", "2", "3"};
const char* binary_name = "mybinaryname";
char myoutput_array[5000];
sprintf(myoutput_array, "%s", binary_name);
for(int i = 0; i < argcount; ++i)
{
strcat(myoutput_array, " ");
strcat(myoutput_array, args[i]);
}
system(myoutput_array);
您可以使用fork()
和system()
讓你的程序不必等到system()
回報。
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[]){
int status;
// By calling fork(), a child process will be created as a exact duplicate of the calling process.
// Search for fork() (maybe "man fork" on Linux) for more information.
if(fork() == 0){
// Child process will return 0 from fork()
printf("I'm the child process.\n");
status = system("my_app");
exit(0);
}else{
// Parent process will return a non-zero value from fork()
printf("I'm the parent.\n");
}
printf("This is my main program and it will continue running and doing anything i want to...\n");
return 0;
}
從子進程中使用execl或execv會更有效率,因爲它不會使用shell,它不會分叉新線程,並且在您調用system之後即將退出。另外,如果你不叫wait(),這個過程將會變成殭屍。 – Billy
system
函數調用shell來運行該命令。雖然這很方便,但它已經衆所周知security implications。如果您可以完全指定要執行的程序或腳本的路徑,並且您可以承受失去的平臺獨立性,則可以使用execve
封裝器,如下面的exec_prog
函數所示,以更安全地執行您的程序。
這裏是你如何在調用者指定的參數:
const char *my_argv[64] = {"/foo/bar/baz" , "-foo" , "-bar" , NULL};
然後調用exec_prog
功能是這樣的:
int rc = exec_prog(my_argv);
這裏的exec_prog
功能:
static int exec_prog(const char **argv)
{
pid_t my_pid;
int status, timeout /* unused ifdef WAIT_FOR_COMPLETION */;
if (0 == (my_pid = fork())) {
if (-1 == execve(argv[0], (char **)argv , NULL)) {
perror("child process execve failed [%m]");
return -1;
}
}
#ifdef WAIT_FOR_COMPLETION
timeout = 1000;
while (0 == waitpid(my_pid , &status , WNOHANG)) {
if (--timeout < 0) {
perror("timeout");
return -1;
}
sleep(1);
}
printf("%s WEXITSTATUS %d WIFEXITED %d [status %d]\n",
argv[0], WEXITSTATUS(status), WIFEXITED(status), status);
if (1 != WIFEXITED(status) || 0 != WEXITSTATUS(status)) {
perror("%s failed, halt system");
return -1;
}
#endif
return 0;
}
記住包括:
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
參見related SE post用於需要經由文件描述符如stdin
和stdout
執行的程序的通信狀況。
所以上面的代碼不使用shell來執行命令? – user3769778
#include <unistd.h>
int main() {
if (fork() == 0) {
execl("foo", "foo", "1", "2", "3", 0);
# We woundn't still be here if execl() was successful, so we exit with a non-zero value.
return -1;
}
return 0;
}
這個問題爲什麼要求C代碼,並用C++標記? – Johan