我有一个项目在Linux操作系统上用C ++编写一个shell,它可以运行终端可以运行的命令子集,如cd
,ls
等。
我的问题是,如果我使用类似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”);打印出任何东西或者我必须添加其他东西吗?
答案 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
结尾的版本以两种方式处理第一个参数:
如果第一个参数不包含 / ,则使用(当前)PATH
环境变量来查找正确的目录。 PATH
变量应该是由:分隔的目录路径列表,以及文件名(即execlp
或execvp
的第一个参数)在每个目录中依次搜索。如果第一个参数 包含 / ,那么它的处理方式与其他exec
变体的处理方式相同:第一个参数必须是实际的路径。可执行文件,通常是一个绝对路径(即一个以 / 开头的路径),虽然允许它是一个相对路径,在这种情况下,它将被视为相对于当前工作目录
此外,如果找到某个文件但未将其识别为可执行二进制文件,则将其视为 shell 脚本,方法是将其传递给默认shell(通常为{{ 1}})。在这种情况下,非/bin/sh
p
版本只会返回错误。 (这与&#34; shebang&#34;执行不同,后者不是由Posix指定的,但通常由系统图像加载器执行,以便它可以与任何exec
变体一起使用。)
对于shell解释器, v 版本更方便。遗憾的是,没有提供 e 和 p 选项的版本(尽管GNU C库exec
确实提供了一个,{{1因为没有这种可能性,就无法使用当前的glibc
变量进行自动路径查找;仅使用新的execvpe
变量。
参考文献:
Posix定义:http://pubs.opengroup.org/onlinepubs/9699919799/functions/execl.html
PATH
的Linux联机帮助页(在PATH
中,所有其他execve
个变体最终都在调用glibc
):http://linux.die.net/man/2/execve
其余exec
变体的Linux联机帮助页:http://linux.die.net/man/3/exec