如何使用脚本终止睡眠进程

How to kill a sleep process using a script

我想编写一个脚本来执行以下操作

  1. 在前台启动 sleep 500 命令。
  2. 然后在后台发送 sleep 500 命令,这样我就可以得到我的提示

我试过在脚本中这样做:

sleep 500
kill `pidof sleep`

但是当我 运行 脚本时,睡眠命令不会停止并且我没有得到提示。关于如何完成这项工作的任何建议都会有所帮助。

我找不到我要找的确切复制品,所以这里有一个简短的例子。如果我明白你想要什么,你想启动一个 sleep 进程,然后在任何时候你希望能够退出睡眠进程 return 提示你。你说“后台”睡眠过程,但我不确定你是否真的需要后台让它在未来自行过期,或者是否只需要在你选择时退出睡眠(那会让更有意义)

虽然您可以简单地使用 Ctrl + C 来中断进程,但您不会 return 进入脚本。因此,如果您需要一种方法 return 到您的脚本,则需要 trap SIGINT。当您设置 trap 'some command' SIGINT 时,您的脚本将拦截并处理中断,并且控制将 return 到 sleep 命令之后的点,例如

#!/bin/bash

## set trap
trap 'printf "\n[Ctrl + C] SIGINT intercepted\n"' SIGINT

printf "sleeping 500...\n"

sleep 500

## rest of script after sleep
printf "control returned to script\ncontinuing to process commands\n"

示例运行上面的脚本

$ bash trap_int.sh
sleeping 500...
^C
[Ctrl + C] SIGINT intercepted
control returned to script
continuing to process commands

这可能会或可能不会满足您的需求。但是,您可以在此基础上进一步控制中断后发生的情况。当您设置 trap 时,您可以让它在您的脚本中调用一个单独的函数,该函数可以有条件地执行代码并通过调用 exit 在该单独的分支上结束脚本。这具有将控制权转移回您的脚本的效果,以仅从以您指定的函数开头的路径执行命令。这样可以避免执行睡眠之后的代码,同时在脚本中提供单独的执行路径 运行 从睡眠中断后需要的任何内容。

中断后有条件地执行命令

不仅仅是sleep 500,在下一个例子中我们将重复调用两个函数sleep_a,这两个函数调用一个嵌套的睡眠函数sleep_b。以下 SIGINT 控制权将传递给名为 handle_interrupt 的函数,在该函数中可以执行其他命令,调用 exit 退出脚本并 return 您进入提示。调用一个名为 actual_exit 的附加函数来执行退出。

#!/bin/bash

## function called to exit, returning you to prompt
function actual_exit
{
    printf "  Exiting after '%s'\n\n" ""
    exit
}

## function called after SIGINT, calls actual_exit to disply signal caught
function handle_interrupt
{
    printf "\n  Signal SIGINT Caught! [ctrl + c]\n\n"
    actual_exit 'SIGINT'
}

## set trap
trap handle_interrupt SIGINT      # calls handle_interrupt on [ctrl + c]

declare -i idx=0    ## loop counter

function sleep_b
{
    printf "\nentering sleep_b\n"
    sleep 2
    printf "executing post sleep_b index: %s\n" $((idx++))
}

function sleep_a
{
    printf "\nentering sleep_a\n"
    sleep 2
    printf "executing post sleep_a index: %s\n" $((idx++))
    sleep_b
}

## repeatedly call nested sleep until signal received
while :; do
    sleep_a
done

## rest of script after sleep
printf "control returned to script\ncontinuing to process commands\n"

当脚本被中断时,while 循环下面的命令永远不会到达,因为脚本通过 SIGINT 上调用的函数提供的代码路径退出。

exit

上提供常用命令

您可以通过在 EXIT 上设置 trap 来添加另一层执行。如果您有一组信号并为其设置了 trap,则可以通过一个通用函数结束所有信号。例如,如果您监视多个信号,每个信号 return 指向一个最终调用 exit 的函数,您可以在 EXIT 上设置一个 trap 来调用一个最终函数,其中包含要在之前执行的命令脚本退出。

例如,您可以这样做:

trap final_function EXIT  # calls final_function on exit() from script

在脚本中任何地方调用 exit 会在 EXIT 上调用 trap,在 return 将控制权还给您之前调用 final_function

让我知道通过中断处理取消睡眠的增量级别之一是否可以满足您的需要。从技术上讲,它不是“背景”sleep,但允许您随时有条件地取消睡眠return在您的脚本中控制您选择的任何位置。