通过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求斐波那契数列示例分享
Feb 14 Python
Python中atexit模块的基本使用示例
Jul 08 Python
python决策树之CART分类回归树详解
Dec 20 Python
使用apidocJs快速生成在线文档的实例讲解
Feb 07 Python
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
Jan 05 Python
python文件选择对话框的操作方法
Jun 27 Python
python 反编译exe文件为py文件的实例代码
Jun 27 Python
python单线程下实现多个socket并发过程详解
Jul 27 Python
Python对接六大主流数据库(只需三步)
Jul 31 Python
python3.8下载及安装步骤详解
Jan 15 Python
Python读取VOC中的xml目标框实例
Mar 10 Python
Python Sqlalchemy如何实现select for update
Oct 12 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
什么是MVC,好东西啊
2007/05/03 PHP
用php来改写404错误页让你的页面更友好
2013/01/24 PHP
PHP图片处理之使用imagecopyresampled函数裁剪图片例子
2014/11/19 PHP
PHP四舍五入、取整、round函数使用示例
2015/02/06 PHP
解析PHP的Yii框架中cookie和session功能的相关操作
2016/03/17 PHP
PHP实现的DES加密解密类定义与用法示例
2020/11/02 PHP
js事件监听机制(事件捕获)总结
2014/08/08 Javascript
JavaScript使用replace函数替换字符串的方法
2015/04/06 Javascript
jquery实现漫天雪花飞舞的圣诞祝福雪花效果代码分享
2015/08/20 Javascript
JS实现颜色动态淡化效果
2017/03/06 Javascript
jquery编写日期选择器
2017/03/16 Javascript
详解在vue-cli项目中安装node-sass
2017/06/21 Javascript
vue实现点击图片放大效果
2017/08/15 Javascript
浅谈Redux中间件的实践
2018/07/27 Javascript
深入浅析ng-bootstrap 组件集中 tabset 组件的实现分析
2019/07/19 Javascript
jQuery实现放大镜案例
2020/10/19 jQuery
JavaScript实现网页跨年倒计时
2020/12/02 Javascript
python不换行之end=与逗号的意思及用途
2017/11/21 Python
获取python文件扩展名和文件名方法
2018/02/02 Python
Django使用Celery加redis执行异步任务的实例内容
2020/02/20 Python
Python短信轰炸的代码
2020/03/25 Python
Python读取配置文件(config.ini)以及写入配置文件
2020/04/08 Python
Python爬取微信小程序Charles实现过程图解
2020/09/29 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
Python操作Excel的学习笔记
2021/02/18 Python
解释一下抽象方法和抽象类
2016/08/27 面试题
网游商务专员求职信
2013/10/15 职场文书
青年创业培训欢迎词
2014/01/10 职场文书
应聘面试自我评价
2014/01/24 职场文书
办公室文员工作职责
2014/01/31 职场文书
企业读书活动总结
2014/06/30 职场文书
债务纠纷委托书
2014/08/30 职场文书
雾霾停课通知
2015/04/24 职场文书
战友聚会致辞
2015/07/28 职场文书
Python装饰器的练习题
2021/11/23 Python
JavaScript圣杯布局与双飞翼布局实现案例详解
2022/08/05 Javascript