Page 1 of 1

Bash/Shell script - make it loop forever??[SOLVED]

Posted: Mon 11 Mar 2013, 03:22
by greengeek
I would like to know how to make a script go back to the beginning and start all over again once it reaches the end.

example:
Lets say I want to use xdotool to move my mousepointer up and down (for no particular reason) I could do this:

#!/bin/sh
xdotool mousemove 10 10
xdotool mousemove 10 30
xdotool mousemove 10 10
xdotool mousemove 10 30
xdotool...etc etc ad infinitum.

or, I could just use the first two lines and repeat them somehow. Is there a simple string that I can add to the bottom of a script to say "return to top line and repeat" so that the script will run forever?

eg:
#!/bin/sh
xdotool mousemove 10 10
xdotool mousemove 10 30
repeat.

Posted: Mon 11 Mar 2013, 04:08
by puppyluvr
:D Hello,
Look at
case
*
*
*
esac

Or

x=10
if x <11 then
*
fi

In both cases the code will loop until "case" or "if" are met..

I have a slideshow code which displays random (*) images, and since there is always another random image it continues on...

Posted: Mon 11 Mar 2013, 06:17
by technosaurus
there is no goto.

here is the most concise infinite loop I can think of

Code: Select all

while :; do
#infinite loop unless "break" is called
done

Posted: Mon 11 Mar 2013, 08:28
by simargl
.

Posted: Mon 11 Mar 2013, 08:48
by greengeek
puppyluvr wrote: case
*
*
*
esac
Not sure if I understood this correctly? I did the following but it did not seem to work:

Code: Select all

#!/bin/sh
case
xdotool mousemove 20 20 
sleep 3
xdotool mousemove 20 40
sleep 1
esac

and I couldn't get this to work either:

Code: Select all

#!/bin/sh
x=10
if x <11 then
xdotool mousemove 20 20 
sleep 3
xdotool mousemove 20 40
sleep 1
 fi 
technosaurus wrote: while :; do
#infinite loop unless "break" is called
done
Yep, that works, thanks.

Posted: Mon 11 Mar 2013, 08:54
by greengeek
simargl wrote:

Code: Select all

while true; do sleep 1 && echo ""; done
I'm obviously doing this wrong too:

Code: Select all

#!/bin/sh
while true; do sleep 1 && echo ""; done
xdotool mousemove 20 20 
sleep 3
xdotool mousemove 20 40
sleep 1

Posted: Mon 11 Mar 2013, 09:04
by simargl
.

Posted: Mon 11 Mar 2013, 09:44
by technosaurus
btw ":" is a shortcut to true and also a useful way to make inline comments
also there should be an example in the xdotool thread that I wrote months ago that was designed to intentionally shake the mouse randomly to be annoying

ex.
printf "hello";: cruel;echo world

which is not the best example it is more useful when you have a long pipe and want to make comments

Code: Select all

....long pipe |cat `: inline comments`| \
continuation |cat `: inline comments`| \
...
here cat just acts as a pass through

but really most of the really long pipes you come across could be reimplemented much faster in a couple lines of awk (learn shell first though ... it will help)

Posted: Mon 11 Mar 2013, 17:01
by Karl Godt
simargl gave a short example.

A while or until loop needs to be programmed with some sleep lines as stated above. Otherwise they would run inside commands as fast as possible, heating up your cpu.

Code: Select all

until [ "`pidof poweroff`" -o "`pidof reboot`" ]; do
yes
done
Explaination :
* until tests for existence of a process-id of poweroff -or reboot. Until one of these two appear it runs the
* yes command, that printfs 'y' into the terminal or standard output?error as much as the cpu can deliver.
* done closes the do command.

You can alternatively use the while command :

Code: Select all

SCR_SIZ=`xwininfo -root | grep '\-geometry' | awk '{print $2}'`
SCREENSIZE="${SCR_SIZ%%+*}"
MAX_X="${SCREENSIZE%%x*}"
MAX_Y="${SCREENSIZE##*x}"
while 
test "`pidof X`"; 
count=0
do
count=$((count+10))
xdotool mousemove $count $count
sleep 5
 if test "$count" -ge "$MAX_X" -o "$count" -ge "$MAX_Y"
  then
   count=0
 fi
