【发布时间】:2010-08-23 23:56:06
【问题描述】:
我正在编写的一系列应用程序要求用户能够从具有KLOG 身份验证的文件系统中读取。某些功能要求用户拥有 KLOG 令牌(即经过身份验证),而其他功能则不需要。我写了一个小的 Python 装饰器,这样我就可以在我的模块中重构“你必须是 KLOGed”的功能:
# this decorator is defined in ``mymodule.utils.decorators``
def require_klog(method):
def require_klog_wrapper(*args, **kwargs):
# run the ``tokens`` program to see if we have KLOG tokens
out = subprocess.Popen('tokens', stdout=subprocess.PIPE)
# the tokens (if any) are located in lines 4:n-1
tokens_list = out.stdout.readlines()[3:-1]
if tokens_list == []:
# this is where I launch KLOG (if the user is not authenticated)
subprocess.Popen('klog')
out = method(*args, **kwargs)
return out
return require_klog_wrapper
# once the decorator is defined, any function can use it as follows:
from mymodule.utils.decorators import require_klog
@require_klog
def my_function():
# do something (if not KLOGed, it SHUOLD ask for the password... but it does not!)
这一切都很简单。除非我尝试应用以下逻辑:“如果用户不是 KLOG,则运行 KLOG 并询问密码”。
我使用subprocess.Popen('klog') 执行此操作,并且password: 提示确实会出现在终端上。但是,当我输入密码时,它实际上会回显到终端,更糟糕的是,点击返回时什么也没有发生。
编辑:
经过Alex快速正确的反应,我解决了如下问题:
- 我从我的模块目录中删除了所有
*.pyc文件(是的 - 这有所不同) - 我使用
getpass.getpass()将密码存储在局部变量中 - 我使用
-pipe选项调用了KLOG 命令 - 我通过管道的
write方法将本地存储的密码传递给管道
以下是修正后的装饰器:
def require_klog(method):
def require_klog_wrapper(*args, **kwargs):
# run the ``tokens`` program to see if we have KLOG tokens
out = subprocess.Popen('tokens', stdout=subprocess.PIPE)
# the tokens (if any) are located in lines 4:n-1
tokens_list = out.stdout.readlines()[3:-1]
if tokens_list == []:
args = ['klog', '-pipe']
# this is the custom pwd prompt
pwd = getpass.getpass('Type in your AFS password: ')
pipe = subprocess.Popen(args, stdin=subprocess.PIPE)
# here is where the password is sent to the program
pipe.stdin.write(pwd)
return method(*args, **kwargs)
return require_klog_wrapper
【问题讨论】:
标签: python subprocess system-calls