5

When running a script with some lines not too important for the script to finish, how do I cancel a specific command without killing the entire script?

Normally I would invoke Ctrl+c, but when I do that with that script, the entire script ends prematurely. Is there a way (e.g. options placed inside the script) to allow Ctrl+c just for the command at hand?

A bit of a background: I have my ~/.bash_profile to run ssh-add as part of it, but if I cancel it, I would like to get the echo lines following the "error 130" of ssh-add being shown to remind me to run it manually before any connection.

2 Answers 2

6

I think you are looking for traps:

trap terminate_foo SIGINT

terminate_foo() {
  echo "foo terminated"
  bar
}

foo() {
  while :; do 
    echo foo
    sleep 1
  done
}

bar() {
  while :; do 
    echo bar
    sleep 1
  done
}

foo

Output:

./foo
foo
foo
foo
^C foo terminated # here ctrl+c pressed
bar
bar
...

Function foo is executed until Ctrl+C is pressed, and then continues the execution, in this case the function bar.

3
  • It's a TRAP! But a good one. After rebuilding my .bash_profile, it works like described. Thanks!
    – Phoenix
    Apr 23, 2020 at 15:32
  • You are welcome! Glad it helped. Apr 23, 2020 at 15:34
  • 1
    "It's a TRAP!" Haha I get it now ;-) Apr 23, 2020 at 21:02
3
#! /bin/bash

trap handle_sigint SIGINT

ignore_sigint='no'

handle_sigint () {
        if [ 'yes' = "$ignore_sigint" ]; then
                echo 'Caught SIGINT: Script continues...'
        else
                echo 'Caught SIGINT: Script aborts...'
                exit 130 # 128+2; SIGINT is 2
        fi
}

echo 'running short commands...'
sleep 1
sleep 1

ignore_sigint='yes'
echo 'running long commands...'
sleep 10
ignore_sigint='no'
echo 'End of script.'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .