5

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.

  • 1
    So why not just background the subshell? – mikeserv Jul 2 '15 at 21:21
  • @mikeserv I'm on rhel 6 with bash 4.1 – basin Jul 2 '15 at 21:27
  • ...so update? Or maybe get a better shell. – mikeserv Jul 2 '15 at 21:29
  • 1
    @mikeserv yeh or he could just install windows and be happy double-clicking stuff instead of writing shell script. Or not doing that at all. I'm pretty sure the OP has his own reason for not changing the operating system or the shell, and it may be better to stay on topic. – pqnet Jul 3 '15 at 13:39
  • 1
    @mikesev Tested dash: it behaves exactly as bash 4.1. bash has been breaking POSIX, good to hear: there are many crappy parts in posix. – basin Jul 3 '15 at 19:34
4

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]: $!";

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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