done
Explaination :
* xwininfo -root gives the current screen resolution ie -geometry 1280x1024+0+0
* MAX_XY are the maximum values formatted using bash string manipulation
* while test for the existence of a process-id of X. If there is a X-PID
* count is set zero
* do
* count increases by 10 each do loop
* xdotool whatever variable count variable count should move the cursor then from upper left to bottom right
* sleep five seconds to give you some chance to move the mouse and not occupying the whole cpu
* if tests if the cursor still would fit into the screen, if not resets the count variable to 0
* done ends the commands in the do loop.

Posted: Mon 11 Mar 2013, 17:47
by greengeek
simargl wrote:

Code: Select all

#!/bin/sh
while true; do
xdotool mousemove 20 20
sleep 3
xdotool mousemove 20 40
sleep 1
done
Thanks - that works.
technosaurus wrote:also there should be an example in the xdotool thread that I wrote months ago that was designed to intentionally shake the mouse randomly to be annoying
technosaurus wrote:annoying mouse fun

Code: Select all

while :; do xdotool mousemove_relative -- -$(($RANDOM % 10)) $(($RANDOM % 10)); xdotool mousemove_relative -- $(($RANDOM % 10)) -$(($RANDOM % 10)); done
Too dangerous for me to fiddle at this stage of my learning curve :-) I'm finding it hard enough to keep control of the mouse, let alone deliberately LOSING control of it...

Code: Select all

....long pipe |cat `: inline comments`| \
continuation |cat `: inline comments`| \
...
here cat just acts as a pass through...but really most of the really long pipes you come across could be reimplemented much faster in a couple lines of awk (learn shell first though ... it will help)
I'm trying...but even the baby steps seem big to me...
Karl Godt wrote:A while or until loop needs to be programmed with some sleep lines as stated above. Otherwise they would run inside commands as fast as possible, heating up your cpu.

Code: Select all

until [ "`pidof poweroff`" -o "`pidof reboot`" ]; do
yes
done
This moves the moves the mouse as expected but does not loop. Have I copied it wrongly?

Code: Select all

#!/bin/sh
until [ "`pidof poweroff`" -o "`pidof reboot`" ]; do
xdotool mousemove 20 20
sleep 3
xdotool mousemove 20 40
sleep 3
yes
done

Posted: Mon 11 Mar 2013, 17:57
by SFR
Hey Greengeek
greengeek wrote:This moves the moves the mouse as expected but does not loop. Have I copied it wrongly?

Code: Select all

#!/bin/sh
until [ "`pidof poweroff`" -o "`pidof reboot`" ]; do
xdotool mousemove 20 20
sleep 3
xdotool mousemove 20 40
sleep 3
yes
done
Delete 'yes' line - apparently it loops on its own.

BTW: Although I always use 'while true; do ... done' method, a famous "fork-bomb"-like syntax (recursive, infinite loop, but deprived of deadly "fork" mechanism) can be utilized as well:

Code: Select all

:(){ echo "Loop..."; sleep 1; :; };:
But of course this is not a good idea to have something like that in your code, so consider this as a "tip of the day". :wink:

Greetings!

Posted: Mon 11 Mar 2013, 18:18
by greengeek
Thanks - removing the "yes" does allow the script to work correctly.

How easy is it to explain what you mean by the "fork bomb". Can you clarify the danger you refer to or if I google it will I be likely to find the explanation (without drawing the attention of Echelon and Homeland Security)?

Posted: Mon 11 Mar 2013, 18:21
by Karl Godt
Yup the yes is one of the commands that are somehow not useful. It would need a -r MANY_TIMES option .
http://www.manpages.spotlynx.com/solaris/man/yes.1 wrote:yes can be used to respond programatically to programs that require an interactive response.
I got that from linuxquestions.org some longer time ago.

