5

execvp() を使用して特定のコマンドを実行する小さなプログラムを実装しています。リダイレクトを使用しない場合は正常に動作しますが、次のようなコマンドを実行すると:

cat file1.txt > redirected.txt

cat は次のエラー メッセージを出力し、失敗します。

cat: >: No such file or directory
cat: redirected.txt: No such file or directory

私はいくつか掘り下げましたが、シェルで実行されないため、おそらく execvp() はリダイレクトを許可されていないのではないかと考え始めています。この制限を回避するには、リダイレクトが発生するタイミングを手動で選択し、fork/exec コードでパイプを使用する必要があるということですか? execvp() を使用するよりも良い方法はありますか?

ありがとう!

4

3 に答える 3

8

「特定のコマンドを実行する小さなプログラム」は、本質的にシェルです。シェルを作成しているので、必要な構文でリダイレクトを実装するのはあなたの仕事です。リダイレクト演算子はカーネルの>機能ではなく、シェルの機能です。

スタイルのリダイレクションを実装shするには、コマンドを解析し、リダイレクション オペレータを見つけ、ファイルを開いて入出力記述子に割り当てる必要があります。これは、を呼び出すexecvpに行う必要があります。dup2システムコールを調べます。

于 2012-12-09T03:19:23.840 に答える
6

そのような構文を本当に使用したい場合は、system()を使用できます。お気づきのように、リダイレクトやワイルドカードの拡張など、さまざまなことがUnixライクなシステムのシェルによって処理されます。

フォークでそれを行う方法は次のようになります。

int kidpid;
int fd = open("redirected.txt", O_WRONLY|O_TRUNC|O_CREAT, 0644);
if (fd < 0) { perror("open"); abort(); }
switch (kidpid = fork()) {
  case -1: perror("fork"); abort();
  case 0:
    if (dup2(fd, 1) < 0) { perror("dup2"); abort(); }
    close(fd);
    execvp(cmd, args); perror("execvp"); abort();
  default:
    close(fd);
    /* do whatever the parent wants to do. */
}
于 2012-12-09T03:20:48.407 に答える
3

最も簡単な方法は次のとおりです。

execlp( "/bin/sh", "/bin/sh", "-c", "cat file1.txt > redirected.txt", (char *)NULL );

で同じことができますexecvp

于 2012-12-09T03:32:53.663 に答える