Bash – command line tool to manage unix signals

bashcoreutilsposixsignals

Is there a command runner like env, nice, nohup, etc., that can run a program with modified signals? In my case, I need something to reset SIGINT to SIG_DFL.

Why do I need this? Because non-interactive bash sets SIG_IGN for SIGINT for background processes and you can't reset it with the shell built-in trap: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=573780

upd: in bash 4.3 background subshell does not ignore SIGINT, other background programs still do

http://tiswww.case.edu/php/chet/bash/CHANGES

h. Fixed a bug that caused SIGINT and SIGQUIT to not be trappable in
asynchronous subshell commands.

Best Answer

There is no. Very easy to write one with perl. Here's untrap script:

#!/usr/bin/perl
$SIG{INT} = "DEFAULT";
exec { $ARGV[0] } @ARGV or die "couldn't exec $ARGV[0]: $!";

Example usage:

#!/bin/bash
untrap bash -c '
    sleep 3
    echo aaa
' &
trap '' INT
wait $!

If you remove untrap prefix, Ctrl-C won't kill the script.

More versatile script:

#!/usr/bin/perl

use Getopt::Long;

GetOptions(
    'help' => sub {
        print "usage: $0 [--sig={INT|HUP|...}={IGNORE|DEFAULT}]... COMMAND [ARG]...\n";
        exit 0;
    },
    'sig=s%' =>
    sub {
        my $action = $_[2];
        my $signame = $_[1];
        die "bad action $action" unless ($action eq "IGNORE" or $action eq "DEFAULT");
        die "bad signame $signame" if ($signame eq "__DIE__" or $signame eq "__WARN__");
        $SIG{$_[1]} = $action;
    }) or exit 1;

exec { $ARGV[0] } @ARGV or die "couldn't exec $ARGV[0]: $!";