我正在尝试加速调用子shell并执行各种操作的脚本集合.我很想知道是否有任何工具可用于执行shell脚本及其嵌套shell的时间,并报告脚本的哪些部分是最昂贵的.
例如,如果我有一个如下的脚本.
#!/bin/bash
echo "hello"
echo $(date)
echo "goodbye"
Run Code Online (Sandbox Code Playgroud)
我想知道三条线中的每一条花了多长时间.time
只会给我一些脚本的总时间.bash -x
很有趣,但不包括时间戳或其他时间信息.
Pau*_*ce. 47
您可以设置PS4
显示时间和行号.这样做不需要安装任何实用程序和工作,而无需将stderr重定向到stdout.
对于这个脚本:
#!/bin/bash -x
# Note the -x flag above, it is required for this to work
PS4='+ $(date "+%s.%N ($LINENO) ")'
for i in {0..2}
do
echo $i
done
sleep 1
echo done
Run Code Online (Sandbox Code Playgroud)
输出如下:
+ PS4='+ $(date "+%s.%N ($LINENO) ")'
+ 1291311776.108610290 (3) for i in '{0..2}'
+ 1291311776.120680354 (5) echo 0
0
+ 1291311776.133917546 (3) for i in '{0..2}'
+ 1291311776.146386339 (5) echo 1
1
+ 1291311776.158646585 (3) for i in '{0..2}'
+ 1291311776.171003138 (5) echo 2
2
+ 1291311776.183450114 (7) sleep 1
+ 1291311777.203053652 (8) echo done
done
Run Code Online (Sandbox Code Playgroud)
这假设GNU日期,但您可以将输出规范更改为您喜欢的任何内容或与您使用的日期版本匹配的任何内容.
注意:如果您希望在不修改现有脚本的情况下执行此操作,则可以执行以下操作:
PS4='+ $(date "+%s.%N ($LINENO) ")' bash -x scriptname
Run Code Online (Sandbox Code Playgroud)
在即将到来的Bash 5中,您将能够保存分叉date
(但是您可以获得微秒而不是纳秒):
PS4='+ $EPOCHREALTIME ($LINENO) '
Run Code Online (Sandbox Code Playgroud)
Emi*_*Sit 10
您可以将正在运行的输出-x
通过管道传输到收到每条线时加时间戳的内容.例如,tai64n
来自djb的daemontools.在一个基本的例子中,
sh -x slow.sh 2>&1 | tai64n | tai64nlocal
Run Code Online (Sandbox Code Playgroud)
这会混淆stdout和stderr,但它确实为所有内容提供了时间戳.然后,您必须分析输出以查找昂贵的行并将其与您的源相关联.
你也可以想象使用strace
有用的.例如,
strace -f -ttt -T -o /tmp/analysis.txt slow.sh
Run Code Online (Sandbox Code Playgroud)
这将生成一份非常详细的报告,其中包含大量的计时信息/tmp/analysis.txt
,但是在每个系统的呼叫级别,这可能过于详细.