2016-11-24 5 views
0

私は、execを使ってlsgrepシステムコールを呼び出すプログラムを作ろうとしています。具体的には、パターンを実行するファイルの数を数えるためにls > tmp; grep ­-c pattern < tmpを実行しなければなりません。ご覧のとおり、lsの内容をtmpファイルに保存してから、grepを使ってファイルを数えたいと思っています。execlを使ってgrepの値を取得

pattern = txtを告白しましょう。

char *a = "ls > tmp"; 
char *b = " -c "; 
char *fin = " < tmp"; 
char *comanda; 
if((comanda = malloc(strlen(pattern)+strlen(pattern)+1)) != NULL){ 
    comanda[0] = '\0'; // ensures the memory is an empty string 
    strcat(comanda,b); 
    strcat(comanda, pattern); 
    strcat(comanda,fin); 
} else { 
    return -1; 
} 

ret = execl("/bin/sh","sh","-c",a,NULL); 
ret = execl("/bin/sh","sh","-c",comanda, NULL); 

をしかし、それは私に次のエラーを示しています:私は、次のコードのようなものをしようとしているls: cannot access > tmp: No such file or directoryを。だから、私はgrepの値を取得する方法を知らないので、execl関数は値を返さないので、grepの値はどのようにして得られますか?

+0

'fork()'で作成された子プロセスで 'execl'を実行する必要があります。 'execl()'は現在のプロセスを実行しているプログラムに置き換えます。プログラムをロードしようとしてエラーが発生した場合にのみ返します。 – Barmar

+0

これは私の実際のポイントです。子プロセスでは 'execl'を使用しますが、とにかく同じエラーが表示されます:' ls:アクセスできません> tmp:そのようなファイルやディレクトリはありません ' –

+0

私は変更しない限りエラーを再現できません'char * a =" ls '> tmp' ";' – Barmar

答えて

1

コマンドの出力を取得するには、パイプを使用する必要があります。あなただけ行うことができConnecting n commands with pipes in a shell?

ls | grep -c pattern 

あなたはちょうどあなたがfind

find your_path/ -name "*pattern*" | wc -l 
を使用する場合がありますファイル名に特定のパターンを持つファイルを取得したい場合は

はを見てください

execlの出力を得るにはGrabbing output from execをご覧ください

ここ

あなたはドンので、あなたは」、comandaのためのスペースの正確な量を割り当てていない

#include <unistd.h> 
#include <string.h> 

int main() 
{ 
    int fd[2]; 
    pipe(fd); 

    if (fork() == 0) 
    { 
     close(fd[0]); 

     dup2(fd[1], 1); 
     dup2(fd[1], 2); 
     close(fd[1]); 

     execl("/bin/sh", "sh", "-c", "find your_path -name '*pattern*' | wc -l", (char *)NULL); 
    } 
    else 
    { 
     char buffer[1024] = {0}; 

     close(fd[1]); 

     while (read(fd[0], buffer, sizeof(buffer)) != 0) 
     { 
     write(1, buffer, strlen(buffer)); 
     memset (buffer, 0, sizeof(buffer)); 
     } 
    } 
    return 0; 
} 
+0

私に例を教えてください。 –

+0

問題は 'ls> tmpを使わなければならないということです。 grep -cパターンを要求します。だから私はパイプを見ます。 –

+0

'execl'を使う必要がなければ、' system'を使ってリダイレクトすることができます。さもなければ、 'fork'と' dup2'で遊んでください。 –

0

あなたは:)

execl("/bin/sh", "sh", "-c", "ls > tmp; grep -c 'pattern' < tmp", (char *)NULL);を)好きでEXECLの第四引数を置き換える、例です。すべての変数のサイズを正しく追加しないでください。したがって、サイズが小さすぎる場合は、strcatをすべて実行したときに配列の範囲外に書き込むため、未定義の動作が発生します。

テンポラリファイルは必要ありません。lsからgrepにパイプするだけで済みます。また、特殊文字が含まれている場合は、パターンの周りに引用符を追加しました。

#include <string.h> 
#include <unistd.h> 
#include <stdlib.h> 

int main() { 
    char *a = "ls | grep -c '"; 
    char *fin = "'"; 
    char *pattern = "foo"; 
    char *comanda; 
    if((comanda = malloc(strlen(a) + strlen(pattern) + strlen(fin) +1)) != NULL){ 
     strcpy(comanda,a); 
     strcat(comanda,pattern); 
     strcat(comanda,fin); 
    } else { 
     return -1; 
    } 
    int ret = execl("/bin/sh","sh","-c", comanda, (char*)NULL); 
    perror("execl"); // Can only get here if there's an error 
} 
関連する問題