Find the answer to your Linux question:
Results 1 to 6 of 6
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1

    What signal emitted with CTL+D in Bash?

    I'm doing the shell history audit logging using syslog to gather the command history. I'm using this well publicized method using trap and logger:

    declare -r REAL_LOGNAME=`/usr/bin/who am i | cut -d" " -f1`
    function log2syslog {
    declare command
    command=`fc -ln -0`
    logger -p local1.notice -t bash -i ": $REAL_LOGNAME as $LOGNAME :$command"
    trap log2syslog DEBUG TERM

    The problem is that the trap on DEBUG will catch the next to last command executed (by virtue of the "fc" command) which is not the current command executed. TERM will catch that "next to last" command on exit, thus completing the logging of each command executed during that session.

    However, CTL+D doesn't seem to emit a SIGTERM signal. What signal is actually being emitted and can it be trapped? I guess another question would be whether there is a way to trap history after command line execution? Moving to Bash 4.1 isn't possible in our "supported" multi-platform environment

    Last edited by onthego; 10-22-2010 at 02:39 PM. Reason: add additional comment

  2. #2
    Linux Guru Cabhan's Avatar
    Join Date
    Jan 2005
    Seattle, WA, USA
    So without fully understanding your code, I'll at least answer the Ctrl-D question.

    Ctrl-D does not emit a signal. Instead, it counts as an input of EOF. EOF causes the program to think that there is no more input, so in this case, Bash decides to exit.

    I'm not sure exactly how to catch that condition super well, unfortunately.

  3. #3
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    As Cabhan said, a Ctrl-D doesn't generate a signal. It is effectively the same behavior as the "exit" command. Your attempt to trap the TERM signal won't work in such a case as it is not generating a signal.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  4. $spacer_open
  5. #4
    Linux Guru Cabhan's Avatar
    Join Date
    Jan 2005
    Seattle, WA, USA
    I just went poking through the bash man page, and I came across this environment variable:
                  Controls the action of an interactive shell on receipt of an EOF
                  character as the sole input.  If set, the value is the number of
                  consecutive EOF characters which must  be  typed  as  the  first
                  characters  on an input line before bash exits.  If the variable
                  exists but does not have a numeric value, or has no  value,  the
                  default  value  is  10.  If it does not exist, EOF signifies the
                  end of input to the shell.
    This does not cause bash to ignore EOF, but means that EOF must be typed multiple times. You could set this variable to a high number, and in the documentation for your script say that EOF is not supported when running your program and that you must run "exit" to quit.

  6. #5

    Makes sense

    Thanks guys for the advise. I'm only command line logging a handful of shared non-user/administrative accounts that the identity is assumed using "sudo su -". That type of exception won't be far reaching.

    Though EOF is not a true Unix signal, it is an event that is detected by the running shell and a section of code is invoked to act on based on that event. The builtin "exit" command itself isn't a true signal, but results in the signal being emitted.

    The method for IGNOREEOF is interesting workaround and worth giving a shot. It will be interesting to see how it affects inline reads and such. I'll post back with the results.
    Last edited by onthego; 10-26-2010 at 03:57 PM. Reason: correct spelling

  7. #6

    Appears to be a suitable solution

    I set the IGNOREEOF=1 without exporting it and seems to be suitable (though not optional) in order to capture the last command executed before exit.

    The fallout comes when you perform in-line reads (aka here-documents) directly from that login shell. For each line directed from STDIN you log a redundant command line execution (from history) for that loop instance. When executing a standalone bash script with a looped in-line read, you only get the script executed once in the log (since the variable is unexported). Logically, if exported, any bash script executed will inherit the IGNOREEOF. The fallout here is the added clutter in the log for what appears to be redundant shell script executions you really don't care to see, again one shell script execution from history per loop iteration in that script.

    Hope this makes sense. Thanks for the tip.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts