在bash脚本中(在REHL5上运行),我使用/ usr / bin / time命令(而不是内置时间命令)来记录在同一脚本中运行的其他命令的运行时间。我面临的问题是,一些我想记录时间的命令不是内置命令或外部脚本,而是在脚本中声明或源自其他脚本的函数。我发现time命令失败并显示如下错误:
/usr/bin/time: cannot run shared-func: No such file or directory
这意味着我在其他地方声明的函数shared-func()在范围内不可见,因此时间无法运行该命令。我已经进行了一些测试,并验证了此错误的原因实际上是因为time命令试图在新的子shell中执行其命令,因此丢失了其范围内的每个已声明的函数或变量。有办法解决这个问题吗?理想的解决方案是强制time命令更改其行为,并使用当前的shell来执行其命令,但如果不可能的话,我也对任何其他解决方案感兴趣。
作为记录,下面是我运行的测试。我创建了两个小脚本:
shared.sh:
function shared-func() {
echo "The shared function is visible."
}
test.sh:
#!/bin/bash
function record-timestamp() {
/usr/bin/time -f % -a -o timestamps.csv "$@"
}
source "shared.sh"
record-timestamp shared-func
这是测试:
$ ./test.sh
/usr/bin/time: cannot run shared-func: No such file or directory
$
是一个不同的过程。一个子shell,没有。
子shell是您在父shell分叉但不分叉时获得的东西exec()
–这是通过复制当前shell实例进行的新过程。在子外壳程序中可以访问功能,尽管它们对父外壳程序没有直接影响(退出子程序时,使用子外壳程序更改进程状态)。
在不使用exec
的情况下启动外部程序时,shell首先派生,然后调用execve()
来调用新程序。execve()
用正在运行的程序替换内存中的过程映像-而不是fork()
,即创建子shell导致失败。而是exec()
一个单独程序的调用。
即使您的新进程也是一个shell,即使经历了任何exec()
-family调用,它也不是子shell,而是一个全新的进程。
tl; dr:您不能使用外部程序将外壳函数调用包装在当前外壳中,因为外部程序的调用始终使用execve()
,并且execve()
始终清除进程状态-包括未导出的外壳函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句