首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Python通过Unix pass命令行程序自动设置密码

如何使用Python通过Unix pass命令行程序自动设置密码
EN

Stack Overflow用户
提问于 2018-07-23 04:46:41
回答 1查看 628关注 0票数 0

我正在尝试使用Unix pass程序自动设置新密码。我知道有一个Python库,pexpect,可能会有帮助,但我希望避免使用第三方库。

在使用终端时,流程如下所示:

$ pass insert --force gmail
>> Enter password for gmail: <type in password using masked prompt>
>> Retype password for gmail: <reenter password>

我希望我的函数做什么:

对于输出运行命令(并在testing)

  • Check输出中回显该命令以查找是否存在'password pass insert --force {entry_name}

  • Capture gmail',如果为True
  • ,则将'{password}\n‘写入stdin
  • ,将'{password}\n’写入stdin again

  1. 回显用于测试

的任何错误或消息

问题:

我被困在步骤2中,子进程要么无限期地挂起,要么出现错误超时,要么不产生任何输出。

尝试数:

  • 我尝试过配置Popen(),在不同的时间点使用stdin.write()和communicate().
  • I've set wait()调用。
  • 我尝试了shell=True和shell=False选项(出于安全原因,首选False )

代码

def set_pass_password(entry_name, password):
    from subprocess import Popen, PIPE

    command = ['pass', 'insert', '--force', entry_name]

    sub = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)

    # At this point I assume that the command has run, and that there is an "Enter password..." message
    message = sub.stdout.read()  # also tried readline() and readlines()
    print(message) # never happens, because process hangs on stdout.read()

    if 'password for {}'.format(entry_name) in message:
        err, msg = sub.communicate(input='{p}\n{p}\n'.format(p=password))
        print('errors: {}\nmessage: {}'.format(err, msg))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-23 04:58:57

编辑:最初的答案是关于passwd的,这是用来设置密码的。我后来注意到您使用的是pass,它是一个密钥库(实际上不会更改Unix密码)。pass程序的工作方式不同,如果stdin不是tty,将不会打印提示符。因此,下面这个非常简单的程序可以工作:

def set_pass_password(entry_name, password):
    from subprocess import Popen, PIPE

    command = ['pass', 'insert', '--force', entry_name]

    sub = Popen(command, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE)

    err, msg = sub.communicate(input='{p}\n{p}\n'.format(p=password))
    print('errors: {}\nmessage: {}'.format(err, msg))

if __name__ == "__main__":
    set_pass_password("ttt", "ttt123asdqwe")

(如果命令成功,您将看到stderr和stdout都为空)。

对于passwd命令:

仅供参考:passwd命令将提示符输出到stderr,而不是stdout

注:您可能需要等待第二次提示后才能再次发送密码,而不是在同一次“”中发送两次密码。

对于这个简单的例子,与您的代码类似的代码应该可以工作,但通常您应该在所有管道上使用select,并在另一端准备好时发送/接收数据,这样就不会出现死锁。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51469120

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档