2012-01-11 31 views
6

Khi tôi gọi execvp, ví dụ execvp(echo, b) trong đó b là một mảng đối số cho lệnh a, sẽ thay đổi mảng này sau này có ảnh hưởng đến lệnh gọi execvp được thực hiện trước đó không? Khi tôi thử gọi execp (echo, b), nó kết thúc in ra (null) thay vì nội dung bên trong của b. Bất cứ ai có thể chỉ ra lý do tại sao và những gì tôi phải làm để vượt qua các đối số một cách chính xác?Xử lý đối số mảng của execvp?

Trả lời

12

Sau khi bạn gọi exec() hoặc một nếu người thân của nó, chương trình gốc của bạn không còn tồn tại nữa. Điều đó có nghĩa là không có gì trong chương trình đó có thể ảnh hưởng đến bất cứ điều gì sau khi cuộc gọi exec(), vì nó không bao giờ chạy. Có lẽ bạn không xây dựng mảng đối số chính xác? Dưới đây là một ví dụ nhanh làm việc của execvp():

#include <unistd.h> 

int main(void) 
{ 
    char *execArgs[] = { "echo", "Hello, World!", NULL }; 
    execvp("echo", execArgs); 

    return 0; 
} 

Từ execvp() man page:

Các execv(), execvp()execvpe() chức năng cung cấp một loạt các con trỏ null-chấm dứt chuỗi đại diện cho danh sách đối số có sẵn cho chương trình mới. Đối số đầu tiên, theo quy ước, nên trỏ đến tên tệp được liên kết với tệp đang được thực thi. Mảng con trỏ phải được chấm dứt bằng con trỏ NULL.

Lỗi thường gặp là bỏ qua phần "Đối số đầu tiên, theo quy ước, nên trỏ đến tên tệp được liên kết với tệp đang được thực hiện". Đó là phần đảm bảo rằng echo nhận được "echo" là argv[0], có lẽ điều đó phụ thuộc vào.

+0

Thay vì sử dụng echo, tôi đã sử dụng một chương trình khác về cơ bản sẽ in ra mọi thứ trong mảng argv của nó. Tôi luôn luôn giả định argv [0] sẽ là tên của lệnh chính nó (param đầu tiên của execv), nhưng trong trường hợp này sau khi gọi execv, argv [0] thì không. Thay vào đó là tham số thứ hai của execv. Bạn có thể làm rõ điều này? – Lucas

+0

Vâng, khi bạn chuyển danh sách đối số sang 'execv', bạn đã đặt' argv [0] 'thành tên của lệnh chưa? Mảng bạn chuyển làm đối số thứ hai 'execvp' * trở thành *' argv' trong chương trình mới, vì vậy bạn cần thiết lập nó theo cách mà nó mong đợi. –

+0

Mã này vi phạm const đúng đắn. Tôi thà viết const char * args [] = {...}; nhưng nguyên mẫu cho execvp yêu cầu các chuỗi trong args phải ghi được! – user877329

0

Hãy nhớ rằng sau exec, chương trình của bạn sẽ được đổi bằng chương trình mới. Nó không thực hiện nữa, vì vậy bất kỳ mã nào trong cùng một quá trình sau khi gọi exec, trên thực tế, không thể truy cập được.

Bạn có chắc chắn rằng mảng b bị chấm dứt bằng NULL không? Phần tử cuối cùng phải là NULL cho exec để hoạt động chính xác. Ngoài ra, hãy nhớ đặt tham số đầu tiên của bạn thành "echo" (argv [0]).

Hãy thử

execlp("echo", "echo", "something", NULL); 

Btw, execlp là thoải mái hơn một chút để sử dụng, bạn có thể vượt qua nhiều thông số như bạn muốn.

+1

Đó không phải là cách hoạt động của 'execvp()'. –

+0

Từ những gì tôi hiểu, execvp nhận lệnh và mảng argv. Tại thời điểm cuộc gọi execvp, cả lệnh và mảng argv đều không phải là NULL. Tuy nhiên, khi echo được gọi là nó dường như không có bất kỳ đối số. – Lucas

+0

Xin lỗi, typo - có nghĩa là 'execlp' ... –

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