使用`subprocess.POPEN`从脚本中将密码传递给KLOG

时间:2010-08-23 23:56:07

标签: python subprocess system-calls

我正在编写的一系列应用程序要求用户能够使用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

1 个答案:

答案 0 :(得分:2)

显然,您的脚本(或稍后产生的其他内容)和运行klog的子进程正在“竞争”/dev/tty - 并且子流程正在丢失(毕竟,您不是调用从wait返回的对象的subprocess.Popen方法,以确保在继续之前等到它终止,因此某种竞争条件不会令人感到意外。

如果wait不够,我会通过添加

来解决这个问题
pwd = getpass.getpass('password:')
Python代码中的

(当然在顶部有import getpass),然后使用klog参数和-pipe运行stdin=subprocess.PIPE,并编写pwd到该管道(调用从subprocess.Popen返回的对象的communicate方法。)