如何在命令输出时隐藏fabric中的密码?
假设我有一个叫做 fabfile.py
的文件,它的内容是这样的:
def setup():
pwd = getpass('mysql password: ')
run('mysql -umoo -p%s something' % pwd)
运行这个文件后,得到的结果是:
[host] run: mysql -umoo -pTheActualPassword
有没有办法让输出的结果变成这样呢?
[host] run: mysql -umoo -p*******
注意:这不是一个关于mysql的问题!
5 个回答
1
当你使用Fabric命令run
时,Fabric并不知道你运行的命令里有没有明文密码。如果不去修改Fabric的源代码,我觉得你无法实现你想要的效果:显示正在运行的命令,但把密码用星号替代。
不过,你可以调整Fabric的输出级别,这样可以对整个Fabric脚本或其中一部分进行设置,让正在运行的命令不显示。虽然这样可以隐藏密码,但缺点是你根本看不到命令。
你可以查看Fabric的文档,了解如何管理输出,链接在这里:管理输出。
1
把密码放在用户的 ~/.my.cnf 文件里的 [client] 部分可能更好。这样你就不需要把密码写在 Python 文件里了。
[client]
password=TheActualPassword
9
与其修改或重写Fabric,不如用一个过滤器来替换标准输出(stdout)或任何输入输出流(iostream)。
下面是一个重写标准输出的例子,用来屏蔽一个特定的密码。这个密码是从Fabric的env.password
变量中获取的,这个变量是通过-I
参数设置的。值得注意的是,你也可以使用正则表达式来实现同样的效果,这样就不需要在过滤器中指定密码了。
我还要提到,这段代码并不是世界上最高效的,但如果你在使用Fabric,可能只是把几个东西拼在一起,更关心的是可管理性而不是速度。
#!/usr/bin/python
import sys
import string
from fabric.api import *
from fabric.tasks import *
from fabric.contrib import *
class StreamFilter(object):
def __init__(self, filter, stream):
self.stream = stream
self.filter = filter
def write(self,data):
data = data.replace(self.filter, '[[TOP SECRET]]')
self.stream.write(data)
self.stream.flush()
def flush(self):
self.stream.flush()
@task
def can_you_see_the_password():
sys.stdout = StreamFilter(env.password, sys.stdout)
print 'Hello there'
print 'My password is %s' % env.password
运行时:
fab -I can_you_see_the_password
Initial value for env.password:
这将产生:
Hello there
My password is [[TOP SECRET]]