2016-04-28 18 views
2

通常のLinuxシェルとは多少異なるシェルプログラムを作成しました。私のプログラムは、入力OR出力を正しくリダイレ​​クトできますが、同時に両方をリダイレクトすることはできません。これまでのオンラインのソリューションは、私にとって役に立たなかった。入力と出力をシェルにリダイレクトするコード

しかし

" echo hi kenny > kenny.txt " works 

" cat in.txt | less "  works 

、(in.txtはランダムなアルファベットのファイルであると仮定)

" sort -u <in.txt> out.txt " does not work for both, only for the input(<). 

次のように私のコードは、おおよそ次のとおりです。

int main(int argc, char* argv[]){ 

readLine(); 

if (lineHasSpecialSymbols()) { 
    if(hasInput()){ 
     inRedirection(); 
    }else 
     outRedirection(); 
} 

} 

はのは、すべてが必要なのthatsを想定してみましょう。いいえパイプ等

のreadLine()

lineHasSpecialSymbols([]端末から行を読み出し、引数に保存します)は、「<」または「>」とリターンの最初のインスタンスを検出しません。以下のために、

void extractCommand(char* symbol) { 
int i; 
int count = 0; 
for (i = 0; args[i] != NULL; i++) 
    if (!strcmp(args[i], symbol)) { 
    args[i] = NULL; 
    while (args[i+1] != NULL) { 
      args2[count] = args[i+1]; 
      args[i+1] = NULL; 
      i++; 
      count++; 
    } 
    } 
} 

申し訳ありません:

void inRedirection(void) { 
extractCommand("<"); 
int fd; 
if ((pid = fork()) == -1) { 
    perror("fork"); 
    exit(1); 
} 
if (pid == 0) { 
    close(0); 
    //open the file args2[0] and use it as standard input 
    fd = open(args2[0], O_RDWR); 
    execvp(args[0], args); 
    perror("execv"); 
    exit(1); 
} 
if (pid != 0) { 
    wait(NULL); 
    printf("Done "); 
    printf(args[0]); 
    printf(".\n"); 
} 
} 

outRedirection():最後に

void outRedirection(void) { 
extractCommand(">"); 
int fd; 
if ((pid = fork()) == -1) { 
    perror("fork"); 
    exit(1); 
} 
if (pid == 0) { 
    close(1); 
    fd = creat(args2[0], 0644); 
    execvp(args[0], args); 
    perror("execv"); 
    exit(1); 
} 
if (pid != 0) { 
    wait(NULL); 
    printf("Done "); 
    printf(args[0]); 
    printf(".\n"); 
} 
} 

、extractCommand()

はここinRedirectionは()どのように動作するかでトリッキーな部分です巨大なコード。ここで問題です:

のは、私は、コマンドを入力するとしましょう:

「ソート-u < in.txt> out.txtを」

コードは「<」を検出し、にコマンドを抽出2つの部分。

「sort -u < in.txt」のみで、残りは含まれません。私の質問は、意図的に動作するようにコードを変更する方法です。また、2つ以上のコマンドに対してこれを行うにはどうすればよいですか?例: "ls -l/home/user | sort -u | wc -l> in.txt"?

私は3番目のargs(args3)を作るようなアルゴリズムを考えましたが、2つ以上のコマンドの場合は衝突します。

+1

は、あなたの「outRedirection」機能ではフォークはありません。 (実際には、 "outRedirection"機能はありません!)。フォーク。次に、コマンドラインを解析します。 '>'シンボルが表示された場合は、dupという名前のファイルにstdoutします。解析を続けます。 '<'記号がある場合は、dup stdinとなります。 –

+1

パーサを一般的に適切に書く方法とインタプリタを具体的に書く方法をまず知りたいでしょう。シンプルな捜索によって発見されるべき多くの情報がある。 "コンパイラの構築"(多くの関連するもの)。 – Olaf

+0

そしてオラフが言ったことの上に、 'man dup2'を読んでください。しかし、スクリプトを適切に解析することがまず必要です(例えば、 'GNU bison'を確認するなど)。 – Dummy00001

答えて

1

あなたの方法を変更することをお勧めします。

int outRedirection(void) { 
    int i; 
    int j; 
    for(i = 0; args[i] != NULL; i++) { 
    // Look for the > 
    if(args[i][0] == '>') { 
     args[i] = NULL; 
     // Get the filename 
     if(args[i+1] != NULL) { 
    output_filename[0] = args[i+1]; 
     } else { 
    return -1; 
     } 
      //For- loop to make input AND output functional 
      for(j = i; args[j-1] != NULL; j++) { 
         args[j] = args[j+2]; 
      } 
     return 1; 
    } 
    } 
    return 0; 
} 

入力のために同じことを行い、その後、そのように実行します。

void IOcommand(void){ 
    if ((pid = fork())== -1){ 
     perror("fork"); 
     exit(1); 
    }if (pid == 0){ 

    if (input == 1) 
     freopen(input_filename[0], "r", stdin); 

    if (output == 1) 
     freopen(output_filename[0], "w+", stdout); 

     execvp(args[0],args); 
     exit(-1); 
} 
if (pid != 0){ 
    wait(NULL); 
    printf("Done "); 
    printf(args[0]); 
    printf(".\n"); 
} 
} 
関連する問題