有没有人能用简单的例子解释shell脚本中exec命令的用途是什么?
答案 0 :(得分:260)
exec
内置命令镜像内核中的函数,其中有一个基于execve
的函数,通常从C调用。
exec
替换当前流程中的当前程序,而不fork
新流程。在你编写的每个剧本中都不会使用它,但它偶尔会派上用场。以下是我使用过的一些场景;
我们希望用户在不访问shell的情况下运行特定的应用程序。我们可以在/ etc / passwd中更改登录程序,但也许我们希望从启动文件中使用环境设置。所以,在(比方说).profile
中,最后一个语句说的是:
exec appln-program
所以现在没有shell可以回去了。即使appln-program
崩溃,最终用户也无法访问shell,因为它不存在 - exec
取代了它。
我们想在/ etc / passwd中使用不同的shell。看起来很愚蠢,有些网站不允许用户更改他们的登录shell。我知道的一个网站上的每个人都以csh
开头,每个人都只是在.login
(csh启动文件)中调用ksh
。虽然这样做有效,但它会使一个流浪csh
进程运行,并且注销是两个阶段,可能会让人感到困惑。所以我们将它更改为exec ksh
,它刚刚用korn shell替换了c-shell程序,并使一切变得更简单(还有其他问题,例如ksh
不是登录的事实-shell)。
只是为了保存流程。如果我们打电话给prog1 -> prog2 -> prog3 -> prog4
等并且永远不会回去,那么让每个电话都成为一名执行官。它节省了资源(不可否认,除非重复这些资源),并使关闭变得更加简单。
你显然已经看到exec
在某个地方被使用了,也许如果你展示了那些惹恼你的代码,我们可以证明它的合理性。
编辑:我意识到上面的答案是不完整的。 exec
和ksh
等shell中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"
在read -u
上使用print -u
或bash
的ksh时,有几种方法可以使用这些方法,例如:
read <&3
echo stuff >&4
答案 1 :(得分:36)
只是为了通过简短的新手友好的简短答案来增加接受的答案,您可能不需要exec
。
如果你还在这里,下面的讨论应该有希望揭示原因。当你跑步时,比方说,
sh -c 'command'
运行sh
实例,然后启动command
作为该sh
实例的子项。 command
完成后,sh
实例也会完成。
sh -c 'exec command'
运行sh
实例,然后用sh
二进制替换<{em} 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
实例的解决方法(例如,如果你真的想要运行你自己的漂亮gosh
而不是sh
,但你的/etc/shells
中没有列出你的,所以你不能将它指定为你的登录shell。
第二次使用exec
来操作文件描述符是一个单独的主题。接受的答案很好地涵盖了这一点;为了保持这种自包含,我只需按照手册中的exec
后面跟着重定向而不是命令名。