编写shell - 如何确定不同exec调用的可执行路径和文件名

时间:2014-03-21 21:35:17

标签: c++ linux shell posix

我有一个项目在Linux操作系统上用C ++编写一个shell,它可以运行终端可以运行的命令子集,如cdls等。

我的问题是,如果我使用类似execl("bin/ls","ls")的内容,它如何知道执行ls的位置。它是否默认只是从运行程序的目录运行ls。如果是这样,我如何更改它的运行位置,就像我运行cd foo然后再次运行ls一样。 是的,我正在制作一个限量版的bash。

这是我到目前为止运行ls的原因。

int quash :: ls(string path)

{
        pid_t child = 0;
        child = fork();

        if (child < 0)
        {
            fprintf( stderr, "process failed to fork\n" );
            return 1;
        }
        if (child == 0)
        {
            wait(NULL);
        }
        else
        {
            execlp("/bin/ls", "ls");
        }
        return 0;
    }

execlp()“/ bin / ls”,“ls”);打印出任何东西或者我必须添加其他东西吗?

1 个答案:

答案 0 :(得分:3)

<强>摘要

如果您致电execl("bin/ls", "ls"),系统将尝试在当前工作目录中名为ls的目录中查找名为bin的文件。这几乎可以肯定你想做什么。你可能要么:

execlp("ls", "ls);

execl("/bin/ls", "ls");

虽然这些也可能都不是你想要的。

更多详情

有许多不同的功能可用于用新的过程映像替换当前运行的过程;这些至少包括以下内容:

execl,  execv
execle, execve
execlp, execvp

包含 l 的版本是 variadic ;它们采用以NULL结尾的const char*参数列表,这些参数定义了应传递给新可执行文件的argv向量。包含 v 的版本改为使用单个char*const[]参数,该参数是以NULL结尾的字符串数组,用于构造argv向量。

e结尾的版本需要一个额外的参数,这是一个char *const[],用于构造新的可执行文件的环境变量。其他版本使用现有的环境变量集合。

p结尾的版本以两种方式处理第一个参数:

  1. 如果第一个参数不包含 / ,则使用(当前)PATH环境变量来查找正确的目录。 PATH变量应该是由分隔的目录路径列表,以及文件名(即execlpexecvp的第一个参数)在每个目录中依次搜索。如果第一个参数 包含 / ,那么它的处理方式与其他exec变体的处理方式相同:第一个参数必须是实际的路径。可执行文件,通常是一个绝对路径(即一个以 / 开头的路径),虽然允许它是一个相对路径,在这种情况下,它将被视为相对于当前工作目录

  2. 此外,如果找到某个文件但未将其识别为可执行二进制文件,则将其视为 shell 脚本,方法是将其传递给默认shell(通常为{{ 1}})。在这种情况下,非/bin/sh p版本只会返回错误。 (这与&#34; shebang&#34;执行不同,后者不是由Posix指定的,但通常由系统图像加载器执行,以便它可以与任何exec变体一起使用。)

  3. 对于shell解释器, v 版本更方便。遗憾的是,没有提供 e p 选项的版本(尽管GNU C库exec确实提供了一个,{{1因为没有这种可能性,就无法使用当前的glibc变量进行自动路径查找;仅使用新的execvpe变量。

    参考文献:

    1. Posix定义:http://pubs.opengroup.org/onlinepubs/9699919799/functions/execl.html

    2. PATH的Linux联机帮助页(在PATH中,所有其他execve个变体最终都在调用glibc):http://linux.die.net/man/2/execve

    3. 其余exec变体的Linux联机帮助页:http://linux.die.net/man/3/exec