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

标签 c++ linux shell posix

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

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

这是我到目前为止运行 ls 的结果。

int quash::ls(字符串路径)

{
        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;
    }

将执行clp()"/bin/ls","ls");打印任何内容还是我必须添加其他内容?

最佳答案

总结

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

execlp("ls", "ls);

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

尽管也有可能这些都不是您真正想要的。

更多详情

有许多不同的函数可以用来用新的进程镜像替换当前运行的进程;这些至少包括以下内容:

execl,  execv
execle, execve
execlp, execvp

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

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

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

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

  2. 此外,如果找到一个文件但它未被识别为可执行二进制文件,它将被视为一个 shell 脚本,通过传递给默认 shell(通常是 /bin/sh).在这种情况下,非 p exec 版本只会返回一个错误。 (这与 Posix 未指定的“shebang”执行不同,但通常由系统图像加载程序执行,因此它可以与任何 exec 变体一起工作。)

对于 shell 解释器,v 版本要方便得多。不幸的是,没有同时提供 ep 选项的版本(尽管 GNU C 库 glibc 确实提供了一个,execvpe ) 因为没有这种可能性,就无法使用当前的 PATH 变量进行自动路径查找;仅使用新的 PATH 变量。

引用资料:

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

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

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

关于c++ - 编写 shell - 如何确定不同 exec 调用的可执行路径和文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22569944/

相关文章:

C++ 字符串文字与 const 字符串

c++ - 时间戳和字节数组

c++ - QML "QtQuick.PrivateWidgets"未找到插件 "widgetsplugin"

Linux CLI 查找没有子路径的 dir 路径 - 结果只有父路径

java - 如何使用Java在windows上启动bat文件,在linux上启动sh文件从特定目录运行

linux - 在 shell 脚本中使用字符串中的变量

linux - 如何删除这样命名的文件?

C++设计模式以避免固定大小数组的模板

linux - docker push to nexus 3 - 校验和摘要格式无效

linux - 在 UNIX 中以相反的顺序获取句子