【问题标题】:Passing a password to KLOG from within a script, using `subprocess.POPEN`使用 `subprocess.POPEN` 从脚本中将密码传递给 KLOG
【发布时间】: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


    【解决方案1】:

    显然,您的脚本(或稍后生成的其他内容)和运行 klog 的子进程正在“竞争”/dev/tty - 并且子进程正在失败(毕竟,您没有调用 @987654324从subprocess.Popen 返回的对象的@ 方法,以确保您等到它终止后再继续,因此某种竞争条件不足为奇)。

    如果 wait 不够,我会通过放置来解决这个问题

    pwd = getpass.getpass('password:')
    

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

    【讨论】:

    • 感谢 Alex - -pipe + getpass() 解决方案效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    相关资源
    最近更新 更多