Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

My current project runs a tests system on a linux box (with 9 active screens)

The whole team are familiar with how to kick off a test &c. but less familiar with the commands for checking progress, moving files around, forcibly stopping the test etc.

I'd like to write a script that can pull useful checks together, kicking them by a simple keypress. I could do this in Perl very easily but more consistent if it was a shell script (bash).

My shell experience is limited though and I would like a sample script (i.e. a framework) that would be easy for others to extend.

Wait for Key
Perform action
  Possibly accept further input for action
Repeat

A bonus would be to run an action every n minutes if no key received.

share|improve this question
    
Perl seems like a fine choice for this task... –  David Z Jul 9 '10 at 9:06
    
i would use perl too. to meet your needs of simplicity you could create a simple config language or DSL –  matthias krull Jul 9 '10 at 9:11
add comment

3 Answers 3

up vote 6 down vote accepted

Based on what you're describing, here's something simple (thanks to Dennis' comments):

while true; do
    # 300 is the time interval in seconds
    if read -n 1 -t 300; then
        case $REPLY in
        a)
            # command(s) to be run if the 'a' key is pressed
            echo a;;
        b)
            # command(s) to be run if the 'b' key is pressed
            echo b;;
        esac
    else
        # command(s) to be run if nothing is pressed after a certain time interval
        echo
    fi
done

Here's the alternative I had before, although I can't remember why I decided against case in the first place:

# define functions here
a_pressed() {
    # command(s) to be run if the 'a' key is pressed
}

b_pressed() {
    # commands for if 'b' is pressed
}

# etc.

nothing_pressed() {
    # command(s) to be run if nothing is pressed after a certain time interval
}

while true; do
    # 300 is the time interval in seconds
    if read -n 1 -t 300; then
        fn_name="${REPLY}_pressed"
        declare -pF | grep -q "$fn_name" && ${fn_name}
    else
        nothing_pressed
    fi
done

Either way, this will handle keypresses and will automatically invoke an action any time nothing has been done for 5 minutes.

share|improve this answer
    
Excellent. Does what I want. Have added some tweaks further down. If you can edit the answer would be good (I'll kill my reply) –  itj Jul 9 '10 at 10:38
    
I would just use a case statement instead of the fn_name variable, although it does make the code compact. –  Dennis Williamson Jul 9 '10 at 15:36
    
One advantage to using case is that if sometimes you want to do "a" or "b", others both, you don't have to define a function "c" that does both. When "c" is pressed, the c) clause would just call both "a" and "b". –  Dennis Williamson Jul 9 '10 at 15:41
    
@Dennis: I considered case but for some reason I decided against it... now I can't remember what that reason might have been, though. So I think you're right, case would be better. I'll edit. –  David Z Jul 9 '10 at 19:38
add comment

The only two i have ever heard of are Bashinator and the NRG Framework

NRG

Bashinator

share|improve this answer
    
Ah, sorry. I was thinking of a sample script. Maybe framework was a bad choice of word. –  itj Jul 9 '10 at 9:17
    
Both are interesting questions, i think. –  matthias krull Jul 9 '10 at 9:43
add comment

Thanks to David Zaslavsky - does what I want.

Suggested tweaks (I can't edit the answer) or format comments

Add Shell Type

#!/bin/bash 

Parameterise time and allow for prompt (but not on timeout). Also appears that the -N should have been -n

# Will wait for this interval, then run default action 
DELAY=30 
while true; do 
    echo "Command list here..." 
    while true; do 
        if read -n 1 -t ${DELAY}; then 
            fn_name="${REPLY}_pressed" 
            declare -pF | grep -q "$fn_name" && ${fn_name} 
            break 
        else 
            default_action 
        fi 
    done 
done 
share|improve this answer
    
this wouldn't be the kind of thing you should edit in to someone else's answer, even if you were able to do so. The point is to show the gist of how to accomplish a task; it's understood that you may have to tweak it to actually use it. I think that what I posted is an adequate answer to your question, but if you disagree, you can certainly accept your own answer. –  David Z Jul 9 '10 at 19:49
    
Not entirely sure I agree, but academic as I don't have the power at present. People will cut and paste answers and snippets, and the better they are - the more useful the stackoverflow family become? -N you have edited I still think the #! should be in, but does guard against people (perhaps like me! who shouldn't be writing scripts. The formatting / extra prompt I agree & am unlikely to have edited even given the power –  itj Jul 12 '10 at 6:43
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.