PDA

View Full Version : Help with a shell script?




msjones
Apr 15, 2011, 02:12 PM
Evening all,

I am having a little fun with some shell scripting but I am stuck creating a loop. Hopefully someone can help. Here is my script:

#!/bin/bash

FORTUNE=`fortune -i`
COUNT=`echo $FORTUNE | wc -m`

if [ $COUNT -lt 140 ]
then
while true; do
echo "$FORTUNE" && exit
done
fi

As you can see if $FORTUNE is less than 140 characters it will echo the text and then close. If $FORTUNE is greater than 140 it will just close. What I want it to do is if its greater than 140 to re-run again until its less than 140, echo and then exit.

Hope this makes sense?



chown33
Apr 15, 2011, 02:37 PM
As you can see if $FORTUNE is less than 140 characters it will echo the text and then close. If $FORTUNE is greater than 140 it will just close. What I want it to do is if its greater than 140 to re-run again until its less than 140, echo and then exit.

According to that description, the if must be inside a loop, not outside it. So structurally you need this:
while ..
..
if ..
...
fi
..
done
but your posted code has this:
if ..
while ..
..
done
fi

msjones
Apr 15, 2011, 02:47 PM
OK So ive changed to this:

#!/bin/bash

FORTUNE=`fortune -i`
COUNT=`echo $FORTUNE | wc -m`

while true; do
if [ $COUNT -lt 140 ]
then
echo "$FORTUNE" && exit
fi
done


This will post if $FORTUNE is less than 140 but if its greater than 140 it just hangs?

Mav3067
Apr 15, 2011, 03:17 PM
OK So ive changed to this:

#!/bin/bash

FORTUNE=`fortune -i`
COUNT=`echo $FORTUNE | wc -m`

while true; do
if [ $COUNT -lt 140 ]
then
echo "$FORTUNE" && exit
fi
done


This will post if $FORTUNE is less than 140 but if its greater than 140 it just hangs?

Thats because you have no exit condition if the count is not less than 140...you have an infinite loop.

msjones
Apr 15, 2011, 03:25 PM
This is where I am at currently:

#!/bin/bash

FORTUNE=`fortune -i`
COUNT=`echo $FORTUNE | wc -m`

while [ $COUNT -lt 140 ]
do
echo "$FORTUNE"
exit 0
done


This works fine, but still can't get it to loop if $COUNT is greater than 140. I have scoured google and I can only find that when a while loop hits its false it will exit?

itickings
Apr 15, 2011, 03:40 PM
This works fine, but still can't get it to loop if $COUNT is greater than 140. I have scoured google and I can only find that when a while loops hits its false is will exit?

Yeah, thats the point. You use a while loop to do something as many times it takes until the condition is met.

If you think about it, what is it that you want to repeat and update?
Put that inside the loop. (You may need to put it before the loop as well to have a value to start with to get into the loop)

What do you only want to do one time?
Put that outside the loop.

chown33
Apr 15, 2011, 03:40 PM
This is where I am at currently:

#!/bin/bash

FORTUNE=`fortune -i`
COUNT=`echo $FORTUNE | wc -m`

while [ $COUNT -lt 140 ]
do
echo "$FORTUNE"
exit 0
done


This works fine, but still can't get it to loop if $COUNT is greater than 140. I have scoured google and I can only find that when a while loops hits its false is will exit?

You won't find the answer by googling. You have a structural logic problem, not a shell syntax problem.

In your loop, does the value of FORTUNE ever change? Does the value of COUNT ever change?

If the values don't change within the loop, then the conditions that cause the loop to loop won't change. A loop with unchanging loop conditions is the definition of an infinite loop. You effectively have:
while [ unchanging condition ]
do
echo unchanging value
exit 0 ## always executes, because && conditional removed
done

So where are the statements that cause FORTUNE and COUNT to change? Where should they be placed if you want them to occur within the loop?

msjones
Apr 15, 2011, 06:00 PM
Yeah the value changes. Fortune is a Linux command line application that gives a fortune every time it's run. I want to post this output to twitter and as you may know twitter only takes 140 characters.

So when my script runs if the fortune is less than 140 it will post. If it's greater than 140 I want it to keep running the command till a fortune less than 140 is given then post it.

