Linux后台运行任务nohup结合用法以及如何精准查找进程并kill后台任务实践

本文主要是介绍Linux后台运行任务nohup结合用法以及如何精准查找进程并kill后台任务实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转自

https://segmentfault.com/a/1190000021265829?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

前言

nohup为什么要跟着&一起使用,不知道大家有没有思考过其中的小区别,另外很多人会推崇使用screen,但是实际生产环境应用场景有限我就不展开了。这次实际遇到的问题主要是因为使用crontab调用了多个不同的nohup后台执行任务,然而代码逻辑中出现对相同文件的占用导致任务进程产生冲突使得system load负载达到600之高,需要kill任务时也不能盲目操作,需要杀掉的进程多且进程名与其它正常的进程名字有交集,需要合理运用pstree找到问题的源头。

Linux后台运行任务nohup结合&用法以及如何精准查找进程并kill后台任务实践

更新历史

2019年11月15日 - 初稿

阅读原文 - https://wsgzao.github.io/post...

扩展阅读


nohup介绍

用途:不挂断地运行命令。

语法:nohup Command [Arg …] [ & ]

  • 无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。
  • 如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。
  • 如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。

退出状态:该命令返回下列出口值:

  • 126 可以查找但不能调用 Command 参数指定的命令。
  • 127 nohup 命令发生错误或不能查找由 Command 参数指定的命令。否则 nohup 命令的退出状态是 Command 参数指定命令的退出状态。

nohup和&的关系

使用 nohup 运行程序:

  • 输出重定向,默认重定向到当前目录下 nohup.out 文件
  • 使用 Ctrl + C 发送 SIGINT 信号,程序关闭
  • 关闭 Shell Session 发送 SIGHUP 信号,程序免疫

使用 & 运行程序:

  • 程序转入后台运行
  • 结果会输出到终端
  • 使用 Ctrl + C 发送 SIGINT 信号,程序免疫
  • 关闭 Shell session 发送 SIGHUP 信号,程序关闭

nohup和&使用实例

一般两个一起组合使用不会受 Ctrl C 和 Shell 关闭的影响:
# 最简单的后台运行
nohup command &
# 输出默认重定向到当前目录下 nohup.out 文件
nohup python main.py &  
# 自定义输出文件(标准输出和错误输出合并到 main.log)
nohup python main.py >> main.log 2>&1 & 
# 与上一个例子相同作用的简写方法
nohup python main.py &> main.log &
# 不记录输出信息
nohup python main.py &> /dev/null &
# 不记录输出信息并将程序的进程号写入 pidfile.txt 文件中,方便后续杀死进程
nohup python main.py &> /dev/null & echo $! > pidfile.txt

由于使用 nohup 时,会自动将输出写入 nohup.out 文件中,如果文件很大的话,nohup.out 就会不停的增大,我们可以利用 Linux 下一个特殊的文件 /dev/null 来解决这个问题,这个文件就相当于一个黑洞,任何输出到这个文件的东西都将消失 只保留输出错误信息 nohup command >/dev/null 2>log & 所有信息都不要 nohup command >/dev/null 2>&1 &

这里解释一下后面的 2>&1 。 这涉及到 Linux 的重定向,其中 0、1、2 分别是标准输入、标准输出、标准错误输出,用来指定需要重定向的标准输入输出。默认情况下是标出输出,也就是 1 。例如我们而上文提到的 2>&1 是 将错误信息重定向到标准输出。

还有就是如果不想让程序输出,Linux 下有一个 /dev/null 的特殊文件,就像一个黑洞,所有输出到这个文件的信息全部会消失,如果你不需要输出日志,这样做就不会导致输出日志文件越来越大,占用存储空间的问题了

其他相关命令
# 结束当前任务
ctrl+c
# 将一个正在前台执行的命令放到后台,并且处于暂停状态
ctrl+z
# 查看任务,返回任务编号 和 进程号
jobs -l
# 将一个在后台暂停的命令,变成在后台继续执行。如果后台中有多个命令,可以用 bg %jobnumber 将选中的命令调出。
bg %jobnumber
# 将后台中的命令调至前台继续运行。如果后台中有多个命令,可以用 fg %jobnumber(是命令编号,不是进程号)将选中的命令调出
fg %jobnumber
编写一个测试脚本
#!/bin/sh
for ((i=1; i<1000; i++))
dod=`date '+%Y-%m-%d %H:%M:%S'`echo "$d print ${i}"sleep 2s
done

查找后台运行程序

  1. 已知pid进程号当然最好了
  2. 使用ps -ef 或者 ps -aux 结合grep过滤
  3. 使用pstree -p确认复杂进程树结构
  4. 使用lsof -i:80查端口获得进程号
  5. 使用netstat -anp | grep 80查端口获得进程号,推荐使用lsof

