質問: NULL; if(strcmp(args[0], "exit")==0) break; if(fork()==0){ if(REDI!=0){ redirect(args, REDI); } execvp(args[0],args); printf("command not found\n"); exit(1); } else{ wait(&status); } } return 0; } ``` ### 試したこと 『これにリダイレクトします。』というところは>を実行した時に表示されていたので、redirectの関数の中には入っているようです。またその関数の中に入ったargs[REDI]の文字列もレダイレクトの対象とするテキストファイル名が入っていたので問題ないと思います。 このコンパイルに関してはエラーはありませんでした。 ``` 実行 > echo hello > text.txt ``` これを実行した時は text.txtのファイルに hello > text.txt という文字列が入りました。 ``` 実行 > cal > text.txt ``` とした時には cal: year `text.txt' not in range 1..9999 というエラーが出てtext.txtには何も入りませんでした。 ### 補足情報(FW/ツールのバージョンなど)
回答: redirect関数を呼び出すときの引数が不適切なのが原因です。 > > echo hello > text.txt > > > これを実行する際、echoへの引数は args[0] = "echo" args[1] = "hello" args[2] = NULL が期待ですがご質問のコードでは args[2] = ">" args[3] = "text.txt" args[4] = NULL と、リダイレクト指示がそのまま引数になってしまってます。これだとechoは args[1]~args[3]までの3つのパラメータを印字しようとしますし、calは意味不明なパラメーター ">" "text.txt"を受け取ってしまいますのでエラーを引き起こします。 とりあえず動くようにするためには以下の(A)を追加すればよいです。 ``` void redirect(char *args[], int REDI){ int fd; fd=open(args[REDI], O_WRONLY | O_CREAT, 0664); close(STDOUT_FILENO); dup(fd); // ">"とその次のリダイレクト先のファイル名を起動コマンドへ渡さないようにする args[REDI - 1] = NULL; //(A) execvp(args[0],args); } ```