3

I have a bash script which is supposed to run a command every X seconds, until the operator interrupts it. Like this:

test.sh

#!/bin/bash

while true; do
    echo Doing a thing...
    sleep 3 & wait
done

This, for the most part, works as expected. However, on one particular user account (which is of course the account I want this to run under) the CTRL-C key combination doesn't seem to be sending an interrupt signal to the script, which means it runs forever until I kill it in another terminal.

Suboptimal.

The first thing I checked was whether the .profile for this account had somehow undefined stty intr, but that is not the case (and explicitly adding the line

stty intr "^c"

to my script didn't help, neither did setting the escape code to something different). The .profile also does not appear to be trapping any signals anywhere. This problem occurs whether I sudo into the account or log in directly. CTRL-C seems to work as expected when I run other commands (e.g. ping) from the command line.

CTRL-C interrupts the script as expected if I run it as root, or if I run it while logged in under a different unprivileged account. Creating an entirely new unprivileged account with a default .profile, it doesn't work. This is all using the same terminal installation and settings (PuTTY), so it doesn't appear to be a case of the terminal itself somehow intercepting or mangling the signals.

The only thing I can think of is that this is some profile setting affecting the behaviour, but I can't see anything in .profile, and outside of stty and possibly $TERM (which is the same in all accounts) I can't think of anything else that could be affecting it like this.

(I'm not including my .profile(s) right now because, quite frankly, they're a mess and it will take a while for me to sanitize. I'm less concerned with finding out what's wrong with my .profile per se, especially since the default .profile on a new account also has this issue, and more about where even I should be looking at for a solution.)

Just in case they're relevant, my stty -a settings (they're the same in the working and the non-working accounts):

speed 38400 baud;
rows = 25; columns = 80; ypixels = 0; xpixels = 0;
intr = ^c; quit = <undef>; erase = ^h; kill = ^x;
eof = ^d; eol = <undef>; eol2 = <undef>; swtch = <undef>;
start = ^q; stop = ^s; susp = ^z; dsusp = <undef>;
rprnt = ^r; flush = ^o; werase = ^w; lnext = ^v;
-parenb -parodd -parext cs8 -cstopb hupcl cread -clocal -loblk
-ignbrk brkint -inpck -ignpar -parmrk -istrip -inlcr -igncr icrnl -iuclc
ixon -ixany ixoff -imaxbel
opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel tab3
isig icanon -xcase echo echoe echok -echonl -noflsh
-tostop -echoctl -echoprt -echoke -defecho -flusho -pendin -iexten
-isscancode -xscancode

What am I missing? If it matters, I am running GNU bash 3.2.17(1)-release on SCO OpenServer 6.0.0 MP4.


Other things tried (recording here to get them out of comment threads)

  • Running the following command from another terminal while the script is running:

    kill -INT <process>
    

    didn't accomplish anything, even while running the kill command as root. Running

    kill -HUP <process>
    

    terminated the script as expected.

  • I attempted to trap the signal by adding the following lines to my script:

    trap "echo hi" SIGINT
    trap "echo lo" SIGHUP
    

    Hitting CTRL-C or running kill -INT <process> as above showed no reaction. Running kill -HUP <process> as above did echo "lo" as expected.

  • I have tried running the script in the following ways

    /bin/sh /path/to/test.sh
    /bin/bash /path/to/test.sh
    /path/to/test.sh
    cd /path/to; test.sh
    

    No difference.

  • As suggested by @mosvy in the comments, I tried running it through perl as follows:

    perl -e '$SIG{INT}="DEFAULT"; exec @ARGV or die "exec: $!"' /path/to/test.sh
    

    This, for some reason, did work.

16
  • How do you kill this process in another terminal? Does kill -INT <process> work? Commented Mar 24, 2020 at 1:45
  • And maybe add a signal trap like this trap 'echo hi' SIGINT to check if script receives SIGINT at all in the first place. Commented Mar 24, 2020 at 1:47
  • @ArkadiuszDrabczyk kill -INT <process> doesn't work, even if i'm logged in as root to do it. kill -HUP <process> works as expected to stop the script. Commented Mar 24, 2020 at 1:50
  • 3
    Try trap - INT (in the shell you're calling your script from, NOT in the script). FWIW, the reason why it won't work inside the script is: "Signals that were ignored on entry to a non-interactive shell [ie a script] cannot be trapped or reset, although no error need be reported when attempting to do so." Reference Commented Mar 24, 2020 at 2:33
  • 1
    Better look for trap commands in all your initialization scripts (Does bash also uses the /etc/profile.d madness on OpenServer too?). A signal can be accidentally ignored by a command like trap "$cmd" INT when cmd is an empty or undefined variable. Commented Mar 24, 2020 at 2:43

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.