exec脚本在shell脚本中有什么用处?
任何人都可以用简单的例子来解释exec命令在shell脚本中的用法吗?
exec
内置命令镜像内核中的函数,有一个基于execve
,通常从C调用。
exec
取代当前进程中的当前程序,而不需要新build一个进程。 你写的每一个脚本都不是你要使用的东西,但它偶尔也派上用场。 以下是我用过的一些场景。
-
我们希望用户在不访问shell的情况下运行特定的应用程序。 我们可以在/ etc / passwd中更改login程序,但也许我们希望从启动文件中使用环境设置。 所以,在(说)
.profile
,最后的声明说:exec appln-program
所以现在没有可以返回的shell了。 即使
appln-program
崩溃,最终用户也无法进入shell,因为它不在那里 –exec
被replaceexec
了。 -
我们想要在/ etc / passwd中使用一个不同的shell。 看起来很愚蠢,一些网站不允许用户改变他们的loginshell。 我知道的一个站点每个人都从
csh
开始,每个人.login
在他们的.login
(csh启动文件)中调用ksh
。 虽然这样做,它留下了一个stream浪的csh
进程运行,注销是两个阶段,可能会混淆。 所以我们把它改成了exec ksh
,它用korn shell代替了c-shell程序,并且简化了一切(还有其他的问题,比如ksh
不是loginshell)。 -
只是为了保存过程。 如果我们调用
prog1 -> prog2 -> prog3 -> prog4
等,永远不会回去,然后使每个调用一个exec。 它节省了资源(没有太多,坦率地说,除非重复),并使关机更简单。
你很明显看到exec
在某个地方使用,也许如果你显示的代码搞砸你,我们可以certificate它的用途。
编辑 :我意识到我上面的答案是不完整的。 在像ksh
和bash
这样的shell中有两个用于exec
用途 – 用于打开文件描述符。 这里有些例子:
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号码和redirect符号之间放置一个空格,那么exec
会恢复到原来的含义:
exec 3 < thisfile # oops, overwrite the current program with command "3"
有几种方法可以使用这些,例如在ksh上使用read -u
或print -u
:
read <&3 echo stuff >&4
只是用一个简短的新手友好的简短答案来增加接受的答案,你可能不需要exec
。
如果你还在这里,下面的讨论应该希望揭示为什么。 当你跑步时,
sh -c 'command'
你运行一个sh
实例,然后作为该sh
实例的一个子sh
启动command
。 当command
结束时, sh
实例也完成。
sh -c 'exec command'
运行sh
实例,然后用 command
二进制代替 sh
实例,然后运行它。
当然,在这个有限的背景下,这两者都是无用的。 你只是想要
command
有一些额外的情况,你希望shell读取它的configuration文件或以某种方式设置环境作为运行command
的准备。 这几乎是exec command
有用的唯一情况。
#!/bin/sh ENVIRONMENT=$(some complex task) exec command
这做一些东西来准备环境,以便它包含所需的东西。 一旦完成, sh
实例就不再需要了,所以只需简单地用command
进程replacesh
实例就可以(小)优化,而不是将其作为subprocess运行并等待它,然后尽快退出当它完成。
同样,如果要在shell脚本的最后释放尽可能多的资源,可能需要将该命令作为优化执行。
如果有东西强迫你运行sh
但是你真的想运行其他东西,那么exec something else
当然是一个解决方法来replace不需要的sh
实例(例如,如果你真的想运行自己的spiffy gosh
而不是sh
但是你的不是没有在/etc/shells
列出,所以你不能指定它作为你的loginshell)。
exec
对操作文件描述符的第二次使用是一个单独的主题。 接受的答案很好地覆盖了这个问题。 为了保持这种独立性,我只要按照exec
来跟随redirect而不是命令名的任何东西,都可以遵循手册。