For the time being I am just echoing the fortune, eventually I will be using the twidge application to post to twitter, which I already have set up and working, I'll just ammed the script once I get the loop sorted.

jiminaus
Apr 15, 2011, 06:17 PM
Yeah the value changes. Fortune is a Linux command line application that gives a fortune every time it's run. I want to post this output to twitter and as you may know twitter only takes 140 characters.

So when my script runs if the fortune is less than 140 it will post. If it's greater than 140 I want it to keep running the command till a fortune less than 140 is given then post it.

For the time being I am just echoing the fortune, eventually I will be using the twidge application to post to twitter, which I already have set up and working, I'll just ammed the script once I get the loop sorted.

So you need to actually run fortune inside the loop. The loop would run fortune until it gets an appropriate one. Then after the loop, you output it.

pilotError
Apr 15, 2011, 06:31 PM
What is the exit condition?


#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+1

** Your Code Here **
done


If I remember correctly, fortune just does a random line search on a text file in the system somewhere. If you run it in a loop, it will run forever, and you'll be tweeting the same crap over and over. The Twitterverse will hunt you down and beat you! LOL

chown33
Apr 15, 2011, 06:39 PM
Yeah the value changes. Fortune is a Linux command line application that gives a fortune every time it's run. I want to post this output to twitter and as you may know twitter only takes 140 characters.

I don't think you're walking through your code. You should sit down with a paper and pencil and walk through it while pretending to be the computer.

I do not mean "Imagine walking through it". I mean actually walk through it one line at a time, and actually write out what happens at each command line step. Then answer this question: Within the loop, when and where does the value of FORTUNE or COUNT change? If you can't find that place, then the problem and solution should be obvious.

In olden days this was called "bench-checking your work".

Bill McEnaney
Apr 16, 2011, 12:36 AM
This is where I am at currently:

#!/bin/bash

FORTUNE=`fortune -i`
COUNT=`echo $FORTUNE | wc -m`

while [ $COUNT -lt 140 ]
do
echo "$FORTUNE"
exit 0
done


This works fine, but still can't get it to loop if $COUNT is greater than 140. I have scoured google and I can only find that when a while loop hits its false it will exit?
What happens when you replace "-lt" with "-le"?

msjones
Apr 16, 2011, 11:37 AM
Thanks for all the responses guys, will be having another crack at this later on today. Will post back when I've sorted it :)

Finally got it working with an infinite loop:

FORTUNE=`fortune`

while true; do
FORTUNE=`fortune`
if [ "${FORTUNE:140}" == "" ]; then
break
fi
done

echo $FORTUNE


Thanks for all the input :)

Bill McEnaney
Apr 16, 2011, 02:26 PM
Finally got it working with an infinite loop:

FORTUNE=`fortune`

while true; do
FORTUNE=`fortune`
if [ "${FORTUNE:140}" == "" ]; then
break
fi
done

echo $FORTUNE


Thanks for all the input :)
Can the if-condition become the loop condition, so you won't need to break out of an infinite loop? Can you replace "while true; do" with "while [ "${FORTUNE:140}" == "" ];" or with something like it? I usually don't write bash scripts, since I'm more familiar with tcsh.

Bill

msjones
Apr 16, 2011, 03:29 PM
Can the if-condition become the loop condition, so you won't need to break out of an infinite loop? Can you replace "while true; do" with "while [ "${FORTUNE:140}" == "" ];" or with something like it? I usually don't write bash scripts, since I'm more familiar with tcsh.

Bill

I tried this originally and the script will not run, it just returns a blank.

chown33
Apr 16, 2011, 04:47 PM
Can the if-condition become the loop condition, so you won't need to break out of an infinite loop? Can you replace "while true; do" with "while [ "${FORTUNE:140}" == "" ];" or with something like it?l

Why?

Efficiency? It's a shell-script, for bog's sake.

Besides, you'd have to reverse the conditional to !=, or use the until keyword in bash.

EDIT:
Doing a little research on 'fortune' programs, it appears the most common implementations have command-line options for the length of the fortune chosen. The options -s -n 140 appear to limit fortune's output to only those epigrams shorter than 140 chars.

So as an exercise in learning shell scripting, this may have been useful. As an exercise in reading man pages before embarking on projects, maybe not so much.