19

Seeking means to get Fabric to automatically (instead of user-interactively) interact with shell commands (and not just requests for passwords, but also requested user input when no "stdin/interactive override" like apt-get install -y is available).

This question along with these Fabric docs suggest that Fabric can only "push the interactivity" back to the human user that's running the Fabric program. Seeking to instead fully automate without any human presence. Don't yet have a "real," current problem to solve, just preparing for possible, future obstacle.

Possibly useful to combine with pexpect (or similar, alternative mechanism) if Fabric can't exclusively handle all stdin/prompts automatically? Hoping it doesn't need to be an "either/or" kind of thing. Why not leverage both (pexpect and Fabric) where appropriate, if applicable, in same program/automation?

Community
  • 1
  • 1
Johnny Utahh
  • 2,389
  • 3
  • 25
  • 41

3 Answers3

19

As Glenn, I would say use pexpect; in addition,

have a look at this wrapper I wrote to script the pexpect behaviour from fabric:

from ilogue.fexpect import expect, expecting, run 

prompts = []
prompts += expect('What is your name?','John')
prompts += expect('Where do you live?','New York')

with expecting(prompts):
    run('command')

See also my blogpost on fexpect or how to handle prompts in fabric with pexpect

Jasper van den Bosch
  • 3,169
  • 4
  • 32
  • 55
15

It's not either/or. You just need to run the fab command through pexpect:

child = pexpect.spawn('fab <task>')
child.expect('prompt:')
child.send('reponse to prompt')
... etc

The fab command is just like any other command, so it can be scripted through pexpect.

Glenn
  • 7,262
  • 1
  • 17
  • 23
  • Ah, enlightening. Was previously thinking of running pexpect inside the fabric.py stuff, makes sense (at least) to run vice versa. – Johnny Utahh Dec 08 '11 at 15:48
  • So there's no way you're aware of to use it the other way around, where pexpect's terminal handling can be scripted inside a fabric task? – Shabbyrobe Dec 08 '11 at 22:26
  • I can't think of any way since fabrics `run` returns a string when it's done, so there's no stream for pexpect to expect on. – Glenn Dec 09 '11 at 01:52
  • 4
    This doesn't "get fabric to automatically interact with shell commands" though. This gets pexpect to automatically interact with fabric. – Shabbyrobe Dec 11 '11 at 03:50
  • @Shabbyrobe- true. Alas, my presentation of my question reflected my thought "limitations," but answer still seems to solve my fundamental problem(s). (Have yet to empirically test it.) Do you specifically need Fabric to drive pexpect in as scenario where pexpect-driving-Fabic won't work? Or some other problem that can't be solved by this answer? – Johnny Utahh Dec 11 '11 at 22:02
2

For Windows users, use winpexpect. Make sure to use this version I linked as this version fixes some bugs in previous versions.

import sys, winpexpect
child = winpexpect.winspawn('ftp', ['<ftp host>'])
child.logfile = sys.stdout
child.expect('User.*:')
child.sendline('username')
child.expect('Password:')
child.direct_sendline('password')
child .sendline('ls')
print('Now enter the FTP interactive mode')
child.interact()
drez90
  • 814
  • 5
  • 17