5

Python Fabric库无法启动后台进程的问题和解决办法

 2 years ago
source link: https://sund.site/posts/py-fabric/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

问题和处理方法

Python 的 Fabric 库能够方便的远程操作Linux主机执行命令或传输文件。其实现方式就是底层实现ssh协议,例如执行下面代码的run方法,在目标主机上启动一个zabbix后台服务:

from fabric import api
from fabric.tasks import Task


class Zabbix(Task):
    def run(self, kwargs):
        with api.settings(host_string='192.168.1.2', user='root', password='123456'):
            api.run('service zabbix_agentd start')

但是这样操作后虽然 Fabric 的 output 返回结果打印是启动成功,但是ssh登录目标主机,却不见 zabbix_agentd 进程,这说明没有真正启动起来。

我查询了 Fabric 文档,发现需要在api.run里添加参数pty=False

            api.run('service zabbix_agentd start', pty=False)

这样就成功启动了后台进程。

什么是pty?

pty 是 pseudo-tty,众所周知 tty 是 Linux 支持输入与输出的终端设备,在 shell 下执行ps可以查看每个进程对应的tty设备号,如ttys0001

pty 是为了解决远程连接时一方不希望对方直接ssh连接到主机上而诞生的「虚拟设备」,即伪tty,其原理是在远程主机和本地之间同时启动pty端口连接终端,可以类比进程间的通道,pty两端同时执行输入输出操作,如同本地直接连接到远程主机。但是一旦断开本地与远程主机的连接,pty就会结束所有刚才的进程。

根据网上的资料,Github 仓库的 ssh 连接就采用 pty, Github 不希望用户创建一个可与它的主机交互的 ssh 连接,所以采用这种模式。

Fabric 在默认情况下就采用 pty ,所以想要用 fabric 登录目标主机启动后台进程,必须加上 pty=False

https://github.com/fabric/fabric/issues/395 http://ytliu.info/blog/2013/09/28/ttyde-na-xie-shi-er/ http://7056824.blog.51cto.com/69854/276610


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK