2013-09-03 45 views
6

Tôi đang cố gắng mã hóa một trình bao. Nhưng vỏ của tôi không thực hiện lệnh - ls -l | ít hơn. Tôi đang sử dụng execvp. mã được đưa ra dưới đây.linux execvp; ls không thể truy cập |, Không có tập tin hoặc thư mục như vậy

#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 

int main(){ 
    int pid, status, num, len; 
    char str[1000], cwd[100]; 
    char* word[100]; 

    getcwd(cwd, sizeof(cwd)); 

    while(1){ 
     chdir(cwd); 

     printf("%s > ", cwd); 

     gets(str); 

     pid=vfork(); 

     if(pid == 0){ 
      num = 0; 
      word[num] = strtok (str, " "); 

      while (word[num] != NULL) { 
       word[num] = strdup (word[num]); 
       len = strlen (word[num]); 
       if (strlen (word[num]) > 0) 
        if (word[num][len-1] == '\n') 
         word[num][len-1] = '\0'; 
       word[++num] = strtok (NULL, " "); 
      } 

      if(strcmp(word[0], "cd") == 0){ 
       chdir(word[1]); 
       getcwd(cwd, sizeof(cwd)); 
      } 
      else{ 
       execvp(word[0],word); 
      } 

      exit(0); 
     } 
     else{ 
      wait(&status); 
     } 
    } 

    return 0; 
} 
+4

'|' là mã thông báo có liên quan đến trình bao, theo như tôi biết. Làm việc đó bên ngoài một hệ vỏ không thực sự hoạt động vì vỏ của nó đọc '|' và làm cho phép thuật xảy ra. Nếu không có vỏ để làm cho đường ống ma thuật xảy ra ... nó không hoạt động. – Cornstalks

+0

SO có cách nào khác để tôi có thể chạy không? Tôi có thể bằng cách nào đó chuỗi và với sức mạnh vũ phu làm cho nó hoạt động –

+3

@ Cornstalks nói thật sự. 'execvp' được viết để thực hiện một lệnh với một tập các tham số (nếu cần). Bạn có thể thử 'system' để gọi một dòng lệnh shell full-blown. – lurker

Trả lời

9

thực ra là dòng lệnh trình bao gồm hai quy trình được kết nối bằng một đường ống. Cuộc gọi execvp() chỉ có thể sinh ra một quy trình duy nhất.

Nếu bạn muốn thực hiện điều này từ chương trình của mình, bạn phải gọi trình bao một cách rõ ràng - bằng cách sử dụng lệnh gọi system() hoặc bằng cách thay đổi dòng lệnh thành sh -c 'ls -l | less'. mảng word của bạn sẽ giống như thế này:

word[0] = "sh" 
word[1] = "-c" 
word[2] = "ls -l | less" 
word[3] = NULL 

[EDIT] Ngoài ra, bạn có thể làm những gì vỏ được làm trong nội bộ: đẻ trứng hai quá trình và kết nối chúng với một ống. Điều này sẽ liên quan đến việc sử dụng các cuộc gọi fork(), pipe(), dup2()execve(). Tuy nhiên, việc gọi shell là ít công việc hơn, và vì dù sao less vẫn là một chương trình tương tác, bạn không cần phải lo lắng về hiệu năng nhiều như vậy: bất cứ thứ gì mất ít hơn 100 ms được coi là tức thời.

+0

cảm ơn rất nhiều sự giúp đỡ –

+0

+1 Chỉ vì lạm dụng 'sh' như lệnh execvp. Không thấy điều đó đến = P. – WhozCraig

+2

@WhozCraig: GNU libc 'system()' nội bộ thực hiện chính xác điều tương tự dưới mui xe. Xem: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/system.c;hb=HEAD –

Các vấn đề liên quan