1

I need to figure out how to trap Ctrl C, so that if I want to end the script early, it can re-enable the suspend and hibernation modes.

I looked at other discussions of trapping Ctrl C, but found none that were of help.

Thanks.

#     TimerInTerminal.sh

# To prevent your Linux system from suspending or going into hibernation, you need to disable the following systemd targets:
# sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target

# To re-enable the suspend and hibernation modes, run the command:
# sudo systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target

soundfile="/usr/share/sounds/My_Sounds/Electronic_Chime.wav"
# Stop computer from sleeping while timer is running

# prevent your Linux system from suspending or going into hibernation
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target

# This allows supend ?
#trap "echo marlin | sudo -S systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target" INT EXIT

if [ $# -eq 1 ]
then
    DURATION="$1"
else
    read -r -p "Timer for how many minutes?( for fractional, use decimal notation , 0.5==30s, 1.25==75s etc) : "  DURATION
    read -r -p "Enter text to display at the end of the timer : " n1
fi

DURATION=$(echo "$DURATION * 60 / 1" | bc) # lets us deal with fractional inputs

START=$(date +%s)   # only do this once (anchor's the time)

countdown () {
    NOW=$(date +%s)              # Get time now in seconds
    DIF=$((NOW - START))         # Compute diff in seconds
    ELAPSE=$((DURATION - DIF))   # Compute elapsed time in seconds
    MINS=$((ELAPSE / 60))        # Convert to minutes... (dumps remainder from division)
    SECS=$((ELAPSE - (MINS*60))) # ... and seconds
    #banner "$MINS:$SECS"
    echo "$MINS:$SECS"
    sleep "$1"
}

while true 
do
    clear
    
    countdown 0 # calc time remaining
    
    if [ $MINS -le 0 ]
    then
        # Blink screen

        while [ $SECS -gt 0 ]
        do
            
            clear # Flash on
            #setterm -term linux -back red -fore white 
            countdown 0.5

            clear # Flash off
            #setterm -term linux -default
            countdown 0.5

        done # End for loop
        
        setterm -term linux -default
        clear
        
        break   # time has expired lets get out of here
    
    else
        countdown 1 
    fi
done

echo $n1
amixer -D pulse sset Master 30% > /dev/null 2>&1
# Play a sound
cvlc --play-and-exit "$soundfile" > /dev/null 2>&1

# To re-enable the suspend and hibernation modes, run the command:
 echo marlin | sudo -S systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target
fixit7
  • 133
  • 1
  • 7
  • How where they not of help? – jesse_b Sep 22 '22 at 12:16
  • To connect the dots, a terminal window accepts your keystrokes and hands them to the tty (or pty) driver, which passes them to the standard input file descriptor of the command that's attached to the tty/pty. In the case of certain keystrokes like `Ctrl-C`, the tty driver generates a signal to the command rather than passing characters into the file descriptor. With Ctrl-C, the signal is named "interrupt", which is commonly abbreviated SIGINT or INT. As jesse_b's answer indicates, you need to use the `trap` mechanism in your script to catch the signal and respond to it within your script. – Sotto Voce Sep 22 '22 at 15:44

1 Answers1

3

Add this somewhere near the top of your script:

trap cleanup SIGINT

cleanup () {
    sudo systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target
}

I'm not sure why you are sending marlin across the pipe to systemctl when you reenable but the trap command you have commented out would probably still work except you have it using mask instead of unmask fwiw. Although it's worth noting that by trapping for INT and EXIT when you press ctrl+c your command will be executed twice.

jesse_b
  • 35,934
  • 12
  • 91
  • 140