为什么这个Linux编程C示例代码失败?

为什么这个Linux编程C示例代码失败?,c,ubuntu,C,Ubuntu,我试图运行高级Linux编程书中的示例(清单3.4,第51页): 知道这里怎么了吗?(使用Ubuntu 10.10)快速猜测,无需验证:您可能必须给出ls命令的完整路径,如/bin/ls快速猜测,无需验证:您可能必须给出ls命令的完整路径,如/bin/ls传递给spawn函数的“程序”参数不正确。按照execvp手册页的规定: 这些函数的初始参数是要执行的文件名 这里要执行的文件是/bin/ls传递给spawn函数的“program”参数不正确。按照execvp手册页的规定: 这些函数的初始参数

我试图运行高级Linux编程书中的示例(清单3.4,第51页):


知道这里怎么了吗?(使用Ubuntu 10.10)

快速猜测,无需验证:您可能必须给出ls命令的完整路径,如/bin/ls

快速猜测,无需验证:您可能必须给出ls命令的完整路径,如/bin/ls

传递给spawn函数的“程序”参数不正确。按照execvp手册页的规定:

这些函数的初始参数是要执行的文件名

这里要执行的文件是/bin/ls

传递给spawn函数的“program”参数不正确。按照execvp手册页的规定:

这些函数的初始参数是要执行的文件名

根据Tom的请求,此处要执行的文件是/bin/ls

问题似乎是命名命令的字符串中的(额外)空格

请记住,您并不是在调用bash(shell)解释器并为其提供string命令。您正在“命名”一个命令,在这方面,它类似于命名一个文件,在与可用命令(文件)进行比较时,会考虑所有字符。

根据Tom的要求:

问题似乎是命名命令的字符串中的(额外)空格


请记住,您并不是在调用bash(shell)解释器并为其提供string命令。您正在“命名”一个命令,在这方面它类似于命名一个文件,在与可用的命令(文件)进行比较时,会考虑所有字符。

是否会出现
ls
之前的空格问题?请尝试
“ls”
而不是
“ls”
。甚至
“/bin/ls”
。此外,您还可以从
errno
获取有关错误的信息;为什么不检查它呢?添加“perror”(“Execvp failed”);”而不是(或除了)fprintf。这将打印一条可读的错误消息,解释到底发生了什么。@MihaiStancu是的,是空间问题。。。奇怪的是,在控制台中,我可以输入“ls”,它就可以工作了。无论如何,谢谢!请以答案的形式发布@汤姆布里托:那是因为你的shell解析你的输入。在
ls
之前的空格可能是问题吗?试试
“ls”
而不是
“ls”
。甚至
“/bin/ls”
。此外,您还可以从
errno
获取有关错误的信息;为什么不检查它呢?添加“perror”(“Execvp failed”);”而不是(或除了)fprintf。这将打印一条可读的错误消息,解释到底发生了什么。@MihaiStancu是的,是空间问题。。。奇怪的是,在控制台中,我可以输入“ls”,它就可以工作了。无论如何,谢谢!请以答案的形式发布@TomBrito:那是因为你的shell解析你的输入。只要能根据
path
找到二进制文件,就不需要完整的路径。由于给出的代码在可执行文件名的第一个字符中有一个空格(这可能是一个错误),您的完整路径解决方案可以工作,但原因是错误的。尽管如此,完整的路径仍然更可取!只要可以根据
path
找到二进制文件,就不需要完整路径。由于给出的代码在可执行文件名的第一个字符中有一个空格(这可能是一个错误),您的完整路径解决方案可以工作,但原因是错误的。尽管如此,完整的路径仍然更可取!
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

/* Spawn a child process running a new program. PROGRAM is the name
 of the program to run; the path will be searched for this program.
 ARG_LIST is a NULL-terminated list of character strings to be
 passed as the program’s argument list. Returns the process ID of
 the spawned process. */
int spawn(char* program, char** arg_list) {
    pid_t child_pid;
    /* Duplicate this process. */
    child_pid = fork();
    if (child_pid != 0)
        /* This is the parent process. */
        return child_pid;
    else {
        /* Now execute PROGRAM, searching for it in the path. */
        execvp(program, arg_list);
        /* The execvp function returns only if an error occurs. */
        fprintf(stderr, "an error occurred in execvp\n");
        abort();
    }
    return 0;
}

int main() {
    /* The argument list to pass to the "ls” command. */
    char* arg_list[] = { "ls", /* argv[0], the name of the program. */
    "-l", "/", NULL /* The argument list must end with a NULL. */
    };
    /* Spawn a child process running the "ls” command. Ignore the
     returned child process ID. */
    spawn(" ls", arg_list);
    printf("done with main program\n");
    return 0;
}
an error occurred in execvp
done with main program