如何在bash中对子进程计时?

如何在bash中对子进程计时?,bash,time,child-process,Bash,Time,Child Process,我有一个编译过的二进制程序,它调用了一大堆(~300)子bash脚本。我只想找到一种方法来计算每个子进程的时间,以找出哪些子进程花费的时间最长。问题是我无法更改已编译的二进制文件(例如通过添加timefoo.sh>>bar\u log.txt)。我可以更改子脚本,因此理论上我可以将它们移动到另一个位置,并用脚本替换它们,这些脚本只需使用time命令从新位置调用这些脚本,但是,还有300多个脚本具有唯一的名称等等。我想知道是否有办法调用原始二进制文件并获取执行子进程的时间日志 提前谢谢 编辑:我对

我有一个编译过的二进制程序,它调用了一大堆(~300)子bash脚本。我只想找到一种方法来计算每个子进程的时间,以找出哪些子进程花费的时间最长。问题是我无法更改已编译的二进制文件(例如通过添加
timefoo.sh>>bar\u log.txt
)。我可以更改子脚本,因此理论上我可以将它们移动到另一个位置,并用脚本替换它们,这些脚本只需使用
time
命令从新位置调用这些脚本,但是,还有300多个脚本具有唯一的名称等等。我想知道是否有办法调用原始二进制文件并获取执行子进程的时间日志

提前谢谢


编辑:我对其他程序的访问权限也有限,无法下载/安装新程序。例如,我没有顶部的

环境变量
ENV
(对于POSIX Shell;对于bash,如果不是以名称
sh
启动,
bash_ENV
)甚至由非交互Shell解析为启动时运行的脚本位置

因此,您可以创建一个初始化跟踪的文件:

if [ -n "$BASH_VERSION" ]; then
  # SECONDS is time since the start of this individual script
  PS4=':$BASH_SOURCE:$LINENO:$SECONDS+'
else
  # note that calling $(date) slows your code substantially
  # nothing to do about it without shell extensions, however.
  PS4=':${0}:$(date)+'
fi
set -x

…并将
ENV
BASH_ENV
设置为指向该文件。

您需要什么分辨率?整数秒精度足够吗?如果需要,可以。我更喜欢ms分辨率,因为其中一些过程相当快。但我真正感兴趣的是最长的,大约是秒/10秒。还有,你们有什么版本的shell?在最近的Bash4中,我们有了更多的性能选项。顺便说一句,在现实世界中,我会找到一种方法让它可用。即使您不能在运行代码的容器中安装新软件,主机上运行的Sysdig也可以跟踪容器中的内容——这非常彻底,开销也很低。@bishop,对。如果这些进程目前在除单个userkernel开关之外的其他地方运行缓慢,那么让系统调用变得更昂贵将产生扭曲测量的效果,这些测量的目的是确定瓶颈在正常、无仪器运行期间的位置,从而将测量的时间移向大量(可能很快)的事情系统调用而不是单个慢速调用。可能有助于陷阱退出添加
陷阱:在
set-x
之前退出$?'exit
您能详细说明一下吗?在运行已编译的二进制文件之前是否运行此文件?输出到哪里去了?[-n$BASH\u版本]是做什么用的?(我的
$BASH_VERSION
输出是
4.1.2(1)-release
)@WarBro,不,您不直接运行它——您创建了两个环境变量,分别称为
ENV
BASH_ENV
,每个变量都包含带有此代码的文件名(答案已经说过)。由这些变量命名的文件的内容(一个或另一个,取决于shell是否为POSIX-y,答案已经说过)将在非交互式shell启动期间执行。默认情况下,输出转到stderr,但您可以打开指向其他地方的FD,并将
BASH\u XTRACEFD
设置为该FD的编号,以便在活动shell为BASH的情况下将其指向其他地方。@WarBro,
[-n“$BASH\u VERSION”]
(空格很重要--
[-n
[-n
不同)检查您的shell是否是bash。既然您说它是由编译程序启动的shell,您无法更改,我们没有任何理由相信该shell是bash,而不是
/bin/sh
,所以测试这两种情况很重要。啊,我误解了。谢谢!