Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I need to adjust my shell script and write to $log multiple times. Opening and closing the file repeatedly will cause an increase in runtime.

How can I write everything at once to the file, including all echo statements defined in my script?

#!/bin/sh
log="loadlog.log"

for i in {1..10}
do
   n=$((100*$i))
   echo "## Users=$i  requests=$n ##" >> $log     
   ab -n $n -c $i  http://mainserver.com/index.html  >>  $log
   ssh root@mainserver cat /proc/loadavg >> $log
   echo "======" >> $log
done
share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

I’m not sure, but I guess you want to open the log file for writing just once, do you?

If so, you need to use a sub-shell, output to the STDOUT and, outside, send it to the log file.

#! /bin/bash
log="loadlog.log"

(
for i in {1..10}; do
    n=$((100*$i))

    echo "## Users=$i  requests=$n ##"

    ab -n $n -c $i  http://mainserver.com/index.html

    ssh root@mainserver cat /proc/loadavg

    echo "======"
done
) >> $log

As well, I recommend you to do something with your code-style—it’s unreadable. And, you need to use #!/bin/bash because you use bash-specific constructs in the loop.

share|improve this answer
    
perfect , this what i was looking for , thanks –  Mohamed Ahmed Feb 10 '13 at 9:27
add comment

Using the exec command with a redirection applies that redirection to the whole script. So, you could redirect all stdout to append to the log file:

#!/bin/sh
log="loadlog.log"

exec 1>>$log

for i in {1..10}
do
   n=$((100*$i))
   echo "## Users=$i  requests=$n ##"
   ab -n $n -c $i  http://mainserver.com/index.html
   ssh root@mainserver cat /proc/loadavg
   echo "======"
done

If you still want to emit stuff to the user, you can make a copy of stdout first:

#!/bin/sh
log="loadlog.log"

exec 3>&1     # file descriptor 3 is now stdout
exec 1>>$log

for i in {1..10}
do
    # ...
   echo "======"                  # this line will be appended to the log file
   echo "completed loop $i" >&3   # this line will be displayed to user
done

exec 1>&3     # fd 1 restored to stdout
exec 3>&-     # fd 3 is closed

echo "stdout now restored"
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.