For loop in bash - Direct output to two files

Thread Tools Search this Thread
Top Forums Shell Programming and Scripting For loop in bash - Direct output to two files
# 1  
Old 04-21-2017
For loop in bash - Direct output to two files

Hello all,

i have a code in which when doing a for loop, i need to direct the output to two files, one just a single output, the other to always append (historical reasons).

So far i managed to do the following, which is working, but am still considering it as "dirty".

INTERFACE_NAME=`$SNMP -v2c -c $COMMUNITY $HOST ifDescr | awk '{print$4}'`
for int in $INTERFACE_NAME
inOct1=`grep "$int " $HOMEDIR/cron/tmp/$(basename $0 .sh)1 | awk '{print$4}' | tr -d "incoming="`
inOct2=`grep "$int " $HOMEDIR/cron/tmp/$(basename $0 .sh)2 | awk '{print$4}' | tr -d "incoming="`

outOct1=`grep "$int " $HOMEDIR/cron/tmp/$(basename $0 .sh)1 | awk '{print$5}' | tr -d "outgoing="`
outOct2=`grep "$int " $HOMEDIR/cron/tmp/$(basename $0 .sh)2 | awk '{print$5}' | tr -d "outgoing="`

speed=`grep "$int " $HOMEDIR/cron/tmp/$(basename $0 .sh)1 | awk '{print$3}' | tr -d "speed="`
status=`grep "$int " $HOMEDIR/cron/tmp/$(basename $0 .sh)1 | awk '{print$1}' | tr -d "state=" | tr -d "([0-9])"`

#Diff the polls, divided by the interval
if [ $outOct2 -lt 0 ] || [ $outOct1 -lt 0 ] || [ $inOct2 -lt 0 ] || [ $inOct1 -lt 0 ]; then
    echo "Negative numbers not allowed...exiting"
    exit 1

inUsage=`echo $(((inOct2 - inOct1) / TIME_INTERVAL))`
outUsage=`echo $(((outOct2 - outOct1) / TIME_INTERVAL))`

#Convert to bits
inUsage=`echo $((inUsage * 8))`
outUsage=`echo $((outUsage * 8))`

#get usage in percantage
perinUsage=`echo "scale=4;((($inUsage/$speed) * 100))" | bc`
perinUsage=`printf '%.3f\n' $perinUsage`
peroutUsage=`echo $(((outUsage/speed) * 100)) | bc`
peroutUsage=`printf '%.3f\n' $peroutUsage`

echo $DATE "|" $int "|" $speed "|" $status "|" $inUsage "|" $perinUsage "|" $outUsage "|" $peroutUsage
done | tee $OUTPUTDIR/$(basename $0 .sh) | tee -a  $HISTDIR/${DATESTAMP}.$(basename $0 .sh)

#Remove LOCK
rm -f ${LOCKFILE}

As you can see this is the interesting part:
echo $DATE "|" $int "|" $speed "|" $status "|" $inUsage "|" $perinUsage "|" $outUsage "|" $peroutUsage
done | tee $OUTPUTDIR/$(basename $0 .sh) | tee -a  $HISTDIR/${DATESTAMP}.$(basename $0 .sh)

where i need to output to two files.

Is there a way to simplify this by making the for loop output to two files and making the output to not show in the screen?

Thanks in advance for your comments
# 2  
Old 04-21-2017
while true
         echo "Destination one" >&5
         echo "Destination two" >&6
         echo "Destination one again" >&5
 done 5>destone 6>&1 | less

5 and 6 are arbitrary numbers higher than 2, as 0-2 are reserved for stdin/stdout/stderr.
This User Gave Thanks to Corona688 For This Post:
# 3  
Old 04-21-2017
If this one echo statement is the only output I would go indeed for
output=`echo $DATE "|" $int "|" $speed "|" $status "|" $inUsage "|" $perinUsage "|" $outUsage "|" $peroutUsage`
echo "$output" >&5
echo "$output" >&6
done 5>$OUTPUTDIR/$(basename $0 .sh) 6>>$HISTDIR/${DATESTAMP}.$(basename $0 .sh)

Otherwise you need to keep one tee (a dup() can only be done by tee)
done | tee $OUTPUTDIR/$(basename $0 .sh) >>$HISTDIR/${DATESTAMP}.$(basename $0 .sh)

This User Gave Thanks to MadeInGermany For This Post:
# 4  
Old 04-22-2017
Your TIME_INTERVAL variable is not expanded by the shell, so your results may not be the desired ones.
And, I'm not sure I understand why you overwrite the output file again and again in the loop, so only the last one will persist and be available / workable upon.
Instead of running 27 external commands for every single interface, you might want to consider doing it ALL in one awk script like
$SNMP -v2c -c $COMMUNITY $HOST ifDescr |
FNR == NR       {INT[$4]++
FNR == 1        {FC++

$X in INT       {
                 sub (/incoming=/, ""; $4)
                 sub (/outgoing=/, ""; $5)
                 if (($4 < 0) || ($5 < 0))      {print "Negative numbers not allowed...exiting"
                                                 exit 1
                 inOct [$X,FC] = $4
                 outOct[$X,FC] = $5

                 sub (/speed=/, ""; $3)
                 if (!speed[$X]) speed[$X] = $3

                 sub (/state=/, ""; $1)
                 sub /\([0-9]\)/, "", $1)
                 if (!state[$X]) state[$X] = $1
END             {for (i in INT) {inUsage  = (inOct [i,2] - inOct [i,1]) / TI * 8
                                 outUsage = (outOct[i,2] - outOct[i,1]) / TI * 8
                                 TMP = sprintf ("%s|%s|%.f|%s|%.0f|%.3f|%.0f|%.3f\n", DT, i, speed[i], state[i], inUsage, inUsage/speed[i]*100, outUsage, outUsage/speed[i]*100)
                                 print TMP  >  OF
                                 print TMP  >> HF
                                 close (OF)
                                 close (HF)
' - $HOMEDIR/cron/tmp/${FNM}1 $HOMEDIR/cron/tmp/${FNM}2

Define X to be the column the interface name is in (here assumed to be 2). Unfortunately, this is just a vague proposal as there are no data nor data structures known to allow for a decent testing.

Last edited by RudiC; 04-22-2017 at 02:32 PM..
This User Gave Thanks to RudiC For This Post:
# 5  
Old 04-23-2017

@Rudi C. I need to try to that to get the script much "cleaner" as am still not yet happy with the code.
In the meantime i have also tried with the arbitrary echos and all worked fine (both Corona's and MadeInGermany's)
Thanks all for the contribution guys.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

How do I assign the output of a command to a variable within a loop in bash?

In the else of the main if condition . else set lnk = $(readlink -f <path> | cut -d '/' -f7) echo "$lnk" if ] When I run the above on command line , the execution seems to be fine and I get the desired output. But when I try to assign it to a variable within a loop... (12 Replies)
Discussion started by: sankasu
12 Replies

2. Shell Programming and Scripting

Disk Space Script to direct output

Hi, I am working on Sun Solaris 5.10 and want to direct the output from a disk space check script to an output file; #!/bin/bash CURRENT=$(df -k /log/logs | grep /log/logs | awk '{ print $5}' | sed 's/%//g') THRESHOLD=30 if ; then echo "Remaining free space is low" > output.txt else... (10 Replies)
Discussion started by: SSKAAB
10 Replies

3. Shell Programming and Scripting

BASH - Need to echo for loop output to one line

I'm trying to echo the release version of some of our Linux servers. Typically I do these types of things by "catting" a text file with the host names, "ssh-ing" to the host and running my string. This is what I've written for i in `cat versions.txt` ; do echo $i ; ssh $i cat /etc/issue |... (5 Replies)
Discussion started by: lombardi4851
5 Replies

4. Shell Programming and Scripting

Manipulating sed Direct Input to Direct Output

Hi guys, been scratching round the forums and my mountain of resources. Maybe I havn't read deep enough My question is not how sed edits a stream and outputs it to a file, rather something like this below: I have a .txt with some text in it :rolleyes: abc:123:xyz 123:abc:987... (7 Replies)
Discussion started by: the0nion
7 Replies

5. Shell Programming and Scripting

Been working since 25+ hrs: Bash Script to rename files supposedly direct but difficult to execute

:wall::wall::wall: Hi I have horrible script below, need help in renaming ls -l output into new filename format: Desired output: cp -pv original_path/.* newDirectory/owner_of_file.%dd%mm%y.file_extension.first_8_characters_of_original_filename localuser@localuser:~ vi... (3 Replies)
Discussion started by: wolf@=NK
3 Replies

6. Shell Programming and Scripting

Bash: Help with output from a for loop

Hi, Sorry I'm new to shell scripting.. my loop is as follows: let i=0 for item in ${APPSARRAY} do #..some code to get a unique value called $result let i=i+1 done What I want to do is within the for loop, create a comma seperated list: ... (3 Replies)
Discussion started by: mjwoodford
3 Replies

7. Shell Programming and Scripting

how to direct scp output to a file in bash shell or script

I can run this from the command line: scp -i identfile /path/file_to_send remotelogin@remotebox:/path_to_put_it/file_to_send and I get: file_to_send 100% |***************************************************************************| 0 00:00 but if I do: scp -i identfile... (6 Replies)
Discussion started by: NewSolarisAdmin
6 Replies

8. Shell Programming and Scripting

Direct the output of a script to a log file

Hi, I have a script to compare 2 files. file1=$1 file2=$2 num_of_records_file1=`awk ' END { print NR } ' $file1` num_of_records_file2=`awk ' END { print NR } ' $file2` i=1 while do sed -n "$i"p $file1 > file1_temp sed -n "$i"p $file2 > file2_temp diff file1_temp... (5 Replies)
Discussion started by: autosys_nm
5 Replies

9. UNIX for Dummies Questions & Answers

direct output to a file then email it

Ok so i have this script and I dont know how to have the output go to a file and then email that file to someone. #!/bin/ksh print "AL" print "AM" print "AN" print "RL\n" nawk '/PROD/ {print $3, $2}' /home/user/switch_listtest | sort -k1,2 print "End of Report" Thank you in... (2 Replies)
Discussion started by: llsmr777
2 Replies

10. Shell Programming and Scripting

How to direct awk output to expr?

Is there any way to combine the following two statements into one? I can't figure out how to get expr to take input from the output of the awk call - I've tried piping the output of the awk call into the expr call, and tried using a 'Here' document, nothing seems to work. export CNT=`wc -l... (4 Replies)
Discussion started by: jvander
4 Replies
Login or Register to Ask a Question

Featured Tech Videos