I am measuring the command duration by the tool time
, but the result of the command is hidden. For example I am measuring the duration of find
or ls
and I see the duration, but not a list of files.
v=&&X=$((time v=$(ls)) 2>&1 | grep real)&&echo $X&&echo "$v"
u@debian:~$ v=&&X=$((time v=$(ls)) 2>&1 | grep real)&&echo $X&&echo "$v"
real 0m0.004s
u@debian:~$
I would like both X
and v
variables be reachable. X
schould return real 0m0.004s
and v
schould return a list of files.
How to measure the duration of a command and get the result of the command?
2
Answers
This Shellcheck-clean Bash code demonstrates one way to do what you want:
ls_time=$({ time ls; } 2>&1)
captures the entire output (both standard output and standard error) oftime ls
into the variablels_time
.ls_output=${ls_time%$'n'real*}
setsls_output
to the full output ofls
. It does that by removing the shortest string at the end of$ls_time
that begins with a newline followed by the stringreal
. See Removing part of a string (BashFAQ/100 (How do I do string manipulation in bash?)) for an explanation of${ls_time%...}
.time_output=${ls_time:${#ls_output}+1}
puts the timing output lines fromtime ls
(excluding the leading newline) intotime_output
. See Extracting parts of strings (BashFAQ/100 (How do I do string manipulation in bash?)) for an explanation of${ls_time:...}
.X=${time_output%%$'n'*}
setsX
to the timing output lines fromtime ls
(excluding the leading newline) with everything after the first newline (the newline at the end of thereal ...
line) removed.v=${ls_output%$'n'}
setsv
to the output ofls
with the final newline (if any (the output could be empty)) removed. That makes it equivalent tov=$(ls)
.declare -p X v
outputs the values of theX
andv
variables in a safe and unambiguous way.echo $var
is not safe.echo "$var"
is better, but still not fully safe. See the accepted, and excellent, answer to Why is printf better than echo?.printf '%sn' "$var"
is safe, but can be ambiguous if$var
contains newline characters.You can use a temporary file :