杀死后台运行程序

kill

kill 命令用来删除执行中的程序或工作。kill 可将指定的信息送至程序。预设的信息为 SIGTERM (15), 可将指定程序终止。若仍无法终止该程序,可使用 SIGKILL (9) 信息尝试强制删除程序,即 kill -9。程序或工作的编号可利用 ps 指令或 job 指令查看。

语法
kill(选项)(参数)

选项

-a:当处理当前进程时,不限制命令名和进程号的对应关系;
-l <信息编号>:若不加<信息编号>选项,则-l参数会列出全部的信息名称;
-p:指定kill 命令只打印相关进程的进程号,而不发送任何信号;
-s <信息名称或编号>:指定要送出的信息;
-u:指定用户。

参数
进程或作业识别号:指定要删除的进程或作业。

实例
列出所有信号名称:

 kill -l1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT
17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU
25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH
29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN
35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4
39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6
59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

只有第 9 种信号 (SIGKILL) 才可以无条件终止进程,其他信号进程都有权利忽略,下面是常用的信号:

HUP     1    终端断线
INT     2    中断(同 Ctrl + C)
QUIT    3    退出(同 Ctrl + \)
TERM   15    终止
KILL    9    强制终止
CONT   18    继续(与STOP相反, fg/bg命令)
STOP   19    暂停(同 Ctrl + Z)

先用 ps 查找进程,然后用 kill 杀掉:

ps -ef | grep vim
root      3268  2884  0 16:21 pts/1    00:00:00 vim install.log
root      3370  2822  0 16:21 pts/0    00:00:00 grep vimkill 3268
kill 3268
-bash: kill: (3268) - 没有那个进程

killall

killall 和 pill 命令差不多都是使用进程的名称来杀死进程,使用此指令可以杀死一组同名进程。我们可以使用 kill 命令杀死指定进程 PID 的进程,如果要找到我们需要杀死的进程,我们还需要在之前使用 ps 等命令再配合 grep 来查找进程,而 killall 把这两个过程合二为一,是一个很好用的命令。

语法
killall(选项)(参数)

选项

-e:对长名称进行精确匹配;
-l:忽略大小写的不同;
-p:杀死进程所属的进程组;
-i:交互式杀死进程,杀死进程前需要进行确认;
-l:打印所有已知信号列表;
-q:如果没有进程被杀死。则不输出任何信息;
-r:使用正规表达式匹配要杀死的进程名称;
-s:用指定的进程号代替默认信号“SIGTERM”;
-u:杀死指定用户的进程。

参数
进程名称:指定要杀死的进程名称。

实例
杀死所有同名进程

killall vi

使用pstree查找和杀死复杂进程

常见的3个kill命令

  • kill
  • pkill
  • killall

搭配查找进程命令

  • pidof
  • pstree
# 已知进程号,启动时输出后台运行程序的进程号,然后读取进程号杀死后台程序:
kill -9 `cat pidfile.txt`# 进程数量较多且有规律,不和其他正常进程冲突
killall 进程名
kill -9 $(pidof 进程名)# 进程数量多,规律不明显,混了正常进程
pstree -p# 复杂点的情况比如像我遇到的真实案例
|-crond(127436)-+-crond(138887)---bash(138892)---bash(138895)---grep(140604)
|               |-crond(139310)---bash(139323)---bash(139324)---python(139431)
|               |-crond(139311)---bash(139325)---bash(139331)---python(139452)
|               |-crond(139312)---bash(139318)---bash(139319)---python(139442)
|               |-crond(139313)---bash(139317)---bash(139320)---python(139444)
|               |-crond(139314)---bash(139329)---bash(139340)---python(139443)
|               |-crond(139315)---bash(139327)---bash(139339)---grep(140768)
|               |-crond(139651)---bash(139660)---bash(139661)---python(139915)
|               |-crond(139652)---bash(139664)---bash(139666)---python(139916)
|               |-crond(139653)---bash(139663)---bash(139665)---python(139914)
|               |-crond(139654)---bash(139675)---bash(139683)---python(139918)
|               |-crond(139655)---bash(139668)---bash(139677)---python(139913)
|               `-crond(139656)---bash(139669)---bash(139682)---grep(139780)# 如果你喜欢用grep也没有问题,多设置几个过滤条件语句组合在一起即可
ps -ef | grep 'python' | grep -v grep | awk '{print $2}' |xargs kill -9

参考文章

Linux 后台运行任务 nohup 和 &

3 Easy Ways to Kill or Terminate a Process on Linux

这篇关于Linux后台运行任务nohup结合用法以及如何精准查找进程并kill后台任务实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/578141

相关文章

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n