Ulrik
Ulrik

Reputation: 1141

Load output from bash time command to a variable

Let's examine my problem in layers:

sleep 3; echo hello

sleeps for three seconds and echoes "hello"

ssh localhost "sleep3; echo hello"

does the same on a remote host over ssh

var=$(ssh localhost "sleep3; echo hello")

does the same but stores "hello" in var

(time var=$(ssh localhost "sleep3; echo hello")) 2>&1

does the same and times it, but since time outputs to stderr, I redirected stderr to stdout, so that I can do this

timer=$((time var=$(ssh localhost "sleep3; echo hello")) 2>&1)

which should make the remote machine wait for 3 seconds, echo "hello" which should be stored on a local machine's variable var, and time the entire process after which the timed value is stored in variable timer.

But unfortunately, var is EMPTY (it works fine in example #3)! For the purpose of my code, it is necessary to store output of ssh in one variable, and ssh execution time in the other, without the use of "more advanced" commands as /bin/time, date, etc... I am sure there is a clever (i.e. shell-only) way of doing this, but I'm not clever enough to figure it out by my self. Any help is greatly appreciated.

Here's a thread that might be useful: [How to store standard error in a variable in a Bash script

Upvotes: 2

Views: 820

Answers (2)

Ulrik
Ulrik

Reputation: 1141

Barmar's answer is good, but it's missing parentheses (timer leaks to stdout). The correct answer would be:

time=$((time ssh localhost "sleep 3; echo hello" &>/tmp/key) 2>&1); key=$(</tmp/key)

which makes the remote machine wait for 3 seconds, echo "hello" which is stored in the local machine's variable var, and time the entire process after which the timed value is stored in variable timer, while doing all that in complete silence.

Upvotes: 0

Barmar
Barmar

Reputation: 781741

Commands run within parentheses, or when doing command substitution, are run in a subshell. Variables in the subshell don't persist after the subshell completes. The simplest solution is to use a file:

timer=$(time ssh localhost "sleep 3; echo hello" 2>&1 >/tmp/var)
var=$(</tmp/var)

Upvotes: 2

Related Questions