Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><code>subprocess.Popen</code>, when instantiated, runs the program. It does not, however, wait for it -- it fires it off in the background as if you'd typed <code>cmd &amp;</code> in a shell. So, in the code above, you've essentially defined a race condition -- if the inserts can finish in time, it will appear normal, but if not you get the unexpected output. You are not waiting for your first <code>run()</code>'d PID to finish, you are simply returning its <code>Popen</code> instance and continuing.</p> <p>I'm not sure how this behavior contradicts the documentation, because there's some very clear methods on Popen that seem to indicate it is not waited for, like:</p> <pre><code>Popen.wait() Wait for child process to terminate. Set and return returncode attribute. </code></pre> <p>I do agree, however, that the documentation for this module could be improved.</p> <p>To wait for the program to finish, I'd recommend using <code>subprocess</code>'s convenience method, <code>subprocess.call</code>, or using <code>communicate</code> on a <code>Popen</code> object (for the case when you need stdout). You are already doing this for your second call.</p> <pre><code>### START MAIN # copy some rows from a source table to a destination table # note that the destination table is empty when this script is run cmd = 'mysql -u ve --skip-column-names --batch --execute="insert into destination (select * from source limit 100000)" test' subprocess.call(cmd) # check to see how many rows exist in the destination table cmd = 'mysql -u ve --skip-column-names --batch --execute="select count(*) from destination" test' process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) try: count = (int(process.communicate()[0][:-1])) except: count = 0 </code></pre> <p>Additionally, in most cases, you do not need to run the command in a shell. This is one of those cases, but you'll have to rewrite your command like a sequence. Doing it that way also allows you to avoid traditional shell injection and worry less about quoting, like so:</p> <pre><code>prog = ["mysql", "-u", "ve", "--execute", 'insert into foo values ("snargle", 2)'] subprocess.call(prog) </code></pre> <p>This will even work, and will not inject as you'd expect:</p> <pre><code>prog = ["printf", "%s", "&lt;", "/etc/passwd"] subprocess.call(prog) </code></pre> <p>Try it interactively. You avoid the possibilities of shell injection, particularly if you're accepting user input. I suspect you're using the less-awesome string method of communicating with subprocess because you ran into trouble getting the sequences to work :^)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload