How to end the `read` command by ctrl c?

102 Views Asked by At
read -l -P "" number
if test -z "$number"
    set number 2
end
# do something e.g. echo "Processed"
echo "Processed"

I want to read something from the standard input and then do something, e.g. echo "Processed". When Ctrl C is inputted from the standard input, I wish do something will never be executed. However, do something is always be executed.

I tried to use trap to kill %self, like

trap 'kill %self' INT
read -l -P "" number
if test -z "$number"
    set number 2
end
# do something e.g. echo "Processed"
echo "Processed"

However, %self should not be killed. This program is triggered by a shortcut. The pid of the program of the same as the pid of the terminal. Thus when kill %self is executed, the terminal is been closed. This is not expected.

The pid of the program of the same as the pid of the terminal.

2

There are 2 best solutions below

0
On BEST ANSWER

When read reads from the terminal and gets a ctrl-c, it is already aborted [0].

However, in that case it sets the variable to empty and returns a false status.

You never check that status, and so execution just continues with an empty variable.

What you want is simply this:

read -l -P "" number
or exit # or return or handling it in another way.

You can also use an if:

if read -l -P "" number
   # do things you would do if read wasn't aborted
   # Note: $number can still be empty if the user just pressed enter!
end

[0]: When you read from e.g. a pipe, the ctrl-c would typically end the writing process, and so read would get an end-of-file instead of a newline, and the same thing would happen.

0
On

Here is one solution to capturing how many times Ctrl-C has been pressed. I don't know if this answers your question because your question is ambiguous about what value you expect $number to hold before and after a Ctrl-C (SIGINT) event. In the example below I pressed Ctrl-C twice after defining the ctrl_c_handler function.

> function ctrl_c_handler --on-signal INT
      echo "ctrl c" %self
      set -g number (math $number + 1)
   end
> ctrl c 37990
> echo $number
1
> ctrl c 37990
> echo $number
2