Vấn đề của bạn là temp
là một con trỏ và bạn cần chuyển một chuỗi con trỏ đến execvp()
.
Cái gì như:
enum { MAX_ARGS = 64 };
char *args[MAX_ARGS];
char **next = args;
temp = strtok(line, " ");
while (temp != NULL)
{
*next++ = temp;
printf("%s\n", temp);
temp = strtok(NULL, " ");
}
*next = NULL;
execvp(args[0], args);
Lưu ý rằng danh sách đối số đã được đưa ra một con trỏ null như một terminator, giống như argv[argc] == NULL
trong main()
. Rõ ràng, tôi đã skimped trên kiểm tra lỗi (nếu bạn vượt qua hơn 63 đối số, bạn sẽ tràn qua args
mảng). Nhưng điều này có chứa ý tưởng cốt lõi.
Với ví dụ này, tôi dường như không thể để có được những lệnh đơn giản của ls
để làm việc, tôi đã cố gắng mkdir
và echo
và họ dường như làm việc tốt. Chuyển số ls
trả về -1 từ execvp()
.
Tôi không chắc chắn những gì các vấn đề có thể là - tất cả các công việc cho tôi:
ls
ls -l
ls -l madump.c
(nơi madump.c
sẽ xảy ra là một tập tin trong thư mục Tôi đang thử nghiệm tại)
Mã tôi đã sử dụng là:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
char line[1024];
while (fgets(line, sizeof(line), stdin) != NULL)
{
if (strcmp(line, "exit\n") == 0)
exit(EXIT_SUCCESS);
char *args[64];
char **next = args;
char *temp = strtok(line, " \n");
while (temp != NULL)
{
*next++ = temp;
printf("%s\n", temp);
temp = strtok(NULL, " \n");
}
*next = NULL;
puts("Checking:");
for (next = args; *next != 0; next++)
puts(*next);
execvp(args[0], args);
}
return EXIT_SUCCESS;
}
Lưu ý rằng tôi đã thêm \n
vào danh sách mã thông báo strtok()
sau khi tạo thư mục có dòng mới ở cuối tên. Tốt cho những người bạn khó chịu và làm bối rối kẻ thù bán giáo dục, nhưng gây phiền toái từ hầu hết các quan điểm khác. Lưu ý cách tôi in ra dữ liệu sẽ được chuyển đến execvp()
ngay trước khi thực sự làm như vậy. Thông thường, tôi muốn sử dụng printf("<<%s>>\n", *next);
thay vì chỉ puts()
để có được một dấu hiệu rõ ràng về nơi các đối số bắt đầu và kết thúc.
Kết quả từ cách chạy lệnh (doit
) là:
$ ./doit
ls -l madump.c
ls
-l
madump.c
Checking:
ls
-l
madump.c
-rw-r--r-- 1 jleffler staff 2352 Jul 28 2011 madump.c
$
bạn đã nhận được gì từ phiên bản của bạn?
Vì bạn không sử dụng 'argc' hoặc' argv', bạn có thể sử dụng 'int main (void)'. Với các tùy chọn trình biên dịch tôi sử dụng thường xuyên, ngăn chặn một vài cảnh báo. –
@JonathanLeffler Tôi sẽ sử dụng chúng sau này. Chỉ cần không vào thời điểm này. – caerulean
Đủ công bằng - nhưng đối với một SSCCE ([Ví dụ ngắn, tự chứa, đúng] (http://sscce.org/)), bạn cố gắng loại bỏ mọi thứ không quan trọng đối với ví dụ được rút gọn. Đó là một vấn đề nhỏ - rất nhỏ. Hầu hết các chương trình cung cấp nhiều cơ hội hơn cho sniping hơn của bạn. –