title: How can I use Python to automate setting a password using the Unix pass command line program
body: <p>I'm trying to automate setting new passwords using the Unix pass program.
  I understand that there is a Python library, <a href="https://pexpect.readthedocs.io/en/stable/" rel="nofollow noreferrer">pexpect</a>, that might help, but I would like to avoid using third-party libraries.</p>
  
  <p><strong>When using a terminal, the flow looks like this:</strong>
  </p>
  
  <pre><code>$ pass insert --force gmail
  &gt;&gt; Enter password for gmail: &lt;type in password using masked prompt&gt;
  &gt;&gt; Retype password for gmail: &lt;reenter password&gt;
  </code></pre>
  
  <p><strong>What I would like my function to do:</strong></p>
  
  <ol>
  <li>Run the command <code>pass insert --force {entry_name}</code></li>
  <li>Capture the output (and echo it for testing)</li>
  <li>Check output for the presence of 'password for gmail', and if True
  
  <ul>
  <li>write '{password}\n' to stdin</li>
  <li>write '{password}\n' to stdin again</li>
  </ul></li>
  <li>Echo any errors or messages for testing</li>
  </ol>
  
  <p><strong>Issues:</strong></p>
  
  <p>I'm stuck on step 2. The subprocess either hangs indefinitely, times out with an error, or produces no output.</p>
  
  <p><strong>Attempts:</strong></p>
  
  <ul>
  <li>I've tried configurations of Popen(), using both stdin.write() and communicate().</li>
  <li>I've set wait() calls at various points.</li>
  <li>I've tried both the shell=True and shell=False options (prefer False for security reasons)</li>
  </ul>
  
  <hr>
  
  <p><strong>Code</strong>:
  </p>
  
  <pre><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))
  </code></pre>