通过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中的split()函数的使用方法
Apr 07 Python
详解python中字典的循环遍历的两种方式
Feb 07 Python
浅谈django开发者模式中的autoreload是如何实现的
Aug 18 Python
Python实现的单向循环链表功能示例
Nov 10 Python
解决pycharm运行时interpreter为空的问题
Oct 29 Python
python将一组数分成每3个一组的实例
Nov 14 Python
使用python实现滑动验证码功能
Aug 05 Python
Python之关于类变量的两种赋值区别详解
Mar 12 Python
python代数式括号有效性检验示例代码
Oct 04 Python
django注册用邮箱发送验证码的实现
Apr 18 Python
Python机器学习之基于Pytorch实现猫狗分类
Jun 08 Python
python工具dtreeviz决策树可视化和模型可解释性
Mar 03 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 图像处理类1
2009/06/15 PHP
php curl 伪造IP来源的实例代码
2012/11/01 PHP
php删除字符串末尾子字符,删除开始字符,删除两端字符(实现代码)
2013/06/27 PHP
ThinkPHP实例化模型的四种方法概述
2014/08/22 PHP
Yii2 队列 shmilyzxt/yii2-queue 简单概述
2017/08/02 PHP
PHP实现财务审核通过后返现金额到客户的功能
2019/07/04 PHP
分别用marquee和div+js实现首尾相连循环滚动效果,仅3行代码
2011/09/21 Javascript
javascript 正则表达式相关应介绍
2012/11/27 Javascript
js获取ajax返回值代码
2014/04/30 Javascript
javascript if条件判断方法小结
2014/05/17 Javascript
node.js中的forEach()是同步还是异步呢
2015/01/29 Javascript
js实现每日自动换一张图片的方法
2015/05/04 Javascript
javascript自定义右键弹出菜单实现方法
2015/05/25 Javascript
使用JavaScript判断用户输入的是否为正整数(两种方法)
2017/02/05 Javascript
javascript闭包功能与用法实例分析
2017/04/06 Javascript
Vue实现内部组件轮播切换效果的示例代码
2018/04/07 Javascript
详解从react转职到vue开发的项目准备
2019/01/14 Javascript
Vue实现导航栏菜单
2020/08/19 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
2020/09/09 Javascript
py2exe 编译ico图标的代码
2013/03/08 Python
python如何通过protobuf实现rpc
2016/03/06 Python
Python进程间通信Queue实例解析
2018/01/25 Python
Python实现求一个集合所有子集的示例
2018/05/04 Python
wxPython实现列表增删改查功能
2019/11/19 Python
Python爬虫爬取电影票房数据及图表展示操作示例
2020/03/27 Python
详解CSS3实现响应式手风琴效果
2020/06/10 HTML / CSS
canvas绘制树形结构可视图形的实现
2020/04/03 HTML / CSS
香港艺人陈冠希创办的潮流品牌:JUICESTORE
2021/03/04 全球购物
路由表示做什么用的?在linux环境中怎么来配置一条默认路由?
2013/06/07 面试题
物业管理毕业生个人的求职信
2013/11/30 职场文书
安全事故检讨书
2014/01/18 职场文书
教师新年寄语
2014/04/03 职场文书
2015年党员自评材料
2014/12/17 职场文书
质量负责人岗位职责
2015/02/15 职场文书
js前端设计模式优化50%表单校验代码示例
2022/06/21 Javascript
JS前端宏任务微任务及Event Loop使用详解
2022/07/23 Javascript