popen2.popen2,3,4 from Python 2.0 on NT 4.0 SP5
mdtompkins at home.com
Thu Nov 2 18:40:14 CET 2000
Much appreciated to everyone for their comments.
There were four errors that I was testing against, and it seems that closing
child_stdin deals with the hang problem for 3 of the 4. sqlloader will gpf
for 8.1.6 on NT, if the input file is missing, but the control file exists.
1. Invalid login/password - sqlplus goes into interactive mode
2. Invalid service name - sqlplus goes into interactive mode
3. Invalid file - sqlplus goes into interactive mode.
4. sqlldr with valid control file, but missing data file.
closing child_stdin deals with the first 3 very nicely. When sqlplus goes
into interactive mode for 1&2, it gives 2 retries to enter the correct
username/password (even though an invalid service name should request a
different service name, I should think). For an invalid file, the sql>
prompt is displayed. These two different ways of dealing with errors cannot
be anticipated in advance. Closing child_stdin appears to be the only
workable solution. Closing child_stdin does not terminate a running process
(which I thought it might).
sqlldr is the utility used to load data into Oracle, according to various
formats specified in a control file. sqlldr uses the control file to
determine the data file name and structure. For case 4, at least on Oracle
8.1.6, sqlldr crashes with a gpf, as soon as the command is executed. A
dialog box is displayed, indicating an uncaught exception. I'm hoping that
sqlldr is fixed for 8.1.7, but in the mean time, it raises the issue of
dealing with uncaught exceptions raised in the child process, and what to do
x=popen2.popen3('sqlldr silent=header userid=pf/pf at dds230pf3
except Exception, variable:
print 'caught', Exception, variable
However, the uncaught exception was not captured by the Python environment.
Of course, I can test for the existence of the data file, before dynamically
creating the call to load the data file, thereby avoiding the uncaught
exception altogether, so its no big deal. But as a general solution, it
should be possible to deal with bad behaving child processes in a platform
independent manner, such that the robustness of the application is not
compromised (if only because one can never anticipate when foobar will
Jake Speed wrote:
> db3l at fitlinxx.com (David Bolen) wrote in
> <uu29u2f8d.fsf at ctwd0143.fitlinxx.com>:
> >speed@?.com (Jake Speed) writes:
> >> If you just use popen(cmd, "r"), won't it take stdin from the console?
> >> I suppose you could use "echo | sqlplus user/pass @file"...
> >> ...or "rem | sqlplus user/pass @file" for Windows.
> >No, if you just used os.popen() then there is no stdin for the child
> >process (e.g., no file handle is opened). In fact, occasionally some
> >processes don't like this if they're written to assume they can make
> >some calls against stdin before they generate their output.
> I just did this:
> import sys, os
> p = os.popen("sqlplus scott/tiger @nosuchfile")
> print p.readlines()
> ..and it hangs, with or without readlines. 'truss -f' shows
> that sqlplus is blocking on 'read(0, ...)'. When I type 'exit'
> at the console, the process shows 'read(0, " e x i t\n", 1024)'
> and exits. When the command is changed to "echo | sqlplus ...",
> the read returns 0 and sqlplus exits.
More information about the Python-list