0

私はCで基本的なシェルを書いています。すべてのリダイレクト演算子が実装されていますが、「cd」をリダイレクトしようとすると、次の問題が発生します。

cd は、出力のリダイレクトなしで完全に機能しますが、

私がこのようなことをしようとしているとき:

cd inexistant_directory > output_file

出力ファイルは作成されません.bashでは、そのコマンドを実行するとstdoutがリダイレクトされます.以前に述べたように、外部コマンドを使用したリダイレクト演算子はうまく機能します.

cd コマンドに遭遇したとき、私は呼び出します

char*path = get_path(parameters);  //implemented by me, works on rest of the cases
int  ret =chdir(path);

子プロセスではなく、親(シェルプロセス自体)でこれを呼び出します

私は何を間違っていますか?

ありがとうございました、

PS : これを実行する OS は Ubuntu 12.10 ですが、コードは POSIX に準拠しています。

LE: 約 600 行になるため、コード全体を掲載することはできませんが、

ここに私の論理があります

if(internal_command) {
     //do quit, exit or cd
} else if (variable_assignemt){
     //do stuff
} else {
    // external command
    pid = fork();
    if(pid == -1) {
        //crash
    } else if (pid == 0) {
        do_redirects()
        call_external_cmd
     }
    default : 
        wait(pid, &status);

したがって、問題を解決するには、標準出力を親(シェルプロセス)にリダイレクトし、コマンドの実行後に復元する必要があると思います

4

1 に答える 1

0

親プロセス(シェル)でstdoutをリダイレクトしないことが、実際にcdの望ましくない動作の原因でした。私の解決策は次のとおりです。

   if(we_have_out_redirection == 1) {
       if(out != NULL) {

       char *outParrent = out;

           fflush(stdout);

       outBackup = dup(STDOUT_FILENO); //I save stdout for future restoration
       int fd = open(outParrent, O_WRONLY | O_CREAT | O_TRUNC, 0644); //open output file
       int rc;
           rc = dup2(fd, STDOUT_FILENO); //redirect stdout

    retval = chdir(out); //execute cd command

        //restore stdout
    close(fd); 
    fflush(stdout);
    rc = dup2(outBackup, 1);
    close(outBackup);
   }
}

親にリダイレクトするのを忘れていたことを指摘してくれた Jake223 に感謝します。

于 2013-03-27T19:51:59.297 に答える