8

改行で区切られたbashコマンドを含むテキストファイルを入力として受け入れ、テキストファイル内のすべてのコマンドを実行するプログラムShellcode.cを作成したいと思います。たとえば、テキストファイルには次が含まれます。

echo Hello World
mkdir goofy   
ls

私はこれを試しました(exec関数の1つで練習を始めるためだけに):

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

void main() {
    char *name[3];

    name[0] = "echo";
    name[1] = "Hello World";
    name[2] = NULL;
    execvp("/bin/sh", name);
}

その見返りに、

echo: Can't open Hello World

私は execvp 関数で立ち往生しています。どこで間違ったのでしょうか?

4

3 に答える 3

19

あなたはそれを間違っています。

ドキュメントで説明されているように、最初の配列インデックスはプログラムの名前です。

execv()、execvp()、およびexecvpe()関数は、新しいプログラムで使用可能な引数リストを表すnullで終了する文字列へのポインタの配列を提供します。慣例により、最初の引数は、実行されているファイルに関連付けられているファイル名を指す必要があります。ポインタの配列は、NULLポインタで終了する必要があります。

また、bashはそのような自由形式の引数を期待していません。次の-cオプションを使用して、コマンドを渡すことを通知する必要があります。

だから、あなたは必要です:

name[0] = "sh";
name[1] = "-c";
name[2] = "echo hello world";
name[3] = NULL;
于 2013-01-03T14:43:28.583 に答える
9

コマンドラインでスクリプトをbashに渡すには、オプション'-c'を追加し、スクリプト全体を単一の文字列として渡す必要があります。

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

void main() {
    char *name[] = {
        "/bin/bash",
        "-c",
        "echo 'Hello World'",
        NULL
    };
    execvp(name[0], name);
}
于 2013-01-03T14:44:04.597 に答える
8

ここでの多くの問題:exec()関数ファミリーは複数のプログラムを実行しません-これらの関数は単一のプログラムを実行し、メモリ内で現在実行中のプロセスを新しいプログラムに置き換えます。渡す文字列のnullポインターで終了する配列には、によって実行されるプログラムへexecvpのコマンドライン引数execvpが含まれているはずです。

複数のプログラムを実行したい場合は、各行をループしてプログラムを1つずつ実行する必要があります。ただし、現在実行中のプロセス(Cプログラム)がシェルを介して実行されたプロセスにすぐに置き換えられるため、使用できませんexecvp。つまり、Cプログラムの残りの部分は実行されません。子プロセスを実行できるように、fork()と組み合わせて使用​​する方法を学ぶ必要があります。execvp最初に呼び出しfork()て子プロセスを作成し、次に子プロセスから呼び出しますexecvp。 Fork + Execは、親プロセスから他のプロセスを起動するためのUNIX環境での一般的な戦略です。

于 2013-01-03T14:43:02.973 に答える