谁能用简单的例子解释一下 exec 命令在 shell 脚本中的用途是什么?
2 回答
exec
内置命令镜像内核中的函数,有一个基于 的家族,通常execve
从 C 中调用。
exec
在当前进程中替换当前程序,而不fork
创建新进程。您不会在编写的每个脚本中都使用它,但它有时会派上用场。以下是我使用过的一些场景;
我们希望用户在不访问 shell 的情况下运行特定的应用程序。我们可以更改 /etc/passwd 中的登录程序,但也许我们希望从启动文件中使用环境设置。所以,在 (say)
.profile
中,最后一条语句是这样说的:exec appln-program
所以现在没有shell可以回去了。即使
appln-program
崩溃,最终用户也无法访问 shell,因为它不存在 - 被exec
替换了。我们想使用与 /etc/passwd 中的不同的 shell。尽管看起来很愚蠢,但有些网站不允许用户更改他们的登录 shell。我知道的一个网站让每个人
csh
都.login
从ksh
. 虽然这有效,但它留下了一个杂散的csh
进程运行,并且注销是两个阶段,这可能会让人感到困惑。因此我们将其更改为exec ksh
仅用 korn shell 替换了 c-shell 程序,并使一切变得更简单(这还有其他问题,例如它ksh
不是登录 shell)。只是为了节省流程。如果我们调用
prog1 -> prog2 -> prog3 -> prog4
etc. 并且永远不会返回,那么让每个调用都成为一个 exec。它节省了资源(不可否认,除非重复)并使关机更简单。
您显然已经exec
在某处看到使用过,也许如果您展示了困扰您的代码,我们可以证明它的使用是合理的。
编辑:我意识到我上面的答案是不完整的。在 shell中有两种用法,例如和- 用于打开文件描述符。这里有些例子:exec
ksh
bash
exec 3< thisfile # open "thisfile" for reading on file descriptor 3
exec 4> thatfile # open "thatfile" for writing on file descriptor 4
exec 8<> tother # open "tother" for reading and writing on fd 8
exec 6>> other # open "other" for appending on file descriptor 6
exec 5<&0 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4 # copy write file descriptor 4 onto 7
exec 3<&- # close the read file descriptor 3
exec 6>&- # close the write file descriptor 6
请注意,间距在这里非常重要。如果在 fd 编号和重定向符号之间放置一个空格,则exec
恢复为原始含义:
exec 3 < thisfile # oops, overwrite the current program with command "3"
有几种方法可以使用它们,在 ksh 上使用read -u
或print -u
, on bash
,例如:
read <&3
echo stuff >&4
只是用一个对新手友好的简短答案来增加接受的答案,您可能不需要exec
.
如果您还在这里,那么下面的讨论应该有望揭示原因。当你跑步时,说,
sh -c 'command'
您运行一个sh
实例,然后command
作为该sh
实例的子级启动。完成command
时,sh
实例也完成。
sh -c 'exec command'
运行一个sh
实例,然后用二进制文件替换该sh
实例,然后运行它。command
当然,在这种有限的情况下,这两者都是无用的;你只是想要
command
在某些边缘情况下,您希望 shell 读取其配置文件或以其他方式设置环境以准备运行command
. 这几乎是唯一exec command
有用的情况。
#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command
这做了一些准备环境的事情,以便它包含所需的内容。一旦完成,sh
实例就不再需要了,因此它是一个(次要)优化,只需将sh
实例替换为command
进程,而不是将sh
其作为子进程运行并等待它,然后在它完成后立即退出。
类似地,如果您想在 shell 脚本末尾为繁重的命令释放尽可能多的资源,您可能希望exec
将该命令作为优化。
如果某些东西迫使您运行sh
,但您确实想运行其他东西,那么exec something else
当然是替换不需要的实例的一种解决方法sh
(例如,如果您真的想运行自己的 spiffygosh
而不是sh
但您的没有列出,/etc/shells
那么您可以'不要将其指定为您的登录外壳)。
exec
操作文件描述符的第二个用途是一个单独的主题。接受的答案很好地涵盖了这一点;为了保持这种独立性,我将按照手册来处理exec
后面跟着重定向而不是命令名的任何内容。