2017-05-20 4 views
0

私はこのファイルを作成し、それにスクリプトを書いてからexecを使って実行しようとしています*Cでシェルスクリプトを実行する方法は?

これまでのところ、ファイルを作成してコードを書きましたが、execlは、スクリプトを実行しないでください

int main(int argc, char * argv[]){ 
    char str[] = "#!/bin/bash \n echo 'Hello World!'"; 
    FILE *fp = fopen("script.sh", "w+"); 
    fwrite(str , 1 , sizeof(str) , fp); 
    fclose(fp); 
    execl ("/usr/bin/chmod", "chmod", "+x", "script.sh", (char *)0); 
    execl ("/export/home/redpal/lab4", "script.sh", (char *)0); 
    return 0; 
} 

私は各execlを子プロセスに入れるべきですか?

+2

かもしれないそこに唯一の答えが、私はシェルスクリプトを実行した方法で、シェルスクリプトは、独自のプロセスIDを必要とするので、私は 'にfork'使用子プロセスを作成し、親プロセスが子プロセスの完了を待つための 'waitpid'を作成します。そして、if/else型のステートメント内の子プロセスブロック文の中で、私は 'execve'を使ってスクリプトを実行しました。 –

+2

'execl("/bin/sh "、" sh "、" -c "、chr、NULL);'。ディスクに 'script.sh'を書いたり、そのファイルのパーミッションをfutzしたりする必要はありません。 (もちろん、これは**成功する 'exec'-family呼び出しのように、あなたのプログラムを終了/終了させます)。 –

+1

なぜシェルスクリプトを生成し、なぜそれを実行したいのですか?あなたの実際のプログラムは何を意図していますか? –

答えて

3

(すべてexec(3)機能とexecve(2)システムコールのように)execl機能は成功に戻りません。それは失敗時にのみ戻る。

だからあなたの最初の呼び出し:

execl ("/usr/bin/chmod", "chmod", "+x", "script.sh", (char *)0); 

が成功する可能性が非常に高いです。その後、現在のプログラムはなくなり、process/usr/bin/chmodプログラムを実行しています。そのプログラムが終了すると(数ミリ秒で)、プロセスが終了します(そして、起動したシェルは新しいプロンプトを出します)。

/usr/bin/chmodプログラムを使用する代わりに、chmod(2)システムコールの使用を検討する必要があります。

残りのプログラムも間違っています。生成されたスクリプトをexecにすることもできます(ただし、パス全体を指定する必要があります)。

fork(2)execve(2)waitpid(2)およびフレンドシステムコールを使用してプロセスを実行する方法を理解する必要があります。その方法を説明することはできません(長すぎます)。Advanced Linux Programming本のいくつかの章を読んでください(自由にダウンロードできます)。

おそらく、あなたがあなたの本当のプログラムにLuaまたはGuileのようなインタプリタを埋め込むことを検討すべきである(そう、あなたの質問には、いくつかのXY problemのように見える)

そして、あなたはただおそらく使用して....いくつかのコマンドを実行するsystem(3)またはpopen(3)を使用する場合がありますFILE* cmd = popen("/bin/sh", "w");のようなものかもしれません....そして、シェルコマンドをcmdに書きます。pclose(cmd)

+0

待って、シンプルにして、 'system()'を使うのはなぜですか? – Blacksilver

2

潜在的に失敗したコマンドのたびにエラーをチェックしてください。 sizeof(array)-1バイトをファイルに書き込むか、終了するゼロも書き込む必要があります。

exec* syscallsはプロセスイメージを置き換えます。成功した場合、プログラムは実行したばかりのバイナリに置き換えられます。結果的に、子プロセスでexecを実行するか、exec*システムコールがプログラムで最後に行う必要があります。

あなたの場合、chmodの実行は完全に回避できます。 chmodのシステムコールを直接発行することもできますし、ファイルを作成してバットの権限を正しく設定することもできます。

私はそうのようにそれをしたい:

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

int main(int argc, char * argv[]) 
{ 
    unlink("script.sh"); //unchecked -- let it fail if the file's not there 
    int fd; 
    if(0>(fd = open("script.sh", O_CREAT|O_WRONLY, 0777))) 
     { perror("Couldn't create 'script.sh'"); return EXIT_FAILURE; } 
    int nr; 
    static char const str[] = "#!/bin/bash \n echo 'Hello World!'"; 
    size_t to_write = sizeof str - 1; 
    if(to_write != (nr=write(fd, str, sizeof str - 1)) || 0>close(fd) ) 
     { perror("Couldn't write contents"); return EXIT_FAILURE; } 
    //writes to the filesystem on linux aren't ever partial unless there's a filesystem error 
    //otherwise you need to account for partial write (which fwrite does for you) 

    execl ("./script.sh", "script.sh", (char *)0); 
    perror("Couldn't exec './script.sh'"); 
    return EXIT_FAILURE; 
} 
関連する問題