Register
It is currently Wed Aug 20, 2014 12:47 am

loop until interrupted


All times are UTC - 6 hours


Post new topic Reply to topic  [ 13 posts ] 
Author Message
 PostPosted: Fri Nov 11, 2011 3:04 pm   

Joined: Thu Nov 10, 2011 7:31 pm
Posts: 21
I need a script that will loop until interrupted by a keypress form the parameters.
something like this:
Code:
SCRIPT c echo "loop"
loop
loop
loop
loop
loop
loop
loop
c
loop ended


Top
 Profile  
 PostPosted: Fri Nov 11, 2011 4:39 pm   
User avatar

Joined: Wed Jun 08, 2011 8:27 am
Posts: 189
Location: outer Shpongolia
Using stty(1) and trap(0):

Code:
#!/bin/bash                                                                                                                   
if ((! $#)); then
    printf 'usage: %s <intr_char> <command>\n' "${0##*/}" >&2
    exit 1
fi

if ((${#1} != 1)); then
    echo 'error: interrupt character too long.' >&2
    exit 1
elif [[ $1 != *[[:alpha:]]* ]]; then
    echo 'error: interrupt character must be a letter.' >&2
    exit 1
fi

stty intr "$1"
trap 'echo loop ended; stty intr ^C; exit' SIGINT

shift
if ((! $#)); then
    echo 'warning: no command specified.' >&2
fi

while :; do
    "$@"
done


Top
 Profile  
 PostPosted: Fri Nov 11, 2011 5:00 pm   

Joined: Thu Nov 10, 2011 7:31 pm
Posts: 21
denton@natty:~/scripts$ ./loop
./loop: line 10: syntax error near unexpected token `elif'
'/loop: line 10: `elif [[ $1 != *[[:alpha:]]* ]]; then


Top
 Profile  
 PostPosted: Fri Nov 11, 2011 5:25 pm   
User avatar

Joined: Wed Jun 08, 2011 8:27 am
Posts: 189
Location: outer Shpongolia
I can't reproduce the error you're getting...

It should've output this:
Code:
usage: loop <intr_char> <command>

even if there were syntax errors or control characters around elif...

Are you missing the ; then in:
Code:
if ((${#1} != 1)); then

?

If the answer is yes, then you haven't typed:
Code:
./loop

only.


Top
 Profile  
 PostPosted: Fri Nov 11, 2011 5:35 pm   

Joined: Thu Nov 10, 2011 7:31 pm
Posts: 21
I realized it had DOS encoding for some reason and I fixed it. I retried it with the -x parrameter to #! /bin/bash and I got
Code:
denton@natty:~/scripts$ ./intloop c echo "hi"
+ printf 'usage: %s <intr_char> <command>\n' bash
usage: bash <intr_char> <command>
+ exit 1


Top
 Profile  
 PostPosted: Fri Nov 11, 2011 5:52 pm   
User avatar

Joined: Wed Jun 08, 2011 8:27 am
Posts: 189
Location: outer Shpongolia
How weird... the first condition is like... ignored, and there is no error.
Which bash(1)'s version are you using?

Try the POSIX sh(1) version:

Code:
#!/bin/sh                                                                                                                     
if [ $# -eq 0 ]; then
    echo 'usage: <intr_char> <command>' >&2
    exit 1
fi

if [ "${#1}" -ne 1 ]; then
    echo 'error: interrupt character too long.' >&2
    exit 1
fi

case $1 in
    *[![:alpha:]]*)
        echo 'error: interrupt character must be a letter.' >&2
        exit 1
esac

stty intr "$1"
trap 'echo loop ended; stty intr ^C; exit' 2

shift
if [ $# -eq 0 ]; then
    echo 'warning: no command specified.' >&2
fi

while :; do
    "$@"
done


Top
 Profile  
 PostPosted: Fri Nov 11, 2011 7:20 pm   

Joined: Thu Nov 10, 2011 7:31 pm
Posts: 21
I'm using Ubuntu 11.04's BASH interpreter.
bash --version gives me
Code:
GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


Top
 Profile  
 PostPosted: Sat Nov 12, 2011 4:50 am   
User avatar

Joined: Tue Apr 27, 2010 2:28 pm
Posts: 172
Location: Czech Republic
Code:
char=''
while [[ $char != c ]] ; do
   read -t.01 -n1 char
   echo -n . # Do your loop
done


Top
 Profile  
 PostPosted: Sat Nov 12, 2011 7:03 am   
User avatar

Joined: Wed Jun 08, 2011 8:27 am
Posts: 189
Location: outer Shpongolia
blendmaster345 wrote:
I'm using Ubuntu 11.04's BASH interpreter.
bash --version gives me
Code:
GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.



Well, it's fine. It should works!

I'd suggest checking whether there are control characters again,
and make sure that the syntax is correct.

Also, does the POSIX sh(1) version work?


Top
 Profile  
 PostPosted: Sun Nov 13, 2011 11:58 am   

Joined: Thu Nov 10, 2011 7:31 pm
Posts: 21
choroba wrote:
Code:
char=''
while [[ $char != c ]] ; do
   read -t.01 -n1 char
   echo -n . # Do your loop
done

the c thing was only an example. I want you to be able to use any key.


Top
 Profile  
 PostPosted: Sun Nov 13, 2011 12:41 pm   
User avatar

Joined: Wed Jun 08, 2011 8:27 am
Posts: 189
Location: outer Shpongolia
@choroba: Does my solution work for you? I don't understand why it won't for blendmaster345.

----

blendmaster345 wrote:
choroba wrote:
Code:
char=''
while [[ $char != c ]] ; do
   read -t.01 -n1 char
   echo -n . # Do your loop
done


the c thing was only an example. I want you to be able to use any key.


Following choroba's idea:

Code:
#!/bin/bash

if ((! $#)); then
    echo 'usage: <intr_char> <command>' >&2
    exit 1
fi

intr_char=$1

shift
if ((! $#)); then
    echo 'warning: no command specified.' >&2
fi

while [[ $input != $intr_char ]] ; do
    read -n 1 -t .01 input
    "$@"
done


But this is less efficient.
You'll sometimes have to type « c » multiple times, because it relies on read(0)'s timeout.

You also didn't answer me.


Top
 Profile  
 PostPosted: Sun Nov 13, 2011 1:27 pm   

Joined: Thu Nov 10, 2011 7:31 pm
Posts: 21
Oh, sorry. I'm not sure. Like I said, I am using Ubuntu 11.04's default terminal configuration.


Top
 Profile  
 PostPosted: Sun Nov 13, 2011 2:16 pm   
User avatar

Joined: Tue Apr 27, 2010 2:28 pm
Posts: 172
Location: Czech Republic
jsz wrote:
@choroba: Does my solution work for you? I don't understand why it won't for blendmaster345.

Yes, both the solutions work (bash 4.1.7, openSUSE 11.3).

jsz wrote:
You'll sometimes have to type « c » multiple times, because it relies on read(0)'s timeout.

I was able to reproduce the problem only with very simple commands: if the command inside the loop took some time (more than .1s), I was not able to reproduce it.


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP