LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 12-05-2012, 02:16 PM   #1
towardstheedge
LQ Newbie
 
Registered: Nov 2012
Posts: 6

Rep: Reputation: Disabled
Bash- file names with associated file content


I am working on another optional project for my Linux class.

The basic idea is a bucket brigade. Two scripts are working together to spin off a variable number of instances of a process that hands a file from one to the next... one of the processes generates the bucket files with a random number 1 - 5 for "gallons" another interacts with the "fire" file. The rest are just handing the content of the bucket files down the line.

The part I am having trouble with is generating a report on the status of the whole thing while it is still running.

I want to be able to list the current bucket.* files that exist and the contents of them. They will each only contain a random number between 1 and 5.

It seems like there should be a tool that does this sort of thing simply but I don't know what it would be.

I got close with this:
Code:
ls | grep bucket. > .current.buckets
cat bucket.* > .bucket.contents

echo "The current active buckets and contents:"
paste .current.buckets .bucket.contents | tr '\t' '\n'
The problem with this is I can't be sure that grep and cat are listing the file name/content in the same order. I can generate an output with this which looks like what I want but I want it to be accurate.

Last edited by towardstheedge; 12-05-2012 at 02:18 PM.
 
Old 12-05-2012, 06:49 PM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,470
Blog Entries: 54

Rep: Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901
Quote:
Originally Posted by towardstheedge View Post
The part I am having trouble with is generating a report on the status of the whole thing while it is still running.
It would have been more interesting if you would have listed the actual scripts you used...


Quote:
Originally Posted by towardstheedge View Post
I want to be able to list the current bucket.* files that exist and the contents of them. They will each only contain a random number between 1 and 5.
If you assert a single bucket is passed along the line (only one "bucket" file exists in the directory) then you could:
Code:
BUCKETS=0; GALLONS=0
..
if [ -f ./bucket ]; then
 ((BUCKETS++))
 CONTENT=$(cat ./bucket)
 GALLONS=$[${GALLONS}+$CONTENT]
else
 echo "Oi! Where's me bucket?"
fi
if there's multiple buckets and you have to "pass" them in numeric order (bucket.001, bucket.002)
Code:
incr() {  ((BUCKETS++)); GALLONS=$[${GALLONS}+$1]; }
find . -type f -name bucket.\*|sort -n|while read BUCKET; do
 CONTENT=$(cat ./bucket); incr $CONTENT
done
and somewhere at the end
Code:
echo "Passing ${BUCKETS} buckets containing ${GALLONS}"
*BTW unless it's a hard requirement actual bucket files shouldn't be necessary: one script, or a script consisting of several functions, could supply another script or function with bucket names and contents as arguments.
 
Old 12-05-2012, 09:59 PM   #3
towardstheedge
LQ Newbie
 
Registered: Nov 2012
Posts: 6

Original Poster
Rep: Reputation: Disabled
Well I certainly can post the scripts as they are. I am new at this so they are probably not extremely clear or the best way of doing things... But I have got them running fairly well except for the one hitch. I could actually leave it off and just report the number of bucket files there are and which ones they are easily. But I wanted to add the content of each bucket file to the report.

The brig script is the primary script. The passer script is used by the brig script to instantiate passer processes.

I realize these are kinda sloppy... I didn't really start with a plan but just built in one feature at a time. There are some artefacts from testing still in there. I know the variables are a bit sloppy too. I didn't know how many I was going to use. I got a bit carried away with sending errors to /dev/null. When running the script with large numbers of passers and big fire values many processes run out of order and it really wasn't important to know about the errors when it still worked. I also wanted to make sure all the extra files were removed so I built in quite a bit of redundancy, especially with removing the buckets.

brig:
Code:
#!/bin/bash

#brig
#towardstheedge
#dec 2012

#user defines a fire
#user defines number of passers
#passers put out fire

if [[ "$2" = *[!0-9]* ]];
then
echo "The second argument may only contain digits"
exit
fi
#$2 must be empty or contain only digits
#to pass this point

case "$1" in

fire)
if [ -z "$2" ];
then
echo Please provide a fire size
echo 'exe: brig fire 10'
else
echo "$2" > .fire.size
echo "A fire of $2 intensity has started"
fi
;;

alarm)

rm .report.pas.* 2> /dev/null

if [ -z "$2" ];
then
echo Please provide the number of passers
echo 'exe: brig alarm 5'

elif [ "$2" -lt 2 ];
then
echo "There needs to be more than one passer"

else

passvar="$2"
export totalpass="$2"
#passers check exported variable to see if they
#are high number

touch .keep.passing

echo "$totalpass Passers have been activated"
while [ "$passvar" -gt 0 ];
do

bash passer "$passvar" &
((passvar--))
done
fi
;;

status)

firenow=0

clear
echo "Report of situation as of"
echo $(date)

if  [ -e .fire.size ];
then
firenow=$(cat .fire.size)
fi

if [ "$firenow" -gt 0 ];
then
echo "The fire is blazing with $firenow intensity"
else
echo "No fire is active"
fi

if [ -e .keep.passing ];
then

touch .passers.pause
sleep 3

ls | grep bucket. > .current.buckets
cat bucket.* > .bucket.contents

echo "The current active buckets and contents:"
paste .current.buckets .bucket.contents | tr '\t' '\n'

rm .current.buckets
rm .bucket.contents
rm .passers.pause

else

echo "There are no buckets currently active"

fi

;;

quit)
rm .keep.passing 2> /dev/null
sleep 1
rm .fire.size 2> /dev/null
rm bucket.* 2> /dev/null

if [ -e .report.pas.1 ];
then
cat .report.pas.* >> .unified.report
fi

clear
echo 'Generating Report for this session'
sleep 3
cat .unified.report | more
else
echo "No reports exist at this time"
fi
;;

*)
echo 'Usage: brig [fire (n)|alarm (n)|status|report|quit]'
esac

passer:
Code:
#!/bin/bash

#passer
#towardstheedge
#dec 2012

#creates the passer scripts
#used with brig script

mybuckets=0
mywater=0
#initializing variables for reporting
#keeping track of totals for each passer

case "$1" in
#case structure assigns behavior of passer instance
#3 types of passers accounted for
#passer at water - passer at fire - passers in between

$(( passnum = totalpass )) )
#if exported variable from brig = local passnum variable
#then the passer is the end of the line (high number)
#echo "Passer $passnum has arrived at the water"

while [ -e .keep.passing ];
do

if [ -e .passers.pause ];
then
sleep 1
else

   if [ ! -e bucket.$1 ];
   then
   gallons=$((RANDOM%5+1))
   echo "$gallons" > bucket.$1
   ((mybuckets++))
   mywater=$(($mywater+$gallons))
#   echo "Passer $totalpass fills a bucket with $gallons gallons"
   fi
fi
done
;;
#above is high num passer at water

1)
#echo "Passer 1 has arrived at the fire"
while [ -e .keep.passing ];
do

if [ -e .passers.pause ];
then
sleep 1
else

   if [ -e bucket.2 ];
   then
   fire1=$(cat .fire.size) 2> /dev/null
   water3=$(cat bucket.2) 2> /dev/null
   rm bucket.2
   ((mybuckets++))
   mywater=$(($mywater+$water3))
   fire2=$(($fire1-$water3))
   echo "$fire2" > .fire.size
#   echo "Passer 1 takes bucket of $water3 gallons from passer 2"
#   echo "Passer 1 dumps $water3 gallons of water on the fire"
#   echo -e  "\e[1;33mFire has been\
# reduced to a level $fire2 fire\e[00m"

        if [[ "$fire2" -le 0 && -e .keep.passing ]];
        then
        rm .keep.passing
        rm .fire.size
        echo "Fire is out"
        fi
   fi
fi
done
;;
#above is passer 1 always at fire

*)
#echo "Passer $1 is in position"

takebucket=$(($1+1))

while [ -e .keep.passing ];
do

if [ -e .passers.pause ];
then
sleep 1
else

   if [ -e bucket.$takebucket -a ! -e bucket.$1 ];
   then
   water5=$(cat bucket.$takebucket 2> /dev/null)
   rm bucket.$takebucket 2> /dev/null
   ((mybuckets++))

    if [ ! -z $water5 ];
    then
      mywater=$(($mywater+$water5)) 2> /dev/null
    fi
#strange errors occur with high values of fire/passers
#with fire size 300 and 20 passers I had several errors
#saying that $water5 contained no value
    echo "$water5" > bucket.$1
#   echo "Passer $1 takes bucket with $water5 gallons"
#   echo "from passer $takebucket"
#   sleep $1
   fi
fi
done

#above is all other passers
#not concerned with invalid $1 because
# $1 is handed to passer directly from brig
esac

rm bucket.* 2> /dev/null

echo '......................' >> .report.pas.$1
echo "For fire ending at" >> .report.pas.$1
echo $(date) >> .report.pas.$1
echo "Passer $1 handled $mybuckets buckets"\
 >> .report.pas.$1
echo "Passer $1 handled $mywater gallons of water"\
 >> .report.pas.$1
echo '......................' >> .report.pas.$1


So what I want is to be able to type "$ brig status" while the passers are still passing bucket files and have information about which buckets are active at the time and what they have in them. One or the other piece of information is easy to do but getting them to work together is what I can't figure out.
 
Old 12-06-2012, 05:36 AM   #4
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,470
Blog Entries: 54

Rep: Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901Reputation: 2901
Quote:
Originally Posted by towardstheedge View Post
So what I want is to be able to type "$ brig status" while the passers are still passing bucket files
Seeing you already have case statements to pass arguments the only thing you need to do is add a "status)" one that displays your report.
 
Old 12-06-2012, 12:59 PM   #5
towardstheedge
LQ Newbie
 
Registered: Nov 2012
Posts: 6

Original Poster
Rep: Reputation: Disabled
Ya I don't know what happened. I was copy-pasting several lines at a time from nano because I don't know how to copy an entire nano file content to clipboard, I must have missed some lines... I do have a status case set up. Edit: oh wait, it is in there above the quit case below the alarm case. But it is so sloppy I couldn't even find it for a while lol. Obviously I have a lot of work to do learning to keep things a bit more organized.

Anyway, I was able to get what I wanted for my program with some help from my professor. The code that did what I want is:

Code:
for bucket in $(ls bucket.?)
do

echo -n "Bucket: $bucket contains --"
echo "$(cat $bucket) gallons"
done
... just in case someone else can use the solution sometime.

Last edited by towardstheedge; 12-06-2012 at 01:07 PM.
 
  


Reply

Tags
bash, file, script


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
bash script for specific file names arman Programming 5 02-10-2012 04:10 AM
Bash: bash file names are different than openbox trash file names whatthefunk Programming 4 02-15-2011 01:52 AM
[SOLVED] Bash file names with spaces alex1986 Programming 5 07-26-2010 09:47 PM
Add file content to a variable (bash)? LinuxSeeker Programming 4 12-19-2005 01:41 PM
Bash crashes ? File names with () and spaces Danodare Slackware 1 02-27-2004 02:50 PM


All times are GMT -5. The time now is 09:20 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration