3

How can I catch the CTRL+D keyboard in ksh and after exit?

while true; do
  read cmd
  echo $cmd
  if [ "$cmd" = "?????" ]; then
        break
  fi

done
dlmeetei
  • 9,905
  • 3
  • 31
  • 38
Marco Rocci
  • 355
  • 1
  • 2
  • 10

2 Answers2

6

CTRL-D is "end-of-file (EOF)" and what you need to do is "trap" that input. Unfortunately, there isn't a EOF character -- when you hit the chord CTRL-D, the tty sends a signal to the reading application that the input stream has finished by returning a sentinel value to make it exit.

To prevent this character from being treated as further input, it has to be an special character (e.g. something out of range like -1). When the terminal detects such a character, it buffers all its characters so that the input is empty, which in turn makes your program read zero bytes (end of file).

You may be running into an issue because the read command exits when receiving eof, so your script was likely terminating before getting to your conditional. This has the side effect of breaking out of the script, but likely not in the way you wanted.

Try:

#!/usr/bin/env ksh

# unmap so we can control the behavior
stty eof ^D

while true; do
  read cmd
  echo $cmd

  # are we out of input? let's get a taco
  if [ ! -n "$cmd" ]; then
    echo 'taco time'
  fi

done

When you get to other signals (like ^C) the general form is:

trap [commands] [signals to catch]

Mwiza
  • 7,780
  • 3
  • 46
  • 42
4

Just use while read:

while read cmd; do
  echo $cmd
done
pynexj
  • 19,215
  • 5
  • 38
  • 56
  • Yes, thanks. It works. But how can i use a comparison? – Marco Rocci Feb 10 '15 at 15:02
  • Why do you have to use a comparison? – pynexj Feb 10 '15 at 15:10
  • for personal Culture and increase my skills. Maybe oneday i should need to do a break when i press ctrl + something – Marco Rocci Feb 10 '15 at 15:11
  • When EOF is seen, read gets nothing. CTRL-D is just used to indicate the EOF. It's not similar to other CTRL-something like CTRL-C which would usually send a signal. – pynexj Feb 10 '15 at 15:19
  • For signals: [link1](http://stackoverflow.com/questions/9937743/what-keyboard-signal-apart-from-ctrl-c-can-i-catch), [link2](http://stackoverflow.com/questions/6764265/ctrl-c-sigint-ctrl-x), [link3](http://www.yolinux.com/TUTORIALS/C++Signals.html), for EOF: [link4](http://en.wikipedia.org/wiki/End-of-file) – pynexj Feb 10 '15 at 15:27
  • 1
    Even better, when read gets eof, the command exits with a non-zero status. This is exactly why `while read` works: when it hits eof, read exits non-zero, and the while loop can exit. – glenn jackman Feb 10 '15 at 16:37