通过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抽象类的新写法
Jun 18 Python
Python编程对列表中字典元素进行排序的方法详解
May 26 Python
用python简单实现mysql数据同步到ElasticSearch的教程
May 30 Python
python利用微信公众号实现报警功能
Jun 10 Python
Django框架模板注入操作示例【变量传递到模板】
Dec 19 Python
python在回调函数中获取返回值的方法
Feb 22 Python
python实现socket+threading处理多连接的方法
Jul 23 Python
Django的性能优化实现解析
Jul 30 Python
Django继承自带user表并重写的例子
Nov 18 Python
Pyqt5自适应布局实例
Dec 13 Python
Python列表切片常用操作实例解析
Dec 16 Python
如何基于Django实现上下文章跳转
Sep 16 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
php将字符串转换成16进制的方法
2015/03/17 PHP
php字符串截取函数mb_substr用法实例分析
2019/06/25 PHP
Swoole扩展的6种模式深入详解
2021/03/04 PHP
JavaScript 克隆数组最简单的方法
2009/02/12 Javascript
JQuery 遮罩层实现(mask)实现代码
2010/01/09 Javascript
利用谷歌地图API获取点与点的距离的js代码
2012/10/11 Javascript
js里取容器大小、定位、距离等属性搜集整理
2013/08/19 Javascript
javasciprt下jquery函数$.post执行无响应的解决方法
2014/03/13 Javascript
jquery bind(click)传参让列表中每行绑定一个事件
2014/08/06 Javascript
jquery获得同源iframe内body下标签的值的方法
2014/09/25 Javascript
利用原生JavaScript获取元素样式只是获取而已
2014/10/08 Javascript
浅析JavaScript中命名空间namespace模式
2016/06/22 Javascript
Python中文分词工具之结巴分词用法实例总结【经典案例】
2017/04/15 Python
浅谈Python peewee 使用经验
2017/10/20 Python
numpy中实现ndarray数组返回符合特定条件的索引方法
2018/04/17 Python
python实现随机调用一个浏览器打开网页
2018/04/21 Python
Python数据类型之Set集合实例详解
2019/05/07 Python
Django后台管理系统的图文使用教学
2020/01/20 Python
python生成并处理uuid的实现方式
2020/03/03 Python
python递归调用中的坑:打印有值, 返回却None
2020/03/16 Python
Pycharm Git 设置方法
2020/09/15 Python
HTML5添加鼠标悬浮音响效果不使用FLASH
2014/04/23 HTML / CSS
英国男士时尚购物网站:Stuarts London
2017/10/22 全球购物
Gap英国官网:Gap UK
2018/07/18 全球购物
Oral-B荷兰:牙医最推荐的品牌
2020/02/25 全球购物
接口的多继承会带来哪些问题
2015/08/17 面试题
酒店人事专员岗位职责
2013/12/19 职场文书
社区禁毒工作方案
2014/06/02 职场文书
党的群众路线专项整治方案
2014/11/03 职场文书
终止劳动合同证明书样本
2014/11/19 职场文书
解除劳动合同证明书模板
2014/11/20 职场文书
外贸业务员岗位职责
2015/02/13 职场文书
学年个人总结范文
2015/03/05 职场文书
帝企鹅日记观后感
2015/06/10 职场文书
基层党建工作简报
2015/07/21 职场文书
高温慰问简报
2015/07/21 职场文书