1829187 Members
17664 Online
109986 Solutions
New Discussion

Scripting

 
SOLVED
Go to solution
Andrew Porter_1
Occasional Contributor

Scripting

Can you assign stderr to a variable?
12 REPLIES 12
James R. Ferguson
Acclaimed Contributor

Re: Scripting

Hi Andrew:

This works:

# X=`print -u2 "hello andrew" 2>&1`

Regards!

...JRF...
A. Clay Stephenson
Acclaimed Contributor

Re: Scripting

You can do something like this:

XX=$(my_command 2>&1)

${XX} will then contain both stdout's and stderr's output but to get them separately is a bit more difficult.

ERRS=""
TFILE=/var/tmp/XX${$}.err

XX=$(my_command 2>${TFILE})
if [[ -s ${TFILE} ]]
then
ERRS=$(cat ${TFILE})
fi
rm -f ${TFILE}

Now ${XX} contains the output of stdout and ${ERRS} contains that of stderr







If it ain't broke, I can fix that.
Andrew Porter_1
Occasional Contributor

Re: Scripting

Didn't work

Here what I am tring to do...

I am trying to put the elaspe time of a command into a variable

I was using

time {command}

to get the elaspe time
Jordan Bean
Honored Contributor
Solution

Re: Scripting


Do you mean that you want to capture stderr to a variable? Yes.

Using command substitution:

errormsg=$(command 2>&1 >/dev/ull)

The order of redirection is important! You first want to reassign stderr to what stdout is using, then redirect stdout to null if you don't it.


Using pipes and the shell's read command:

( command | read ouput ) 2>&1 | read error

This pipeline often confuses people. The grouping with parans is important because you want the stderr of the command to pass to the second read, not through first.


James R. Ferguson
Acclaimed Contributor

Re: Scripting

Hi (again):

OK, thy this:

# time date 2> /tmp/mytime
# X=`# echo $X

Regards!

...JRF...
Darrell Allen
Honored Contributor

Re: Scripting

Yes you can.

V=$(ls junk 2>&1 >V.out)
In this case, $V contains stderr from "ls junk" and V.out contains stdout.

You could capture stderr and stdout both to the variable:
V=$(ls junk 2>&1)

Lastly, to capture stderr in a variable and send stdout to the screen:
V=$(ls junk 2>&1 >$(tty))

Darrell
"What, Me Worry?" - Alfred E. Neuman (Mad Magazine)
Darrell Allen
Honored Contributor

Re: Scripting

Oops! I meant to say "If you want to send STDOUT to the bit bucket".

Darrell
"What, Me Worry?" - Alfred E. Neuman (Mad Magazine)
Darrell Allen
Honored Contributor

Re: Scripting

For your example:

etime=(time {command} 2>&1 >$(tty))
echo $etime

If you want to send stderr to the bit bucket:
etime=(time {command} 2>&1 >/dev/null)

Darrell
"What, Me Worry?" - Alfred E. Neuman (Mad Magazine)
Darrell Allen
Honored Contributor

Re: Scripting

That's weird! My "Oops" reply is posted before my "For your example" reply.

I'll have to point this out to Dan (the forums admin).

By the way, welcome to the forums Andrew. It's the best (even if there's been a few problems today with the site upgrade).

Darrell
"What, Me Worry?" - Alfred E. Neuman (Mad Magazine)
Andrew Porter_1
Occasional Contributor

Re: Scripting

Thanks for all your help guys heres what I've come up with...



t=$(time {Command} 2>&1 >/dev/null|grep real|awk '{print $2}')

Thanks again
Jordan Bean
Honored Contributor

Re: Scripting


You can drop this grep this way:

t=$(time command 2>&1 >/dev/null | awk '$1~/^real$/{print $2}')

Or you can capture all times this to any array:

set -A t $(time command 2>&1 >/dev/null | awk '{print $2 $4 $6}')
echo real $t
echo all ${t[@]}
echo real ${t[0]} user ${t[1]} sys ${t[2]}

James R. Ferguson
Acclaimed Contributor

Re: Scripting

Hi (again) Andrew:

Another way of capturing just the timing statistics was shown in my second post. All three metrics are assigned to the variable as a simple string.

Regards!

...JRF...