简体   繁体   中英

Bash variable expansion can't be combined with time command

I was writing a small shell script in bash to measure the speed of several executables using the time command. Because I wanted to time several different programs, to avoid repeating myself I saved the time command and the format string I wanted and tried to use variable expansion (testing the performance of ls as an example):

#!/usr/bin/env bash

timer="/usr/bin/time -f 'elapsed time: %E' --"
$timer ls 1>/dev/null

The time command is supposed to use the -- to separate its options (in this case a format string) from the command it's supposed to time. However, in this script time insists on trying to execute my format string and fails with

/usr/bin/time cannot run time:: No such file or directory
Command exited with non-zero status 127
'elapsed

But if I put the whole command on one line with no variable expansion it correctly recognizes the format string and executes ls :

#!/usr/bin/env bash

/usr/bin/time -f 'elapsed time: %E' -- ls 1>/dev/null

produces "elapsed time: 0:00.00"

I ended up just typing out the whole command on each line to get it to run, but I was curious if anyone could explain why variable expansion doesn't work here.

The data in $timer is split on $IFS (spaces), and used as separate arguments. It is not expanded and then evaluated as bash code.

Your command $timer ls is therefore equivalent to:

"/usr/bin/time" "-f" "'elapsed time:" "%E'" "--" "ls"

The correct way to do this in your case is using a function:

timer() {
  /usr/bin/time -f 'elapsed time: %E' -- "$@"
}
timer ls

PS: This problem is automatically pointed out by shellcheck .

You need to use a BASH array to store command line:

timer=(/usr/bin/time -f 'elapsed time: %E' --)
"${timer[@]}" ls

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM