我在现有的工作系统中添加了几个部分。 有一个控制机器(本地Linux PC)运行一些测试脚本,涉及通过SSH远程向多台不同的机器发送大量命令。测试框架使用 Python 编写,并使用 Fabric 访问不同的计算机。
所有命令都使用通用调用函数处理,简化如下:
def cmd(host, cmd, args):
...
with fabric.api.settings(host_string=..., user='root', use_ssh_config=True, disable_known_hosts=True):
return fabric.api.run('%s %s' % (cmd, args))
发送到每台机器的实际命令通常涉及在远程端运行现有的python脚本。那些python脚本,做一些包括调用外部命令的工作(使用system
和subprocess
)。在远程python脚本完成时,测试PC上调用的run()
命令将返回。
有一次,我需要其中一个远程python脚本来启动后台任务:使用openvpn --config /path/to/config.openvpn
启动openvon服务器和客户端。在普通的python脚本中,我只使用&
:
system('openvpn --config /path/to/config.openvpn > /var/log/openvpn.log 2>&1 &')
当通过Fabric远程调用此脚本时,必须明确使用nohup
,dtach
,screen
等人在后台运行作业。我得到了它:
system("nohup openvpn --config /path/to/config.openvpn > /var/log/openvpn.log 2>&1 < /dev/null &"
Fabric FAQ详细介绍了这一点。 它适用于某些后台命令。
此技术不适用于我需要的所有命令。在某些脚本中,我需要启动后台atop
命令(类固醇上的top
)并将其stdout重定向到文件。
我的代码(注意:使用atop -P
表示可解析的输出):
system('nohup atop -P%s 1 < /dev/null | grep %s > %s 2>&1 &' % (dataset, grep_options, filename))
当通过Fabric远程调用包含该命令的脚本时,会立即终止atop进程。生成输出文件但它是空的。通过SSH登录远程计算机时调用相同的脚本工作正常,atop
命令会在输出文件中定期转储数据。
一些谷歌搜索和挖掘带来了有关使用Fabric的后台作业的有趣信息,但我的问题似乎只针对某些类型的后台作业。我试过了:
nohup
替换为dtach -n
:相同症状看起来我的想法已经不多了。
织物对于我们正在做的事情似乎有些过分。我们甚至不使用“fabfile”方法,因为它集成在nose
框架中,我运行它们调用nosetests
。也许我应该使用Fabric来支持手动SSH命令,尽管我不喜欢改变工作系统的想法,因为它不支持我的一个新模块。
答案 0 :(得分:0)
在我的环境中,看起来它正在运作
from fabric.api import sudo
def atop():
sudo('nohup atop -Pcpu 1 </dev/null '
'| grep cpu > /tmp/log --line-buffered 2>&1 &',
pty=False)
结果:
fabric:~$ fab atop -H web01
>>>[web01] Executing task 'atop'
>>>[web01] sudo: nohup atop -Pcpu 1 </dev/null | grep cpu > /tmp/log --line-buffered 2>&1 &
>>>
>>>Done.
web01:~$ cat /tmp/log
>>>cpu web01 1374246222 2013/07/20 00:03:42 361905 100 0 5486 6968 0 9344927 3146 0 302 555 0 2494 100
>>>cpu web01 1374246223 2013/07/20 00:03:43 1 100 0 1 0 0 99 0 0 0 0 0 2494 100
>>>cpu web01 1374246224 2013/07/20 00:03:44 1 100 0 1 0 0 99 0 0 0 0 0 2494 100
...
atop命令可能需要超级用户。这不起作用
from fabric.api import run
def atop():
run('nohup atop -Pcpu 1 </dev/null '
'| grep cpu > /tmp/log --line-buffered 2>&1 &',
pty=False)
另一方面,这项工作。
from fabric.api import run
def atop():
run('sudo nohup atop -Pcpu 1 </dev/null '
'| grep cpu > /tmp/log --line-buffered 2>&1 &',
pty=False)