2

unix ライクな xv6 OS のシェル プログラムで基本的なコマンド実行を実装しようとしています。私が編集しているシェル コードの一部は、ターミナルで使用されるコマンドを実行するために execvp コマンドを使用している runcmd 関数です。プログラムをコンパイルするとエラーは発生しませんが、コマンド ラインでコマンドを入力しようとしても何も起こりません。exec コマンドのman ページを読みましたが、これらの引数を exec() コマンドで渡す必要がある適切な方法や、どのバージョンの exec() をいつ使用するかについてはまだよくわかりません。 OSプログラミングにはまだ非常に慣れていません。

コマンドを実行するために追加する必要がある、ここで実装していないものは何ですか? 以下の runcmd 関数のコードがあります。

編集:

各コマンドのバイナリへのパスを含む exec ステートメントを追加しました。ただし、最初の exec コマンド (この場合は cd) のみが機能します。他のコマンドを使用すると、コマンド ラインはそれを CD のように実行します。複数のコマンドで動作させるにはどうすればよいですか?

struct cmd {
  int type;          //  ' ' (exec), | (pipe), '<' or '>' for redirection
};
struct
 execcmd {
  int type;              // ' '
  char *argv[MAXARGS];   // arguments to the command to be exec-ed
};

// Execute cmd.  Never returns.
void
runcmd(struct cmd *cmd)
{
  int p[2], r;
  struct execcmd *ecmd;
  struct pipecmd *pcmd;
  struct redircmd *rcmd;

  if(cmd == 0)
    exit(0);
  
  switch(cmd->type){
  default:
    fprintf(stderr, "unknown runcmd\n");
    exit(-1);

  case ' ':
    ecmd = (struct execcmd*)cmd;
    
    if(ecmd->argv[0] == 0)
      exit(0);
    //fprintf(stderr, "exec not implemented\n");
     execvp("/bin/cd" , ecmd->argv );
     execvp("/bin/grep" , ecmd->argv );
     execvp("/bin/echo" , ecmd->argv );
     execvp("/bin/cat" , ecmd->argv );
     execvp("/bin/ls" , ecmd->argv );
    break;

  case '>':
  case '<':
    rcmd = (struct redircmd*)cmd;
    //fprintf(stderr, "redir not implemented\n");
    execvp("/bin" , ecmd->argv );
    runcmd(rcmd->cmd);
    break;

  case '|':
    pcmd = (struct pipecmd*)cmd;
    fprintf(stderr, "pipe not implemented\n");
    int execl(const char *path, const char *arg, ...);
    break;
  }    
  exit(0);
}
4

2 に答える 2