简体   繁体   English

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

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

I'm trying to automate setting new passwords using the Unix pass program. 我正在尝试使用Unix pass程序自动设置新密码。 I understand that there is a Python library, pexpect , that might help, but I would like to avoid using third-party libraries. 我知道有一个Python库pexpect可能会有所帮助,但我想避免使用第三方库。

When using a terminal, the flow looks like this: 使用终端时,流程如下所示:

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

What I would like my function to do: 我想要我的功能做什么:

  1. Run the command pass insert --force {entry_name} 运行命令pass insert --force {entry_name}
  2. Capture the output (and echo it for testing) 捕获输出(并回显以进行测试)
  3. Check output for the presence of 'password for gmail', and if True 检查输出中是否存在“ gmail密码”,如果为True
    • write '{password}\\n' to stdin 在标准输入上写“ {password} \\ n”
    • write '{password}\\n' to stdin again 再次将'{password} \\ n'写入标准输入
  4. Echo any errors or messages for testing 回显任何错误或消息以进行测试

Issues: 问题:

I'm stuck on step 2. The subprocess either hangs indefinitely, times out with an error, or produces no output. 我被困在第2步。子进程无限期挂起,错误超时或不产生任何输出。

Attempts: 尝试次数:

  • I've tried configurations of Popen(), using both stdin.write() and communicate(). 我已经尝试使用stdin.write()和communication()来配置Popen()。
  • I've set wait() calls at various points. 我在各个点设置了wait()调用。
  • I've tried both the shell=True and shell=False options (prefer False for security reasons) 我已经尝试了shell = True和shell = False选项(出于安全原因,最好选择False)

Code : 代码

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

Edit: the original answer was about passwd , which is what's used to set passwords. 编辑:最初的答案是关于passwd ,它是用来设置密码的。 I noticed late that you use pass , which is a keystore (doesn't actually change the Unix password). 后来我注意到您使用pass ,这是一个密钥库(实际上并没有更改Unix密码)。 The pass program works differently and will not print a prompt if stdin is not a tty. 如果stdin不是tty, pass程序的工作方式有所不同,并且不会显示提示。 Therefore the following very simple program works: 因此,以下非常简单的程序可以工作:

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

(you will see that both stderr and stdout are empty, if the command succeeded). (如果命令成功,您将看到stderr和stdout均为空)。

For the passwd command: 对于passwd命令:

FYI: the passwd command outputs the prompt to stderr , not stdout . 仅供参考: passwd命令将提示输出到stderr ,而不是stdout

NOTE: rather than sending the password twice in the same 'write', you might need to wait for the second prompt before sending the password again. 注意:您可能需要等待第二个提示,然后才能再次发送密码,而不是在同一“写”中两次发送密码。

For this simple case, code similar to yours should work, but in general you should use select on all the pipes and send/receive data when the other side is ready, so you don't get deadlocks. 对于这种简单的情况,与您的代码相似的代码应该可以工作,但是通常您应该在所有管道上使用select并在另一侧准备好时发送/接收数据,因此不会出现死锁。

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

相关问题 如何自动化需要 linux 命令行中的两个输入的 python 程序? - How can I automate a python program that requires two inputs in a linux command line? 使用 Python 使用 INIT 文件自动化命令行程序并向其提供命令 - Using Python to Automate Command Line Program with INIT file and Feed Commands to It 如何在python代码中使用unix的“ uniq -c”命令? - How can I use “uniq -c” command of unix in python code? 如何使用python将密码传递给另一个程序 - How to pass password to another program using python 如何使用 python 的命令行脚本在后台运行 python 程序? - How can I run a python program in the background using python's Command Line Scripts? 如何使用./ 通过 Python 脚本执行命令行程序? - How can I execute command line program with ./ via a Python script? 如何将 python 脚本的结果传递给命令行? - How can I pass the result of a python script to the command line? Python 脚本 - 如何从命令行参数将密码作为变量传递 - Python script - how to pass password as variable from command line arguments 如何使用python与命令行程序通信? - How to communicate with command line program using python? 如何使用 cron 在 Raspberry Pi 上自动化 Python 程序? - How can I automate Python program on Raspberry Pi with cron?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM