编写shell-如何确定不同exec调用的可执行路径和文件名 我有一个在C++操作系统上编写shell程序的程序,它可以运行一个命令的子集,一个终端可以运行如 CD, Ls>代码>等。

编写shell-如何确定不同exec调用的可执行路径和文件名 我有一个在C++操作系统上编写shell程序的程序,它可以运行一个命令的子集,一个终端可以运行如 CD, Ls>代码>等。,c++,linux,shell,posix,C++,Linux,Shell,Posix,我的问题是,如果我使用类似于execl(“bin/ls”、“ls”)的东西,它如何知道从哪里执行ls。默认情况下,仅从运行程序的目录中运行ls。如果是这样的话,我如何改变它的运行位置,比如我运行cdfoo,然后再次运行ls。 是的,我正在制作bash的有限版本 以下是我到目前为止关于运行ls的内容 int-quash::ls(字符串路径) { pid_t child=0; child=fork(); if(子级

我的问题是,如果我使用类似于
execl(“bin/ls”、“ls”)
的东西,它如何知道从哪里执行
ls
。默认情况下,仅从运行程序的目录中运行
ls
。如果是这样的话,我如何改变它的运行位置,比如我运行
cdfoo
,然后再次运行ls。 是的,我正在制作bash的有限版本

以下是我到目前为止关于运行ls的内容

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

{
pid_t child=0;
child=fork();
if(子级<0)
{
fprintf(stderr,“进程分叉失败\n”);
返回1;
}
如果(子项==0)
{
等待(空);
}
其他的
{
execlp(“/bin/ls”、“ls”);
}
返回0;
}

Will execlp()“/bin/ls”、“ls”);打印出任何内容,还是我必须添加其他内容?

摘要

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

execlp("ls", "ls);

虽然也有可能这两者都不是你真正想要的

更多详细信息

有许多不同的函数可用于用新的进程映像替换当前正在运行的进程;这些措施至少包括:

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

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

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

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

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

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

    参考资料:

  • Posix定义:

  • 用于
    execve
    的Linux手册页(在
    glibc
    中,所有其他
    exec
    变体最终调用
    execve
    ):

  • 其余
    exec
    变体的Linux手册页:


  • 摘要

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

    execlp("ls", "ls);
    

    虽然也有可能这两者都不是你真正想要的

    更多详细信息

    有许多不同的函数可用于用新的进程映像替换当前正在运行的进程;这些措施至少包括:

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

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

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

  • 如果第一个参数不包含/,则使用(当前)
    PATH
    环境变量来查找正确的目录。代码