Posted: Mon 11 Mar 2013, 18:31
by SFR
greengeek wrote:How easy is it to explain what you mean by the "fork bomb". Can you clarify the danger you refer to or if I google it will I be likely to find the explanation (without drawing the attention of Echelon and Homeland Security)?
No danger - it's in Wikipedia: http://en.wikipedia.org/wiki/Fork_bomb 8)
Basically it's a nice looking one-liner, which multiplies itself (or rather its own process) ad infinitum, what makes system completely freezed.
Sadly, Puppy isn't immune for that kind of attack... :roll:

Greetings!

Posted: Mon 11 Mar 2013, 19:00
by greengeek
SFR wrote:infinite loop, but deprived of deadly "fork" mechanism) can be utilized as well:

Code: Select all

:(){ echo "Loop..."; sleep 1; :; };:
But of course this is not a good idea to have something like that in your code, so consider this as a "tip of the day".
Do you mean that it's not a good idea because it's so easy to get it wrong (and include a recursive fork by mistake)?

Posted: Mon 11 Mar 2013, 19:15
by greengeek
SFR wrote:Basically it's a nice looking one-liner, which multiplies itself (or rather its own process) ad infinitum, what makes system completely freezed.
Sadly, Puppy isn't immune for that kind of attack..!
It's very handy for me to know that I need to take care to avoid such risks. I'm always keen to tinker and "have a bash" so I would've dived in and locked up my system for sure... :-) Wiki suggests this as a means of prevention:
As a fork bomb's mode of operation is entirely encapsulated by creating new processes, one way of preventing a fork bomb from severely affecting the entire system is to limit the maximum number of processes that a single user may own.
I wonder if this might be possible on Puppy.

BTW - My reason for wanting these scripts to help with mouse movement is to allow an inexperienced or physically challenged user to easily select between a limited number of mousepointer_position_choices. That way they can have some degree of functionality by having a "mouseclick" button, but no actual ability to move the mouse anywhere I don't want it to go.

Posted: Mon 11 Mar 2013, 19:55
by SFR
greengeek wrote:
SFR wrote:infinite loop, but deprived of deadly "fork" mechanism) can be utilized as well:

Code: Select all

:(){ echo "Loop..."; sleep 1; :; };:
But of course this is not a good idea to have something like that in your code, so consider this as a "tip of the day".
Do you mean that it's not a good idea because it's so easy to get it wrong (and include a recursive fork by mistake)?
That too, but primarily, because 'while...' or 'until...' are most simple/common/readable methods.
But it may be useful, for example, if you'd like to deliberately obfuscate the code.
greengeek wrote:Wiki suggests this as a means of prevention:
As a fork bomb's mode of operation is entirely encapsulated by creating new processes, one way of preventing a fork bomb from severely affecting the entire system is to limit the maximum number of processes that a single user may own.
I wonder if this might be possible on Puppy.
Hard to say...
# ulimit -a | grep "max user processes"
max user processes (-u) 30948
#
shows that max. number of processes is limited, but it doesn't seem to work (maybe it doesn't affect root account?).

Greetings!

Posted: Tue 16 Jul 2013, 19:33
by greengeek
This thread morphed into an expanded topic tracing the development of SFRs "OneSwitch" pet for disabled users. New thread can be found here:
http://murga-linux.com/puppy/viewtopic.php?t=87418

Posted: Mon 17 Aug 2015, 18:37
by greengeek
SFR wrote:Hard to say...
# ulimit -a | grep "max user processes"
max user processes (-u) 30948
#
shows that max. number of processes is limited, but it doesn't seem to work (maybe it doesn't affect root account?).
Greetings!
On a different thread "scientist" has been trying the following:
This works and prevents root user from starting more than 50 processes.

Code: Select all

root   hard    nproc           50
I haven't tried it yet but thought I would post it.
The other thread is:
http://www.murga-linux.com/puppy/viewtopic.php?t=100634

Posted: Wed 26 Aug 2015, 13:15
by L18L
greengeek wrote:On a different thread "scientist" has been trying the following:
This works and prevents root user from starting more than 50 processes.

Code: Select all

root   hard    nproc           50
I haven't tried it yet but thought I would post it.
I have tried it:

Code: Select all

# root   hard    nproc           50
bash: root: command not found
# 
:wink: