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。
启动并终止特定进程
杀死正在运行的进程的最简单方法可能是通过进程名称选择它,如以下示例中使用pkillcommandas
pkill -f test.py
(或)一种更简单的方法pgrep来搜索实际的进程ID
kill $(pgrep -f 'python test.py')
使用grepoverps-ef|grepname_of_process然后杀死与所得pid相关联的进程(进程ID)可以获得相同的结果。在测试环境中使用名称选择进程很方便,但在生产环境中使用脚本时确实很危险:几乎不可能确保名称与您实际要杀死的进程相匹配。在这些情况下,以下方法实际上是非常安全的。
使用以下方法启动最终将终止的脚本。假设您要执行并最终终止的命令是pythontest.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包含pythontest.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文件),并管理进程在被杀死之前死亡的情况。