繁体   English   中英

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

[英]Passing a password to KLOG from within a script, using `subprocess.POPEN`

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

这非常简单。 除非我尝试应用以下逻辑:“如果用户不是KLOGed用户,请运行KLOG并要求输入密码”。

我使用subprocess.Popen('klog')password:提示确实出现在终端上。 但是,当我编写密码时,它实际上会回显到终端,更糟糕的是,在按回车键时什么也没有发生。

编辑:

在亚历克斯做出快速正确的答复后,我解决了以下问题:

  • 我从模块目录中删除了所有*.pyc文件(是的-这*.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

显然,您的脚本(或稍后会生成的其他内容)和运行klog的子klog正在争用/dev/tty ,并且子进程正在丢失(毕竟,您没有调用返回对象的wait方法)来自subprocess.Popen ,以确保您等到它终止才继续,所以某种竞争条件就不足为奇了。

如果wait还不够,我会通过以下方法解决此问题:

pwd = getpass.getpass('password:')

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM