質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.62%

  • C

    3573questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

リダイレクトを実装したい

解決済

回答 3

投稿

  • 評価
  • クリップ 2
  • VIEW 482

HO_Pollyanna

score 1

Cで簡単なシェルを実装したいのですが、リダイレクトが実現できません

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>

#define MAX_LINE_IN 1000
#define MAX_ARGS 30
#define BUF_SIZE 256

int nol(const char *s){
  int i;
  FILE *f=fopen(s,"r");
  char buf[BUF_SIZE];

  if(!f){
    printf("ファイル読み込みエラー\n");
    exit(0);}

  i=0;

  while((fgets(buf,BUF_SIZE,f)) != NULL){
    i++;
  }
  if(fclose(f))exit(0);

  return i;
}
void redirect(const char *args[],int a){//a:<のある位置
  int fd,i;

  args[a]=NULL;
  fd=open(args[a+1],O_WRONLY | O_CREAT,0664);//rwrwrのこと
  close(STDOUT_FILENO);
  dup(fd);
  execvp(args[0],args);

}

 int main(int argc, char *argv[]){
   int pid, status;
   char line_in[MAX_LINE_IN];
   char *args[MAX_ARGS];
   int nargs;
   int i;

   ////tokenize
   for(;;){
     printf("> ");
     if(fgets(line_in,MAX_LINE_IN,stdin)==NULL)exit(0);
     line_in[strlen(line_in)-1]='\0';

     char *token = strtok(line_in," ");
     nargs=0;
     args[nargs++]=token;
     while(token!=NULL){
       token = strtok(NULL," ");
       if(token!=NULL){
     args[nargs++]=token;
       }
     }
     args[nargs] = NULL;

     if(args[0]!=NULL){
       if(!strcmp(args[0],"exit"))
     {
       exit(1);
       continue;
     }




       if(fork()==0){

     if(!strcmp(args[0],"nol"))
       {
         printf("%d\n",nol(args[1]));
         exit(1);
       }
     for(i=0;i<nargs;i++)
       {
         if(!strcmp(args[i],">"))
           {
         redirect(args[0],i);
         exit(1);
           }
       }
     execvp(args[0],args);
     printf("command not found\n");
     exit(1);
       }

       else{
     wait(&status);
       }  

     } 

   }  
   return 0;
 }

コンパイルすると以下の警告がでます
shell.c: In function ‘redirect’:
shell.c:38:18: warning: passing argument 2 of ‘execvp’ from incompatible pointer type [-Wincompatible-pointer-types]
execvp(args[0],args);
^
In file included from shell.c:3:0:
/usr/include/unistd.h:581:12: note: expected ‘char * const*’ but argument is of type ‘const char ’ extern int execvp (const char *file, char *const argv[ ^ shell.c: In function ‘main’: shell.c:87:13: warning: passing argument 1 of ‘redirect’ from incompatible pointer type [-Wincompatible-pointer-types] redirect(args[0],i); ^ shell.c:31:6: note: expected ‘const char ’ but argument is of type ‘char *’
void redirect(const char *args[],int a){//a:<のある位�

実行後、echoコマンドで出力先を任意のファイルにリダイレクトしたいのですが新しいファイルが生成されません。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • y_waiwai

    2018/05/04 17:28

    そのコードで具体的にどういう動作をさせたいんでしょうか?

    キャンセル

  • HO_Pollyanna

    2018/05/04 17:31

    echo (任意の文字列) > ___.txt   と入力したときにテキストファイルに任意の文字列を出力させたいと考えています

    キャンセル

  • y_waiwai

    2018/05/04 17:36

    で、今のコードで、echo (任意の文字列) は実行できるんでしょうか

    キャンセル

  • HO_Pollyanna

    2018/05/04 17:37

    実行できません

    キャンセル

回答 3

checkベストアンサー

0

void redirect(const char *args[], int a)

こちらの最初の引数は、文字列へのポインタ(ポインタのポインタ)
それに対し、呼び出し側は、

redirect(args[0], i);

char *args[MAX_ARGS];

なので、args[0] は、最初の文字列です。
従って、示すものが違うと思われます。
単に、
redirect(args, i);
で良いかなと、思いますがどうでしょう。

const の有無に関する警告は、それだけでは、無視しても動く事が多い(だから、警告)。その陰にもっと大きな問題がある可能性ですね。

ちょっと、Linuxまで動かして確認できないので、問題点の指摘まで。
(久々に、fork()システムコールを見た。どっかのコピペでやってませんか?)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/07 14:29

    本当にありがとうございました。解決できました。

    キャンセル

0

extern int execvp (const char *file, char *const argv[
なので*argv[]は書き換え可能で無ければいけません。

void redirect(char *const args[],int a)

にしましょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/04 22:38

    回答有り難う御座います
    該当の箇所を修正したのですが
    echo hello > hello.txt
    と入力してもhello.txtが現れません...

    コンパイル時の警告
    shell.c: In function ‘main’:
    shell.c:87:13: warning: passing argument 1 of ‘redirect’ from incompatible pointer type [-Wincompatible-pointer-types]
    redirect(args[0],i);
    ^
    shell.c:31:6: note: expected ‘char * const*’ but argument is of type ‘char *’
    void redirect(char *const args[],int a){//a:<のある位�
    ^

    キャンセル

0

真っすぐな回答でなくて申し訳ないのですが、system callの帰値を全部調べましょう。ドキュメントを読むという話ではなく、以下のようにコードを書くという意味です。

if((fd=open(...)) == -1 ) {
   // NULL になってしまった原因の分析
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/07 14:29

    回答有り難うございます。参考になります。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3573questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。