skip to Main Content

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


  1. This Shellcheck-clean Bash code demonstrates one way to do what you want:

    #! /bin/bash -p
    
    ls_time=$({ time ls; } 2>&1)
    ls_output=${ls_time%$'n'real*}
    time_output=${ls_time:${#ls_output}+1}
    
    X=${time_output%%$'n'*}
    v=${ls_output%$'n'}
    
    declare -p X v
    
    • ls_time=$({ time ls; } 2>&1) captures the entire output (both standard output and standard error) of time ls into the variable ls_time.
    • ls_output=${ls_time%$'n'real*} sets ls_output to the full output of ls. It does that by removing the shortest string at the end of $ls_time that begins with a newline followed by the string real. 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 from time ls (excluding the leading newline) into time_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'*} sets X to the timing output lines from time ls (excluding the leading newline) with everything after the first newline (the newline at the end of the real ... line) removed.
    • v=${ls_output%$'n'} sets v to the output of ls with the final newline (if any (the output could be empty)) removed. That makes it equivalent to v=$(ls).
    • declare -p X v outputs the values of the X and v 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.
    Login or Signup to reply.
  2. You can use a temporary file :

    tmp=$(mktemp)
    v=$({ time ls; } 2>$tmp)
    X=$(cat $tmp)
    rm $tmp
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search