创建 UNIX shell
我想为 UNIX 创建一个迷你 shell,只是为了了解一切的来龙去脉。我对过去认为理所当然的事情有些困惑。这是一个有点哲学的问题。当我创建一个“shell”时,我假设我有一个没有 shell 的 UNIX,那么在这种情况下,std in 和 std out 是什么?像 system() 和 exec() 这样的函数不使用 shell 来执行程序,所以如果我首先创建一个 shell。这些功能如何运作?
I want to create a mini shell for UNIX just to know the ins and outs of everything. I am having some confusions understanding things that I used to get for granted. This is kinda philosophical question. When I creating a "shell", I assume I have a UNIX with no shell, so what would be the std in and std out in this case? doesnt functions like system() and exec() use the shell to execute programs, so if I am creating a shell in the first place. How do these functions work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
exec
系列中有多个函数:execve(2)
、execl(3)
、execle(3)
>、execlp(3)
、execv(3)
、execvp(3)
。第一个execve(2)
由操作系统内核作为系统调用提供。 (好吧,程序调用的函数是由系统 C 库提供的,但是它是系统调用的简单包装。)其他函数提供稍微不同的语义,并根据execve(2)
函数。shell 可以使用
execvp(3)
或execlp(3)
提供可执行文件的PATH
搜索,但至少bash( 1)
哈希可执行文件的完整路径名以提供性能优势。 (有关详细信息,请参阅bash(1)
内置hash
。)system(3)
通过/bin/sh 实现 - c
,正如您所猜测的。标准输入和输出由生成 shell 的程序设置。如果用户直接登录控制台,它将由
agetty(8)
或mgetty(8)
或任何getty
处理 -类似的程序处理直接登录。如果用户通过sshd(8)
登录,则sshd(8)
负责创建pty
并将终端从站委托给外壳。如果用户通过 xterm(1) 或其他终端仿真器创建 shell,那么这些进程将负责连接 shell 的标准输入、输出和错误。There are several functions in the
exec
family:execve(2)
,execl(3)
,execle(3)
,execlp(3)
,execv(3)
,execvp(3)
. The first one,execve(2)
is provided by the operating system kernel as a system call. (Well, okay, the function that programs call is provided by the system C library, but it is a simple wrapper around the system call.) The other functions provide slightly different semantics and are implemented in terms of theexecve(2)
function.The shells could use
execvp(3)
orexeclp(3)
to provide thePATH
search for executables, but at leastbash(1)
hashes the full pathname of executables to provide a performance benefit. (Seebash(1)
built-inhash
for details.)system(3)
is implemented via/bin/sh -c
, as you've surmised.The standard input and output is set up by whichever program spawned the shell. If a user logs in on the console directly, it'll be handled by
agetty(8)
ormgetty(8)
or whichevergetty
-alike program handles direct logins. If a user logs in viasshd(8)
, thensshd(8)
is in charge of creating thepty
and delegating the terminal slave to the shell. If a user creates their shells viaxterm(1)
or other terminal emulators, then those processes will be responsible for hooking up the standard input, output, and error for the shell.system(3)
确实使用(可能直接或通过 exec 间接)shell 来完成其工作。然而,exec(3)
和朋友们不使用 shell,而是直接执行指定的程序映像。您只需阅读它们各自的man
页面即可了解这一点。一个区别是,使用 system(),您将看到像通配符这样的糖被扩展,而如果您使用 exec() 将
*
作为参数传递给程序,您的程序将看到文字星号(并且可能不知道该怎么做)。shell 可以使用 exec() 等来实现。它从称为 TTY(电传打字机,或老式终端)或 PTY(伪终端,如现代系统中)的东西获取其标准输入和标准输出。请参阅 posix_openpt(2)。
system(3)
does indeed use (possibly directly or indirectly via exec) a shell to do its work.exec(3)
and friends, however, do not use a shell, but rather execute the specified program image directly. You can see this simply by reading their respectiveman
pages.One difference is that with system(), you will see sugar like wildcards being expanded, whereas if you pass
*
as an argument to your program using exec(), your program will see the literal asterisk (and probably not know what to do).A shell can be implemented using exec() among other things. It gets its stdin and stdout from something called the TTY (teletype, or old-school terminal) or PTY (pseudo-terminal, as in modern systems). See
posix_openpt(2)
.