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

How can I use Python to automate setting a password using the Unix pass command line program

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

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

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

我希望我的函数做什么:

  1. 运行命令pass insert --force {entry_name}
  2. 捕获输出(并回显以进行测试)
  3. 检查输出是否存在 'password for gmail',如果为真
    • 将'{password}\n'写入标准输入
    • 再次将'{password}\n'写入标准输入
  4. 回显任何错误或消息以进行测试

问题:

我卡在了第 2 步。子进程无限期挂起、超时并出现错误,或者不产生任何输出。

尝试次数:


代码:

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))

编辑:原来的答案是关于 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

注意:与其在同一个 'write' 中发送两次密码,您 可能 需要等待第二次提示才能再次发送密码。

对于这种简单的情况,与您的代码类似的代码应该可以工作,但通常您应该在所有管道上使用 select 并在另一端准备好时使用 send/receive 数据,所以您不需要不会出现死锁。