Reputation: 3417
I have a working script in Linux that creates ssh-keys. In macOS, it hangs on wait().
import os
import sys
import pexpect
passphrase = os.environ['HOST_CA_KEY_PASSPHRASE']
command = 'ssh-keygen'
child = pexpect.spawn(command, args=sys.argv[1:])
child.expect('Enter passphrase:')
child.sendline(passphrase)
child.wait()
Upvotes: 1
Views: 1538
Reputation: 3417
Finally, I found the problem. It seems that the ssh-keygen
binary is slightly different, and it outputs some things after.
because wait() is a blocking call.
This will not read any data from the child, so this will block forever if the child has unread output and has terminated. In other words, the child may have printed output then called exit(), but, the child is technically still alive until its output is read by the parent.
.wait() docs here
to solve this problem read_nonblocking reads at most size characters from the child application. If there are bytes available to read immediately, all those bytes will be read (up to the buffer size).
.read_nonblocking() docs here
working solution
import os
import sys
import pexpect
passphrase = os.environ['HOST_CA_KEY_PASSPHRASE']
command = 'ssh-keygen'
child = pexpect.spawn(command, args=sys.argv[1:])
child.expect('Enter passphrase:')
child.sendline(passphrase)
# Avoid Hang on macOS
# https://github.com/pytest-dev/pytest/issues/2022
while True:
try:
child.read_nonblocking()
except Exception:
break
if child.isalive():
child.wait()
Upvotes: 2