为什么我在命令行上看不到 execvp() 的结果?
Why can't I see the results of execvp() on the command line?
请注意,这是一项家庭作业。目标是创建一个 shell 界面。
问题是为什么我输入命令时在终端上看不到execvp()的结果?
代码如下:
int getcmd(char *prompt, char *args[], int *background)
{
int length, i = 0;
char *token, *loc;
char *line;
size_t linecap = 0;
printf("%s", prompt);
length = getline(&line, &linecap, stdin);
if (length <= 0) {
exit(-1);
}
// Check if background is specified..
if ((loc = index(line, '&')) != NULL) {
*background = 1;
*loc = ' ';
} else
*background = 0;
while ((token = strsep(&line, " \t\n")) != NULL) {
for (int j = 0; j < strlen(token); j++)
if (token[j] <= 32)
token[j] = '[=10=]';
if (strlen(token) > 0)
args[i++] = token;
}
return i;
}
以下是我的主要功能:
int main()
{
char *args[20];
int bg;
while(1){
bg = 0;
int cnt = getcmd("\n>> ", args, &bg);
pid_t child_pid = fork();
//for (int i = 0; i < cnt; i++)
// printf("\nArg[%d] = %s", i, args[i]);
// a negative number will be returned only
// if the forking was unsuccessful i.e
// no child process is cloned from the original
// process
if(child_pid < 0){
fprintf(stderr, "Fork Failed");
return 1;
}
// the return value for a successful fork of a child is 0
else if(child_pid == 0){
execvp(args[0], args);
}
// this is the parent process here
else {
int status;
if (bg == 1){
printf("\nBackground enabled..\n");
getcmd("\n>> ", args, &bg);
}
else{
printf("\nBackground not enabled \n");
waitpid(child_pid, NULL, 0);
}
}
}
}
当我 运行 我的代码时,它会编译并给我提示符 (>>)。当我 运行 一个命令如 ls
时,它只打印 Background not enabled(因为我没有指定 &)。但是,如果我在不同的终端上执行 ps
命令,我会看到有一个新进程 运行ning。我忽略了什么吗?当我将 ls
作为参数提供给 execvp()
系统调用时,为什么我看不到它的结果?
getcmd()
未能初始化 line
。它最初应该指向 NULL
:
char *line = NULL;
If linep
points to a NULL pointer, a new buffer will be allocated.
另外请问你在哪里NULL
-终止args
。 args
中最后一个被 getcmd()
赋值的元素应该指向 NULL
.
您可以通过
在最开始将所有 args
元素初始化为 NULL
来确保是这种情况
char * args[20];
for (size_t i = 0; i < 20; ++i)
{
args[i] = NULL;
}
为了测试,可以像这样初始化 args
char * args[] = {
"ls",
"ls",
"-alrt",
NULL /* a must */
}
The execv(), execvp(), and execvP() functions provide an array of pointers to null-terminated strings
that represent the argument list available to the new program. The first argument, by convention,
should point to the file name associated with the file being executed. The array of pointers must be
terminated by a NULL pointer.
请注意,这是一项家庭作业。目标是创建一个 shell 界面。
问题是为什么我输入命令时在终端上看不到execvp()的结果?
代码如下:
int getcmd(char *prompt, char *args[], int *background)
{
int length, i = 0;
char *token, *loc;
char *line;
size_t linecap = 0;
printf("%s", prompt);
length = getline(&line, &linecap, stdin);
if (length <= 0) {
exit(-1);
}
// Check if background is specified..
if ((loc = index(line, '&')) != NULL) {
*background = 1;
*loc = ' ';
} else
*background = 0;
while ((token = strsep(&line, " \t\n")) != NULL) {
for (int j = 0; j < strlen(token); j++)
if (token[j] <= 32)
token[j] = '[=10=]';
if (strlen(token) > 0)
args[i++] = token;
}
return i;
}
以下是我的主要功能:
int main()
{
char *args[20];
int bg;
while(1){
bg = 0;
int cnt = getcmd("\n>> ", args, &bg);
pid_t child_pid = fork();
//for (int i = 0; i < cnt; i++)
// printf("\nArg[%d] = %s", i, args[i]);
// a negative number will be returned only
// if the forking was unsuccessful i.e
// no child process is cloned from the original
// process
if(child_pid < 0){
fprintf(stderr, "Fork Failed");
return 1;
}
// the return value for a successful fork of a child is 0
else if(child_pid == 0){
execvp(args[0], args);
}
// this is the parent process here
else {
int status;
if (bg == 1){
printf("\nBackground enabled..\n");
getcmd("\n>> ", args, &bg);
}
else{
printf("\nBackground not enabled \n");
waitpid(child_pid, NULL, 0);
}
}
}
}
当我 运行 我的代码时,它会编译并给我提示符 (>>)。当我 运行 一个命令如 ls
时,它只打印 Background not enabled(因为我没有指定 &)。但是,如果我在不同的终端上执行 ps
命令,我会看到有一个新进程 运行ning。我忽略了什么吗?当我将 ls
作为参数提供给 execvp()
系统调用时,为什么我看不到它的结果?
getcmd()
未能初始化 line
。它最初应该指向 NULL
:
char *line = NULL;
If linep points to a NULL pointer, a new buffer will be allocated.
另外请问你在哪里NULL
-终止args
。 args
中最后一个被 getcmd()
赋值的元素应该指向 NULL
.
您可以通过
在最开始将所有args
元素初始化为 NULL
来确保是这种情况
char * args[20];
for (size_t i = 0; i < 20; ++i)
{
args[i] = NULL;
}
为了测试,可以像这样初始化 args
char * args[] = {
"ls",
"ls",
"-alrt",
NULL /* a must */
}
The execv(), execvp(), and execvP() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the file name associated with the file being executed. The array of pointers must be terminated by a NULL pointer.