2

After standing up rhel VM and I was tailing a log file (tail -f xyz.log) however I realized that control-c didn't work to exit out of it. I tried control-z which did but that left background job so that I had to manually kill the process (tail -f xyz.log).

Someone in my shop told me to comment out trap function in /etc/profile which I did.

#trap "" 1 2 3 15

Then logout and log back in to shell environment, control-c began to work!

I just want to understand what happened. I did 'man trap' but I am not consuming the contents well unfortunately. Thank you for your time to read this.

  • 2
    The real mystery is why would somebody put that in /etc/profile? That's just weird. – Matti Virkkunen May 6 '16 at 1:33
3

The given trap command told the shell to intercept these signals:

1 SIGHUP
2 SIGINT
3 SIGQUIT
15 SIGTERM

The "" is the command to be run if one of those signals is received. In other words, do nothing; ignore the signals completely.

You can see what characters are bound to signals using stty -a, e.g., on the second line of output from stty in this example (the format depends upon the system you are using):

$ stty -a
speed 38400 baud; rows 40; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

The correspondence between some characters and signals is given in 11.1.9 Special Characters, e.g.,

  • intr sends SIGINT
  • quit sends SIGQUIT

so my ^C would send SIGINT (your configuration may differ).

Once you commented-out the trap, the shell reverted to its default behavior, which makes these special characters send signals when you type them, e.g.,^\ sends SIGQUIT and ^C sends SIGINT.

Further reading:

  • Thank you for your explanation and further reading items. After reading this and others, gradually make sense to me what happened. – DaeYoung May 5 '16 at 23:30
2

Pressing Ctrl+C in a terminal sends the SIGINT signal to the process running in the terminal. (More precisely, to all processes in the foreground process group; for example, if you're running foo | tail -f then the signal is sent to both foo and tail.)

The conventional meaning of SIGINT (INTerrupt signal) is “abort the current task and return to an interactive prompt”. Programs that don't have an interactive prompt, such as tail, simply exit to let the shell take over.

The trap command defines the shell's behavior when it receives a signal. For example trap 'echo killed' INT makes the shell print killed when it receives a SIGINT signal. trap 'echo killed' 2 is the same on a Linux PC because 2 is the number of the signal whose name is INT. This only triggers if the shell gets the signal, it doesn't trigger if another program is in the foreground.

trap "" INT is a special case. It doesn't just tell the shell to do nothing when it receives the signal, it tells the shell to ignore the signal. When a process registers a handler for a signal, that doesn't affect the programs it runs — the handler is code in the process, there would be no way to invoke it from another program. But ignoring a signal is a different setting, and that one is kept when a program runs another program. So after trap "" INT, when you run tail, the signal is still ignored, and pressing Ctrl+C has no effect.

If you want to keep effectively ignoring signals in the shell but not in programs that it starts, set a non-empty trap, for example trap " " INT or trap : INT (: is the shell's no-op command). Alternatively, run trap - INT before running tail to reset the signal handling to its default non-ignored state.

0

trap is a shell-builtin, the normal format is trap cmd list_of_signals. cmd is empty in your case, i.e. ignore that signal. 1 is the hangup signal, 3 is intr or Ctrl-C. See man bash Section Shell Builtin Commands for further explanation.

  • :Thank you for your concise and pointy answer. – DaeYoung May 5 '16 at 23:31

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.