Den
Den

Reputation: 183

How might I script-call SIGINT (CTRL+C)?

my issue is this: how can I implement the call to SIGINT (CTRL+C) by means of code, rather than have a user key-in the signal?

The script is light-hearted fun, but also a learning tool (for me), as I am progressively implementing features and functionality in a bid to increase my understanding an knowledge of BASH scripting.

Specifically, I am finding it difficult to utilise signal trapping and how to make it work with the rest of my script. Essentially, after a period of time, SIGINT should be called and there should be a fall-through to the next set of instructions before reaching the end of the program. While there are many examples of capturing SIGINT, dealing with Process IDs in the foreground and background, I cannot make sense of them, where, I could fairly confidently attempt implementation.

What I have is this,

#!/usr/bin/bash

read -p "What is your name?" name
read -p "How old are you?" age

printf "Hello ${name^}; you are ${age} years old."
printf "Let's find out when you will become rich."

trap ctrl_c INT

ctrl_c()
{
  flag=1
}

dots()
{
  if [[ "$" -eq 1 ]]; then
    echo "."
  fi
  if [[ "$2" -eq 2 ]]; then
    echo ".."
  fi
  if [[ "$3" -eq 3 ]]; then
    echo "..."
  fi

flag=0
dot_count=1

while [[ "$flag" -eq 0 ]]; do
  if [[ $dot_count -eq 4 ]]; then
    dot_count=1
  fi
  
  printf "\r%sCalculating%s" "$(tput el)" "$(dots "$dot_count")"
  dot_count=$((dot_count + 1))
  sleep 1
done

  printf "\r%sCalculating... [Done]" "$(tput el)"

    ...

get_rich=$((($RANDOM) + $age))

printf "You'll be rich by the time you are $get_rich!\n"

The function ctrl_c() seems to serve no purpose, because, to my knowledge, it is not called; only setting flag=0 causes the Progress Bar to function. Physically entering CTRL+C stops the Progress Bar and allows the program to continue to its end. So, is ctrl_c actually necessary? Could the while-loop be written another way without flag=0?

Ultimately, is there a way to programatically send SIGINT?

Upvotes: 1

Views: 382

Answers (1)

gomfy
gomfy

Reputation: 689

  1. You are right that in this case you can get rid of ctrl_c.
  2. You can simply add kill -INT $$ command as @dan suggested somewhere in the while loop. In the example below I added it to when dot_count equals 4. In that case there is no need for pressing Ctrl+C on your keyboard; after dot_count reaches 4 the script will terminate.
#!/usr/bin/bash

read -p "What is your name?" name
read -p "How old are you?" age

printf "Hello ${name^}; you are ${age} years old."
printf "Let's find out when you will become rich."

trap flag=1 INT

dots()
{
  if [[ "$1" -eq 1 ]]; then
    echo "."
  fi
  if [[ "$2" -eq 2 ]]; then
    echo ".."
  fi
  if [[ "$3" -eq 3 ]]; then
    echo "..."
  fi
}

flag=0
dot_count=1

while [[ "$flag" -eq 0 ]]; do
  if [[ $dot_count -eq 4 ]]; then
    dot_count=1
    kill -INT $$
  fi
  
  printf "\r%sCalculating%s" "$(tput el)" "$(dots "$dot_count")"
  dot_count=$((dot_count + 1))
  sleep 1
done

printf "\r%sCalculating... [Done]" "$(tput el)"


get_rich=$((($RANDOM) + $age))

printf "You'll be rich by the time you are $get_rich!\n"

I get the following running it on an Ubuntu 22.04:

gomfy:signal$ bash script.sh 
What is your name?G 
How old are you?98
Calculating... [Done]You'll be rich by the time you are 26348!

Upvotes: 1

Related Questions