3

I have a simple script (child.py) as below:

#!/usr/bin/env python
import pexpect

def ency():
    child = pexpect.spawn("cryptsetup luksChangeKey /mnt/ency")
    child.expect('Enter passphrase to be changed:')
    child.sendline('password-old')
    child.expect('Enter .*: ')
    child.sendline('password-new')
    child.expect('Verify .*: ')
    child.sendline('password-new')
    child.interact()

ency()

I invoke this script using a different script (master.sh)

#!/bin/bash
python child.py 

The code run successfully when I run child.py, but when I envoke child.py using master.sh, I get the following error:

Traceback (most recent call last):
  File "child.py", line 15, in <module>
    ency()
  File "child.py", line 13, in ency
    child.interact()
  File "/usr/lib/python2.7/site-packages/pexpect-4.2.1-py2.7.egg/pexpect/pty_spawn.py", line 740, in interact
    mode = tty.tcgetattr(self.STDIN_FILENO)
termios.error: (25, 'Inappropriate ioctl for device')

Note that I am invoking master.sh using PowerCLI. I also tried to invoke child.py directly using PowerCLI's Invoke-vmscript –vm vmname –scripttext “python child.py” and still get the same behavior.

Any ideas or suggestions on how to resolve this?

Thanks

pynexj
  • 19,215
  • 5
  • 38
  • 56
Taleeb
  • 125
  • 1
  • 8
  • Is `master.py` a shell script? Why `python child.py`? – pynexj Dec 30 '16 at 15:33
  • master is a python file, child is a bash script. I edited my question to reflect this. thank you for pointing this. – Taleeb Dec 30 '16 at 17:30
  • 1
    *master is a python file, child is a bash script*, are you sure it's not the other way around @Taleeb? Also, how do you call `master.py`? – Gabriel Dec 30 '16 at 17:41
  • http://stackoverflow.com/a/1402389/2988730. Not a dupe, just a possible solution. – Mad Physicist Dec 30 '16 at 17:45
  • @Gabriel master is shell script, I call master with `sh master.sh`. – Taleeb Dec 30 '16 at 17:55
  • @MadPhysicist Thanks to your link, I now see what could be causing this issue, but not sure how to resolve it. – Taleeb Dec 30 '16 at 17:56
  • Without more info on the error I can not be sure, but for some reason it looks like the child process does not end up connected to a tty when you run it from a subshell instead of the command-line directly. – Mad Physicist Dec 30 '16 at 17:59
  • This fails for me with the error `pexpect.exceptions.ExceptionPexpect: The command was not found or was not executable: cryptsetup.` Is there some other file needed to run this? – Gabriel Dec 30 '16 at 18:03
  • 1
    @Gabriel. cryptsetup is part of the LUKS management suite. If you do not have that installed, try running against some other program that you have that takes a non-trivial set of inputs. – Mad Physicist Dec 30 '16 at 18:04
  • And that's my cue to leave :) I assumed this was a simple script. Sorry I can't help you any further @Taleeb, good luck. – Gabriel Dec 30 '16 at 18:08
  • @Gabriel you can run almost the same script with `child = pexpect.spawn("passwd root")` it should produce similar output, of course you have to change your child expect to something similar to : `child.expect('.*: ')` Thanks – Taleeb Dec 30 '16 at 18:16
  • From the traceback information, it seems that the `child.interact()` call is the problem. That makes me wonder how exactly the `master.sh` script is being started? Am I correct in thinking that it is not started by you on the command line, but using some other method? In that case, at that point there simply is no terminal yet to provide interactive input. Perhaps some more background about what you're trying to accomplish can help to suggest a workaround... – brm Dec 30 '16 at 19:24
  • @brm You are correct, I am invoking master.sh using powershell. I also tried to invoke child directly using powershell `Invoke-vmscript –vm vmname –scripttext “python child.py”` still get the same behavior. – Taleeb Dec 30 '16 at 19:42
  • It seems to me that inside your `master.sh` script, you should start some kind of terminal that the `client.py` program can use for interactive input. On my Linux system for example, I can use `xterm -e "python client.py"` to accomplish this. I don't know enough about powershell or about your setup in general to give a useful suggestion though. – brm Dec 30 '16 at 19:46

1 Answers1

2

Since you are running the pexpect script on a VM I suppose you don't really need to interact with it. So just replace

child.interact()

with

child.expect(pexpect.EOF)  # also use the `timeout` argument if necessary

to wait for the child to complete.


According to the doc, interact()

gives control of the child process to the interactive user (the human at the keyboard). Keystrokes are sent to the child process, ...

pynexj
  • 19,215
  • 5
  • 38
  • 56