2011-03-08 9 views
33

Cコード内で別のプログラムを実行したい。 例えば、私はlinuxで引数を指定してCコード内で外部プログラムを実行するにはどうすればよいですか?

./foo 1 2 3 

fooコマンドを実行するには、同じフォルダ内に存在するプログラムであり、1 2 3は引数です。 fooプログラムは、自分のコードで使用されるファイルを作成します。

どうすればよいですか?

+1

なぜこの質問はCコードを要求し、C++でタグ付けされていますか? – Johan

答えて

32

使用system()

int status = system("./foo 1 2 3"); 

system()あなたは、例えばをチェックするために使用できる状態変数を返した後、実行を完了するためにfooのを待ちます出口コード。 Linuxシステム上のman 2 waitは、あなたが状況を調査するために使用できるさまざまなマクロの一覧が表示されます、最も興味深いものはまたWIFEXITEDWEXITSTATUS

だろうあなたがstdoutに、fooの出力を読むために必要がある場合は、popen()を使用しています。その後

+1

system()はどこに宣言されていますか? –

+4

stdlib.h、別の答えにあります。 –

+2

https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132と、この著者が投稿した代替回答を参照してください。 –

4
C

#include <stdlib.h> 

system("./foo 1 2 3"); 
C++で

#include <cstdlib> 

std::system("./foo 1 2 3"); 

オープンし、いつものようにファイルを読み込みます。

1

方法については、このような:

char* cmd = "./foo 1 2 3"; 
system(cmd); 
+4

文字列リテラルを 'char *'に代入している間は、C++では非難され、Cでは悪い考えがあります。 –

+0

私はそれを意味しました。 :) –

1

ここでは、彼らはまだ技術的に難しいこの例では、コードされているが(引数がハードコーディングされていませんが、簡単にする必要がありますとき、可変引数に拡張する方法があります)...拡張する方法を見つけ出すために:あなたのプログラムがsystem()戻るまで待つ必要がないように、

#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); 
15

をあなたはfork()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; 
} 
+0

子プロセスからexeclまたはexecvを使うほうがはるかに効率的です。なぜなら、シェルを使用せず、新しいスレッドをforkしたり、システムコールした直後に終了したりするからです。また、wait()を呼び出さなければ、プロセスはゾンビになります。 – Billy

27

system関数は、コマンドを実行するシェルを呼び出します。これは便利であるが、それはよく知られているsecurity implicationsである。実行するプログラムまたはスクリプトへのパスを完全に指定でき、systemが提供するプラットフォームの独立性を失う可能性がある場合は、exec_prog関数のように、execveラッパーを使用してプログラムをより安全に実行できます。ここで

あなたは、呼び出し側で引数を指定する方法は次のとおりです。

const char *my_argv[64] = {"/foo/bar/baz" , "-foo" , "-bar" , NULL}; 

次に、このような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; 
} 

は覚えておいてください:

int rc = exec_prog(my_argv); 

ここexec_prog機能だが以下を含みます:

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <stdio.h> 

は、このようなstdinstdoutとしてファイルディスクリプタ経由で実行されるプログラムとの通信を必要とする状況にrelated SE postを参照してください。

+0

上記のコードはシェルを使用してコマンドを実行しませんか? – user3769778

2
#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; 
} 
関連する問題