Search code examples
shellfishtrap

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


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.


Solution

  • 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.