通过python 执行 nohup 不生效的解决


Posted in Python onApril 16, 2020

通过paramiko模块ssh登录linux,然后用exec_command方法执行带有nohup的shell命令不生效,python脚本如下:

import paramiko
import time
 
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.1.2', 22, 'root', '123456')
ssh.exec_command('nohup ping localhost & \n')
time.sleep(1)

脚本执行完之后ping进程并没有继续运行,这可能是因为exec_command执行完之后立刻关闭通道的原因,换用invoke_shell可以正常运行:

import paramiko
import time
 
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.1.2', 22, 'root', '123456')
chan = ssh.invoke_shell()
chan.send('nohup ping localhost & \n')
time.sleep(1)

注意,命令最后的回车\n和延时必不可少

补充知识:paramiko远程服务器nohup阻塞问题

一、需求描述:

需要来回切换多台服务器(脚本命令不太熟),就用了python的paramiko模块进行远程连接服务器,控制程序的停止和启动。安装:pip install paramiko

二、问题描述:

import paramiko
 
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.0.3', port=22, username='xxx')
# 执行命令
stdin, stdout, stderr = ssh.exec_command('cd ~/ ; nohup python3.6 run_test.py > nohup_test.log 2>&1 &')
# 获取命令结果
result = stdout.read()
# 关闭连接
ssh.close()

这样连接服务器的时候确实可以执行,但是遇到会阻塞的任务时,就无法生效,找了很多方法,最后发现这个比较有效。

三、解决方法

import paramiko
 
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.0.3', port=22, username='xxx', key=private_key)
# 添加下面代码
transport = ssh.get_transport()
channel = transport.open_session()
# 执行命令 此方法没有返回值
channel.exec_command('cd ~/ ; nohup python3.6 run_test.py > nohup_test.log 2>&1 &')
 
# 关闭连接
ssh.close()

四、类的调用实现:

简单测试,见下面代码

# -*- coding: utf-8 -*-
"""
20190330
"""
 
import paramiko
import time
from confs.log import logger # 自行导入logging模块即可
 
 
class EasyConnectHandle(object):
  """操作远程服务器"""
 
  def __init__(self, connect_host_name:dict):
    """初始化参数"""
    """
      "test":{
        "ip":"192.168.0.189",
        "user_name":"xxxx",
        "pwd":"huhuhu"
      },
    """
    self.connect_host = connect_host_name
    self.ssh = paramiko.SSHClient()
    self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 允许连接陌生服务器
    self.ssh.connect(hostname=self.connect_host["ip"], port=22, username=self.connect_host["user_name"],
             password=self.connect_host["pwd"], timeout=10) # 初始化的时候连接到新的服务器
    logger.info(f"登录服务器---{self.connect_host['ip']}成功:")
 
  def __new__(cls, *args, **kwargs):
    """单例模式"""
    if not hasattr(cls, '_instance'):
      cls._instance = super(EasyConnectHandle, cls).__new__(cls)
    return cls._instance
 
  def exec(self, cmd=""):
    """执行操作"""
    stdin, stdout, stderr = self.ssh.exec_command(cmd)
    return stdout.read().decode()
 
  def quit(self):
    """断开服务器"""
    self.ssh.close()
    logger.info(f"退出服务器---{self.connect_host['ip']}成功")
 
if __name__ == '__main__':
  test_host = {
    "test": {
        "ip": "192.168.0.111",
        "user_name": "xxxx",
        "pwd": "xxxx",
        "jobs": [
          {
            "path": "/home/lemon",
            "type": "touch test_1.sh"
          },
          {
            "path": "/home/lemon",
            "type": "touch test_2.sh"
          }
        ]
      }
    }
  for i in ["test"]:
    easy_conn = EasyConnectHandle(test_host[i])
    transport = easy_conn.ssh.get_transport()
    if len(test_host[i].get("jobs", [])) >= 1:
      for job in test_host[i]["jobs"]:
        channel = transport.open_session()
        channel.exec_command(f"cd {job['path']};{job['type']}")
        logger.info(f"服务器---{easy_conn.connect_host['ip']}执行---cd {job['path']};{job['type']}---成功")
        time.sleep(2)
    else:
      logger.info(f"服务器---{easy_conn.connect_host['ip']}暂时没有任务")
    easy_conn.quit()

以上这篇通过python 执行 nohup 不生效的解决就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python之import机制详解
Jul 03 Python
python中元类用法实例
Oct 10 Python
Python的SQLalchemy模块连接与操作MySQL的基础示例
Jul 11 Python
通过python将大量文件按修改时间分类的方法
Oct 17 Python
Python提取特定时间段内数据的方法实例
Apr 01 Python
使用 Python 玩转 GitHub 的贡献板(推荐)
Apr 04 Python
Django stark组件使用及原理详解
Aug 22 Python
详解Python绘图Turtle库
Oct 12 Python
Python 中判断列表是否为空的方法
Nov 24 Python
python3爬虫中引用Queue的实例讲解
Nov 24 Python
selenium如何定位span元素的实现
Jan 13 Python
浅析Python OpenCV三种滤镜效果
Apr 11 Python
在python中使用nohup命令说明
Apr 16 #Python
VS2019+python3.7+opencv4.1+tensorflow1.13配置详解
Apr 16 #Python
python实现程序重启和系统重启方式
Apr 16 #Python
Mac PyCharm中的.gitignore 安装设置教程
Apr 16 #Python
jupyter notebook 重装教程
Apr 16 #Python
Pycharm 使用 Pipenv 新建的虚拟环境(图文详解)
Apr 16 #Python
Python实现Word表格转成Excel表格的示例代码
Apr 16 #Python
You might like
通过html表格发电子邮件
2006/10/09 PHP
杏林同学录(八)
2006/10/09 PHP
php编程实现获取excel文档内容的代码实例
2011/06/28 PHP
php检测数组长度函数sizeof与count用法
2014/11/17 PHP
javascript下查找父节点的简单方法
2007/08/13 Javascript
这段js代码得节约你多少时间
2011/12/20 Javascript
checkbox全选所涉及到的知识点介绍
2013/12/31 Javascript
jquery 操作css样式、位置、尺寸方法汇总
2014/11/28 Javascript
详解AngularJS中的作用域
2015/06/17 Javascript
JavaScript iframe数据共享接口实现方法
2016/01/06 Javascript
深入理解JavaScript中的块级作用域、私有变量与模块模式
2016/10/31 Javascript
Javascript 链式作用域详细介绍
2017/02/23 Javascript
jQuery extend()详解及简单实例
2017/05/06 jQuery
在vue.js中使用JSZip实现在前端解压文件的方法
2018/09/05 Javascript
node上的redis调用优化示例详解
2018/10/30 Javascript
详解js创建对象的几种方式和对象方法
2021/03/01 Javascript
pandas获取groupby分组里最大值所在的行方法
2018/04/20 Python
Python实现快速傅里叶变换的方法(FFT)
2018/07/21 Python
PyQt5响应回车事件的方法
2019/06/25 Python
在python中画正态分布图像的实例
2019/07/08 Python
python实现一行输入多个值和一行输出多个值的例子
2019/07/16 Python
Python中的sys.stdout.write实现打印刷新功能
2020/02/21 Python
基于Python爬取爱奇艺资源过程解析
2020/03/02 Python
浅谈Keras中shuffle和validation_split的顺序
2020/06/19 Python
python实现录制全屏和选择区域录屏功能
2021/02/05 Python
html5定位获取当前位置并在百度地图上显示
2014/08/22 HTML / CSS
html5清空画布方法(三种)
2017/10/16 HTML / CSS
英国最大的独立家具零售商:Furniture Village
2016/09/06 全球购物
薇姿法国官网:Vichy法国
2021/01/28 全球购物
linux面试题参考答案(11)
2012/05/01 面试题
2014七年级班主任工作总结
2014/12/05 职场文书
2014年个人教学工作总结
2014/12/09 职场文书
2015年项目工作总结
2015/04/29 职场文书
PHP实现考试倒计时功能代码
2021/04/16 PHP
python基于tkinter制作下班倒计时工具
2021/04/28 Python
Python实现老照片修复之上色小技巧
2021/10/16 Python