Answers:
该exec
内核中的内置命令镜功能,还有他们家的基础上execve
,这通常是由被称为C.
exec
在当前进程中替换当前程序,而无需fork
执行新进程。并不是您在编写的每个脚本中都会使用它,但有时会派上用场。这是我使用过的一些场景;
我们希望用户在不访问外壳的情况下运行特定的应用程序。我们可以在/ etc / passwd中更改登录程序,但是也许我们希望从启动文件中使用环境设置。因此,在(say)中.profile
,最后一条语句表示如下内容:
exec appln-program
所以现在没有外壳可以回去了。即使appln-program
崩溃,最终用户也无法进入shell,因为它不存在-被exec
替换了。
我们想使用与/ etc / passwd中不同的shell。看起来很愚蠢,有些网站不允许用户更改其登录外壳。我知道有一个站点,每个人都从这里开始csh
,每个人都.login
将对的调用放入(csh启动文件)ksh
。在此csh
过程中,它留下了一个混乱的进程,并且注销是两个阶段,可能会造成混乱。因此,我们将其更改为exec ksh
仅用korn shell替换了c-shell程序,并使一切变得更简单(与此相关的还有其他问题,例如,事实ksh
并非登录shell)。
只是为了节省流程。如果我们打电话prog1 -> prog2 -> prog3 -> prog4
等,再也不回头,那么让每个电话都执行一次。这样可以节省资源(当然,除非重复,否则可以节省很多资源),并且使关机更加简单。
您显然已经exec
在某处使用过,也许如果您显示的代码有问题,我们可以证明其使用是合理的。
编辑:我意识到我上面的答案是不完整的。in 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
上使用bash
,例如:
read <&3
echo stuff >&4
exec
可用于重定向:>如果没有指定命令,任何重定向采取在当前shell效果,返回状态是0。如果有一个重定向错误,返回状态是1。但如何做exec
实际工作来更改文件描述符?为什么为此任务选择此特定命令?(Markdown现在失败了吗?)
exec >.\logfilename.log 2>&1
&>
是bash
扩展名(请参阅man bash
),您的示例等效于exec >/var/log/userdata.log 2>&1
。换句话说,它将stdout和stderr重定向到该文件。除非重置它们,否则后面的命令将继承这些重定向,但是将执行它们。
只需使用简短的新手友好的简短答案来增加已接受的答案,您可能就不需要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
实例(例如,如果您确实想运行自己的spiffy gosh
而不是您的spiffy ,sh
但您的未列出),则/etc/shells
可以不要将其指定为您的登录外壳)。
exec
操纵文件描述符的第二个用途是一个单独的主题。公认的答案很好地涵盖了这一点。为了使它自成一体,对于任何exec
后面跟着重定向而不是命令名的内容,我都只会参考手册。