bash control-c trap

My script code is very complex. So, I’ll just show the general format, leaving out most of the code. If you pressed control-c, it would cancel the scan and unmount the drive. This no longer works. I’v done many searches online. The code should work. It just exits the script without unmounting it.

scanvirus_trap_flag=false

run if user hits control-c

control_c()
{
scanvirus_trap_flag=true
#adding unmount drive command doesn’t do anything.
}

trap keyboard interrupt (control-c)

trap control_c 2

#loop mount drives

#mount drive

clamscan -r ${mountpoint}

#unmount drive

if  "$scanvirus_trap_flag" = 'true' ]; then
   break
fi

#end loop

Have you tried defining he traps BEFORE anything else, in particular
before the functions?


Good luck.

If you find this post helpful and are logged into the web interface,
show your appreciation and click on the star below…

Tried that didn’t work. One time, control-c exited the script. Another time adding control-z trap, the script wouldn’t exit. I’m narrowing the script to a simple script that shows the problem.

control-c = 2, control-z = 20

#!/bin/bash
trap_key=false

# capture the interrupt control-c
trap 'trap_key=controlc' 2

clamscan -r /

if  trap_key = 'controlc' ]; then
    printf "clamscan interrupted
"
else
    printf "clamscan completed
fi


This format did work on my current script. If the user pressed control-c, the drive would be unmounted and the script would exit. In this case, Control-c interrupts clamscan. Then the script detect control-c and prints the message.

FYI, this is a page with similar problem.

http://stackoverflow.com/questions/12771909/bash-using-trap-ctrlc

If I understand you correct, you have a script where you trap the Crtl-C interrupt. Inside the script you run a program. When the program is running, you do a Crtl-C. That interrupts the program (not the script). The program seems to exit as the result of the interrupt. End of story.

You seem to think that the fact that the program is interrupted is carried forward (or better: backward) to the parent process (the script), that is of course not the case. The script can only act on the return code of the exiting pogram. It depends on the exiting program if it creates a return code that signals a Crtl-C interrupt that differs from other return codes. The documentation of the program should tell you what return codes it creates in what situations.

Just a FYI,

If you’re looking for an example trapping these kinds of events,

I was just looking at the script **mysqld_safe **which is installed as part of all mariadb/mysql installs, and one of its interesting features is that it traps attempts to kill the process and either restarts the process or invalidates the action.

The script does a lot more, so for your purposes if you wanted to inspect and use this specific functionality you might want to make a copy and remove everything irrelevant to what you want. The code is also very modularized for flexibility (and best practice) so you’d have to do a little sleuthing following the execution plan(unless you ran it through a stepping debugger).

The code is extensively commented for easy understanding.

TSU

It also works here using template you provided. Please provide actual minimal script that shows this problem and information about your environment and how you start this script.

Ctrl-C is sent to all processes in current foreground process group. So shell should get it - assuming that shell script is the command that is actually started. Unfortunately original post lacks any detail so any answer is nothing more than guesswork.

I’m studying the answers here and this code.

#!/bin/bash 

# Enable job control
set -m

while :
do
    read -t 10 -p "input> " input
     $input == finish ]] && break

    # set SIGINT to default action
    trap - SIGINT

    # Run the command in background
    bash -c "$input" &

    # Set our signal mask to ignore SIGINT
    trap "" SIGINT

    # Move the command back-into foreground
    fg %-

done

Is this the question? In this case you forgot to ask it.

Sorry, I had to leave at that time. The idea, I send clamscan to the background and noting the PID number. When I press control-c, I kill clamscan and set a flag. Also, I’m trying to understand parent-child concept in bash scripts.

trap "kill $clamscan_PID;trap_flag=controlc" SIGINT

clamscan -r \ 
clamscan_PID=#!



So, I’m not fully understanding what is going on when I press control-c with a trap and child-process is running. My original code is very complex. It will confuse the problem for me and anyone helping. This is the problem in it’s most basic form.

How do I get this to work? The trap prevents control-c from exiting the script. Either controlc cancels clamscan, but the script still runs. Else, control-c is doesn’t cancel the script and the clamscan process. So, I will need to kill clamscan in the trap. If it’s exiting on clamscan process not returning to the code, I need to change return code(exit 0). Low on time, again. :stuck_out_tongue:

#!/bin/bash
trap_key=false

# capture the interrupt control-c
trap "kill $clamscan_PID;trap_key=controlc" SIGINT

clamscan -r /

if  trap_key = 'controlc' ]; then
    printf "clamscan interrupted
"
else
    printf "clamscan completed
fi



SIGINT is delivered to shell that runs the script as well as to child process.

Otherwise I completely lost track of what you are trying to do, why you post those random code snippets and what we are supposed to do with them, sorry.

The code snips are helpful code that shows similar problems and solutions from a website, job control.

What is wrong with this code?

#!/bin/bash
trap_key=false

# capture the interrupt control-c
trap 'trap_key=controlc' 2

clamscan -r /

if  trap_key = 'controlc' ]; then
    printf "clamscan interrupted
"
else
    printf "clamscan completed
fi

Nothing until you explain what you expect this code to do, what this code actually does and why you think it is wrong.

I want control-c to cancel clamscan and return to the script. The variable controls the print. Prints results if control-c was pressed or not.

The code snip I included looks like it does that. I have not had chance to test it yet.

This is entirely up to clamscan and shell has no control over it. If clamscan ignores or handles SIGINT, it will continue running. Shell won’t get control until clamscan is terminated.

I think I know what is happening, thanks to help from here. Control-c is working, but it’s causing an error “unexpected EOF” which causes the script to drop to the command line. I’m using a loop which I didn’t add into writing my simple script. I forgot to add a control-c flag inside the a loop and need go back over the scanvirus script.

There are two ways I’v found to catch this error.

http://redsymbol.net/articles/bash-exit-traps/

Using signal exit to unmount the drive if the script exits for any reason. The link shows how to use the exit signal to restart a script if it crashes.

http://stackoverflow.com/questions/64786/error-handling-in-bash#69808

Using sig error to trap this error.

Thanks for the help all. :slight_smile:

I’ll have to come back to this problem later. A new error appeared on my SED stream filter line on scanvirus script.

I found an alternative method to fix the problem, using the ‘trap function exit’.

Thanks to all for the help…