Bash 作业处理

示例

创造工作

要创建作业,只需&在命令后附加一个:

$ sleep 10 &
[1] 20024

您还可以通过按Ctrl+使正在运行的进程成为工作z

$ sleep 10
^Z
[1]+  Stopped                 sleep 10

背景和前景过程

为了使Process成为前台,该命令fg与%

$ sleep 10 &
[1] 20024

$ fg %1
sleep 10

现在您可以与流程进行交互。要将其带回后台,可以使用bg命令。由于终端会话已占用,您需要先按Ctrl+停止该过程z

$ sleep 10
^Z
[1]+  Stopped              sleep 10

$ bg %1
[1]+ sleep 10 &

由于某些程序员的懒惰,%如果只有一个进程,或者列表中的第一个进程,所有这些命令也可以使用单个命令。例如:

$ sleep 10 &
[1] 20024

$ fg %        # to bring a process to foreground 'fg %' is also working.
sleep 10

要不就

$ %           # laziness knows no boundaries, '%' is also working.
sleep 10

此外,只需键入fg或bg不带任何参数即可处理最后一项工作:

$ sleep 20 &
$ sleep 10 &
$ fg
sleep 10
^C
$ fg
sleep 20

终止正在运行的工作

$ sleep 10 &
[1] 20024

$ kill %1
[1]+  Terminated              sleep 10

睡眠进程在后台运行,进程ID(pid)20024和作业号1。为了引用该过程,您可以使用pid或作业号。如果使用工作编号,则必须在前面加上前缀%。发送的默认终止信号kill是SIGTERM,它允许目标进程正常退出。

一些常见的杀死信号如下所示。要查看完整列表,请运行kill -l。

信号名称信号值影响
SIGHUP1挂断
SIGINT2键盘中断
SIGKILL9杀死信号
SIGTERM15终端信号

启动并终止特定进程

杀死正在运行的进程的最简单方法可能是通过进程名称选择它,如以下示例中使用pkillcommand as

pkill -f test.py

(或)一种更简单的方法pgrep来搜索实际的进程ID

kill $(pgrep -f 'python test.py')

使用grepoverps -ef | grep name_of_process然后杀死与所得pid相关联的进程(进程ID)可以获得相同的结果。在测试环境中使用名称选择进程很方便,但在生产环境中使用脚本时确实很危险:几乎不可能确保名称与您实际要杀死的进程相匹配。在这些情况下,以下方法实际上是非常安全的。

使用以下方法启动最终将终止的脚本。假设您要执行并最终终止的命令是python test.py。

#!/bin/bash

if [[ ! -e /tmp/test.py.pid ]]; then   # Check if the file already exists
    pythontest.py&                   #+and if so do not run another process.
    echo $! > /tmp/test.py.pid
else
    echo -n "ERROR: The process is already running with pid "
    cat /tmp/test.py.pid
    echo
fi

这将在/tmp包含python test.py进程pid的目录中创建一个文件。如果文件已经存在,则假定该命令已在运行,并且脚本返回错误。

然后,当您想杀死它时,使用以下脚本:

#!/bin/bash

if [[ -e /tmp/test.py.pid ]]; then   # If the file do not exists, then the
    kill `cat /tmp/test.py.pid`      #+the process is not running. Useless
    rm /tmp/test.py.pid              #+trying to kill it.
else
    echo "test.py is not running"
fi

这将完全杀死与您的命令关联的进程,而无需依赖任何易失性信息(例如用于运行命令的字符串)。即使在这种情况下,如果文件不存在,脚本也会假定您要终止未运行的进程。

可以轻松地改进此最后一个示例,以多次运行同一命令(例如,附加到pid文件而不是覆盖pid文件),并管理进程在被杀死之前死亡的情况。