【问题标题】:How might I script-call SIGINT (CTRL+C)?我如何通过脚本调用 SIGINT (CTRL+C)?
【发布时间】:2022-12-16 08:59:30
【问题描述】:

我的问题是:如何通过代码实现对 SIGINT (CTRL+C) 的调用,而不是让用户键入信号?

该脚本轻松有趣,但也是一个学习工具(对我而言),因为我正在逐步实现特性和功能以增加我对 BASH 脚本的理解和知识。

具体来说,我发现很难利用信号捕获以及如何使其与我的脚本的其余部分一起使用。本质上,在一段时间后,应该调用 SIGINT 并且在到达程序结束之前应该有一个下一组指令的失败。虽然有很多捕获 SIGINT 的例子,在前台和后台处理进程 ID,但我无法理解它们,在这些地方,我可以相当自信地尝试实现。

我有的是这个

#!/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"

ctrl_c() 函数似乎没有任何作用,因为据我所知,它没有被调用;只有设置 flag=0 才能使进度条起作用。实际输入 CTRL+C 会停止进度条并允许程序继续执行到最后。那么,ctrl_c 真的有必要吗?如果没有flag=0,while 循环可以用另一种方式编写吗?

最终,有没有办法以编程方式发送 SIGINT?

【问题讨论】:

  • kill -INT $$ 将 SIGINT 发送到您脚本的 pid ($$)。
  • @Shawn:谢谢你的建议。正如您在某些时候可能已经意识到的那样,联机帮助页可能看起来难以理解,而且肯定是深奥的。它提供了很多信息,但是如何准确地应用这些知识——这需要比我更好的人。
  • @dan:谢谢你的建议。我写了同样的 sn-p,但试图把它放在一个用 while 循环构造的倒数计时器中;我仍然需要输入ctrl+c。所以,我现在的问题是安置;在哪里放置代码以获得我正在寻找的功能?

标签: bash signals pid sigint


【解决方案1】:
  1. 你是对的,在这种情况下你可以去掉ctrl_c
  2. 您可以按照@dan 在while 循环中某处的建议,简单地添加kill -INT $$ 命令。在下面的示例中,我将它添加到 dot_count 等于 4 时。在这种情况下,无需按键盘上的 Ctrl+Cdot_count 到达 4 后脚本将终止。
    #!/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 "
    %sCalculating%s" "$(tput el)" "$(dots "$dot_count")"
      dot_count=$((dot_count + 1))
      sleep 1
    done
    
    printf "
    %sCalculating... [Done]" "$(tput el)"
    
    
    get_rich=$((($RANDOM) + $age))
    
    printf "You'll be rich by the time you are $get_rich!
    "
    
    

    我在 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!
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多