shell脚本本身**(真的)的优雅方式是什么?

Oli*_*ver 3 bash benchmarking

我有一个bash脚本,称之为Exp,它执行计算实验,我希望得到结果

time Exp
Run Code Online (Sandbox Code Playgroud)

在脚本本身内:首先它需要始终完成(并且依赖于键入"time Exp"是不够的 - 对于您(或用户!!)需要它的关键情况,它将被遗忘),第二脚本Exp本身需要将其存储在文件中.

编写一个包装器脚本(调用"time Exp")似乎使得由于参数的破坏和time-command的输入/输出而无法使用Exp.

但实际上所需要的只是访问Exp本身的数据,该记录只能通过时间打印的通用记录(也可以通过ps访问)!这就是为什么我要求一个"优雅"的解决方案,而不仅仅是首先以某种方式存储Exp中的日期,最后,在退出之前,计算差异.但只是模拟时间命令在Exp中的作用.我认为这在许多其他情况下会有用.

Jon*_*ler 7

由于POSIX定义了时间实用程序来将其结果写入标准错误,因此您必须注意的唯一技巧是bash内置time行为略有不同.

$ time sleep 1

real    0m1.004s
user    0m0.001s
sys     0m0.002s
$ time sleep 1 2>xyz

real    0m1.005s
user    0m0.001s
sys     0m0.003s
$ (time sleep 1) 2>xyz
$ cat xyz

real    0m1.005s
user    0m0.001s
sys     0m0.002s
$ /usr/bin/time sleep 1 2>xyz
$ cat xyz
        1.00 real         0.00 user         0.00 sys
$ 
Run Code Online (Sandbox Code Playgroud)

测试显示在MacOS X 10.7上.请注意time命令的内置和外部版本之间输出格式的差异.另请注意,在子shell格式中,内置time是正常重定向的,但在简单的情况下,在内置后重定向输出time不会将输出发送到标准错误的其余部分转到的相同位置.

因此,这些观察结果允许您编写优雅的脚本.可能最简单的方法是将现有脚本包装为函数,然后通过内置函数调用该函数time.

原始剧本

# This is what was in the Exp script before.
# It echoes its name and its arguments to both stdout and stderr
echo "Exp $*"
echo "Exp $*" 1>&2
Run Code Online (Sandbox Code Playgroud)

修改过的脚本

log=./Exp.log

Exp()
{
    # This is what was in the Exp script before.
    # It echoes its name and its arguments to both stdout and stderr
    echo "Exp $*"
    echo "Exp $*" 1>&2
}

(time Exp "$@") 2>> $log
Run Code Online (Sandbox Code Playgroud)

注意"$@"在调用Exp函数时要小心使用,以保留在命令行上传递的单独参数,以及$*在函数内部同样故意使用(它会丢失单独的参数,但仅用于说明目的).

可能的问题

唯一的问题是原始命令的错误输出也与定时信息一起发送到同一个日志文件.这可以解决,但涉及棘手的多重重定向,比帮助更容易混淆.然而,为了记录,这很好地工作:

log=./Exp.log

Exp()
{
    # This is what was in the Exp script before.
    # It echoes its name and its arguments to both stdout and stderr
    echo "Exp $*"
    echo "Exp $*" 1>&2
}

exec 3>&2

(time Exp "$@" 2>&3 ) 2>> $log
Run Code Online (Sandbox Code Playgroud)