Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: third_party/pexpect/doc/FAQ.rst

Issue 1398903002: Add third_party/pexpect (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@end-to-end-test
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/pexpect/README.rst ('k') | third_party/pexpect/doc/Makefile » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 FAQ
2 ===
3
4 **Q: Where can I get help with pexpect? Is there a mailing list?**
5
6 A: You can use the `pexpect tag on Stackoverflow <http://stackoverflow.com/quest ions/tagged/pexpect>`__
7 to ask questions specifically related to Pexpect. For more general Python
8 support, there's the python-list_ mailing list, and the `#python`_
9 IRC channel. Please refrain from using github for general
10 python or systems scripting support.
11
12 .. _python-list: https://mail.python.org/mailman/listinfo/python-list
13 .. _#python: https://www.python.org/community/irc/
14
15 **Q: Why don't shell pipe and redirect (| and >) work when I spawn a command?**
16
17 A: Remember that Pexpect does NOT interpret shell meta characters such as
18 redirect, pipe, or wild cards (``>``, ``|``, or ``*``). That's done by a shell n ot
19 the command you are spawning. This is a common mistake. If you want to run a
20 command and pipe it through another command then you must also start a shell.
21 For example::
22
23 child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > log_list.txt"')
24 child.expect(pexpect.EOF)
25
26 The second form of spawn (where you pass a list of arguments) is useful in
27 situations where you wish to spawn a command and pass it its own argument list.
28 This can make syntax more clear. For example, the following is equivalent to the
29 previous example::
30
31 shell_cmd = 'ls -l | grep LOG > log_list.txt'
32 child = pexpect.spawn('/bin/bash', ['-c', shell_cmd])
33 child.expect(pexpect.EOF)
34
35 **Q: The `before` and `after` properties sound weird.**
36
37 A: This is how the -B and -A options in grep works, so that made it
38 easier for me to remember. Whatever makes my life easier is what's best.
39 Originally I was going to model Pexpect after Expect, but then I found
40 that I didn't actually like the way Expect did some things. It was more
41 confusing. The `after` property can be a little confusing at first,
42 because it will actually include the matched string. The `after` means
43 after the point of match, not after the matched string.
44
45 **Q: Why not just use Expect?**
46
47 A: I love it. It's great. I has bailed me out of some real jams, but I
48 wanted something that would do 90% of what I need from Expect; be 10% of
49 the size; and allow me to write my code in Python instead of TCL.
50 Pexpect is not nearly as big as Expect, but Pexpect does everything I
51 have ever used Expect for.
52
53 .. _whynotpipe:
54
55 **Q: Why not just use a pipe (popen())?**
56
57 A: A pipe works fine for getting the output to non-interactive programs.
58 If you just want to get the output from ls, uname, or ping then this
59 works. Pipes do not work very well for interactive programs and pipes
60 will almost certainly fail for most applications that ask for passwords
61 such as telnet, ftp, or ssh.
62
63 There are two reasons for this.
64
65 * First an application may bypass stdout and print directly to its
66 controlling TTY. Something like SSH will do this when it asks you for
67 a password. This is why you cannot redirect the password prompt because
68 it does not go through stdout or stderr.
69
70 * The second reason is because most applications are built using the C
71 Standard IO Library (anything that uses ``#include <stdio.h>``). One
72 of the features of the stdio library is that it buffers all input and
73 output. Normally output is line buffered when a program is printing to
74 a TTY (your terminal screen). Everytime the program prints a line-feed
75 the currently buffered data will get printed to your screen. The
76 problem comes when you connect a pipe. The stdio library is smart and
77 can tell that it is printing to a pipe instead of a TTY. In that case
78 it switches from line buffer mode to block buffered. In this mode the
79 currently buffered data is flushed when the buffer is full. This
80 causes most interactive programs to deadlock. Block buffering is more
81 efficient when writing to disks and pipes. Take the situation where a
82 program prints a message ``"Enter your user name:\n"`` and then waits
83 for you type type something. In block buffered mode, the stdio library
84 will not put the message into the pipe even though a linefeed is
85 printed. The result is that you never receive the message, yet the
86 child application will sit and wait for you to type a response. Don't
87 confuse the stdio lib's buffer with the pipe's buffer. The pipe buffer
88 is another area that can cause problems. You could flush the input
89 side of a pipe, whereas you have no control over the stdio library buffer.
90
91 More information: the Standard IO library has three states for a
92 ``FILE *``. These are: _IOFBF for block buffered; _IOLBF for line buffered;
93 and _IONBF for unbuffered. The STDIO lib will use block buffering when
94 talking to a block file descriptor such as a pipe. This is usually not
95 helpful for interactive programs. Short of recompiling your program to
96 include fflush() everywhere or recompiling a custom stdio library there
97 is not much a controlling application can do about this if talking over
98 a pipe.
99
100 The program may have put data in its output that remains unflushed
101 because the output buffer is not full; then the program will go and
102 deadlock while waiting for input -- because you never send it any
103 because you are still waiting for its output (still stuck in the STDIO's
104 output buffer).
105
106 The answer is to use a pseudo-tty. A TTY device will force line
107 buffering (as opposed to block buffering). Line buffering means that you
108 will get each line when the child program sends a line feed. This
109 corresponds to the way most interactive programs operate -- send a line
110 of output then wait for a line of input.
111
112 I put "answer" in quotes because it's ugly solution and because there is
113 no POSIX standard for pseudo-TTY devices (even though they have a TTY
114 standard...). What would make more sense to me would be to have some way
115 to set a mode on a file descriptor so that it will tell the STDIO to be
116 line-buffered. I have investigated, and I don't think there is a way to
117 set the buffered state of a child process. The STDIO Library does not
118 maintain any external state in the kernel or whatnot, so I don't think
119 there is any way for you to alter it. I'm not quite sure how this
120 line-buffered/block-buffered state change happens internally in the
121 STDIO library. I think the STDIO lib looks at the file descriptor and
122 decides to change behavior based on whether it's a TTY or a block file
123 (see isatty()).
124
125 I hope that this qualifies as helpful. Don't use a pipe to control
126 another application.
127
128 **Q: Can I do screen scraping with this thing?**
129
130 A: That depends. If your application just does line-oriented output then
131 this is easy. If a program emits many terminal sequences, from video
132 attributes to screen addressing, such as programs using curses, then
133 it may become very difficult to ascertain what text is displayed on a screen.
134
135 We suggest using the `pyte <https://github.com/selectel/pyte>`_ library to
136 screen-scrape. The module :mod:`pexpect.ANSI` released with previous versions
137 of pexpect is now marked deprecated and may be removed in the future.
138
139 **Q: I get strange behavior with pexect and gevent**
140
141 A: Pexpect uses fork(2), exec(2), select(2), waitpid(2), and implements its
142 own selector in expect family of calls. pexpect has been known to misbehave
143 when paired with gevent. A solution might be to isolate your pexpect
144 dependent code from any frameworks that manipulate event selection behavior
145 by running it in an another process entirely.
OLDNEW
« no previous file with comments | « third_party/pexpect/README.rst ('k') | third_party/pexpect/doc/Makefile » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698