2012-06-25 34 views
5

Trong chương trình này CLàm thế nào để chuyển hướng đầu ra của hệ thống() vào một tệp?

#include <stdio.h> 
#include <fcntl.h> 
int main() 
{ 
    int file = open("Result", O_CREAT|O_WRONLY, S_IRWXU); 

    dup2(stdout, file); 
    system("ls -l"); 

    return 0; 
} 

Tôi đang cố gắng để chuyển hướng đầu ra của system() vào một tập tin, cho rằng tôi đã sử dụng dup2 nhưng nó không được làm việc.

Có gì sai với mã này?
và, vui lòng cho tôi biết nếu có bất kỳ cách nào tốt hơn để thực hiện điều này? (không sử dụng > tại đầu cuối)

+3

Tại sao không chỉ cần gõ '>' chuyển hướng trong 'lệnh system'? –

+0

Sử dụng 'system (" ls -l> Result ");' hoặc tạo kết hợp 'fork()'/'exec *()' của riêng bạn. –

+1

Không sử dụng 'hệ thống'. Nó luôn luôn sai. Chạy quá trình con bạn mà không cần shell, hoặc sử dụng 'fork' và' execvp' hoặc 'posix_spawn'. –

Trả lời

4

stdout là con trỏ của luồng đầu ra tiêu chuẩn FILE *. dup2 hy vọng bộ mô tả tệp, bạn cũng đã làm sai trật tự các tham số. Sử dụng

dup2(file, 1); 

để thay thế.

Trên phần tốt hơn để làm điều này. Bằng cách này là xấu bởi vì bạn có thể muốn khôi phục lại đầu ra tiêu chuẩn của bạn sau khi hoàn thành cuộc gọi này system. Bạn có thể làm điều này theo nhiều cách khác nhau. Bạn có thể dup nó ở đâu đó và sau đó dup2 nó trở lại (và đóng dup một lần). Cá nhân tôi không thích viết các triển khai riêng của cat như được đề xuất trong các câu trả lời khác. Nếu điều duy nhất bạn muốn được chuyển hướng một lệnh shell đơn với system vào một tập tin trong hệ thống tập tin, sau đó có lẽ là cách trực tiếp và đơn giản nhất là xây dựng các lệnh shell để làm điều này như

system("ls -l > Result"); 

Nhưng bạn phải hãy cẩn thận nếu tên tệp (Result) xuất phát từ đầu vào của người dùng vì người dùng có thể cung cấp một cái gì đó như 'Result; rm -rf /*' làm tên tệp.

Ngoài ra, về chủ đề bảo mật, bạn nên cân nhắc chỉ định đường dẫn đầy đủ đến ls như đề xuất trong các ý kiến:

system("/bin/ls -l > Result"); 
+1

Tôi đã chỉnh sửa bài đăng của bạn để bao gồm một đường dẫn tuyệt đối đến ls trong ví dụ của bạn. – Wug

+0

Chỉnh sửa được hoàn nguyên vì OP chạy '" ls "' và điều này sẽ thay đổi ý nghĩa của cuộc gọi hệ thống. Câu hỏi cũng không liên quan đến đường dẫn tuyệt đối hoặc tương đối. Tôi nghĩ tốt hơn nên hỏi @unkulunkulu nếu anh ta muốn sửa lại câu trả lời của mình. – Andomar

+0

@Andomar, trên thực tế, tôi chấp nhận chỉnh sửa, nhưng dù sao, cả hai điểm của bạn đều hợp lệ, tôi không thấy sự khác biệt :) Wug, cảm ơn vì gợi ý, nó sẽ được nhìn thấy trong các bình luận. – unkulunkulu

2

Bạn nên sử dụng popen() chức năng thư viện và đọc khối dữ liệu từ trở FILE * và viết chúng vào bất kỳ tập tin đầu ra nào bạn thích.

Reference.

4

Điều đơn giản là sử dụng > thực:

#include <stdio.h> 
int main() 
{ 
    system("ls -l > /some/file"); 

    return 0; 
} 

Một thay thế là sử dụng popen(), một cái gì đó dọc theo dòng của

#include <stdio.h> 
    #include <stdlib.h> 
    main() 
    { 
      char *cmd = "ls -l"; 
      char buf[BUFSIZ]; 
      FILE *ptr, *file; 

      file = fopen("/some/file", "w"); 
      if (!file) abort(); 
      if ((ptr = popen(cmd, "r")) != NULL) { 
        while (fgets(buf, BUFSIZ, ptr) != NULL) 
          fprintf(file, "%s", buf); 
        pclose(ptr); 
      } 
      fclose(file); 
      return 0; 
    } 
0

sử dụng dup thay vì dup2. dup tạo trình mô tả tệp bí danh, giá trị nào phải luôn là bộ mô tả tệp có sẵn nhỏ nhất.

new_fd = dup(file); - Trong tuyên bố này file có thể có giá trị 3 (vì stdin0, stdout1stderr2).do đó new_fd sẽ là 4

Nếu bạn muốn chuyển hướng stdout vào tệp. Sau đó làm như sau.

close(stdout); 
new_fd = dup(file); 

Bây giờ dup sẽ trở lại 1 là bí danh cho các mô tả file, bởi vì chúng tôi đóng stdout mô tả tập tin để mở là 0,2,31 là nhỏ nhất mô tả tập tin có sẵn.

Nếu bạn đang sử dụng dup2 phương tiện, dup2(file,1); - làm như thế này

+0

Sử dụng 'dup()' thay vì 'dup2()' là _only_ nếu bạn không quan tâm vị trí trùng lặp được đặt. Nếu bạn quan tâm, sử dụng 'dup2()' - đó là mục đích rõ ràng của nó! Nếu thay vào đó bạn chỉ đơn giản là hy vọng cho tốt nhất, như câu trả lời này, nó sẽ làm việc tốt cho đến một ngày mô hình phá vỡ và bạn sẽ không có bất kỳ ý tưởng tại sao nó không thành công. Những người làm cho một số tình tiết tăng nặng vào cuối đêm có thể tránh được bằng cách đơn giản là làm đúng cách ngay từ đầu. – mah

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