12

What I'd like to achieve is the launch of the following shell command:

mysql -h hostAddress -u userName -p userPassword 
databaseName < fileName

From within a python 2.4 script with something not unlike:

cmd = ["mysql", "-h", ip, "-u", mysqlUser, dbName, "<", file]
subprocess.call(cmd)

This pukes due to the use of the redirect symbol (I believe) - mysql doesn't receive the input file.

I've also tried:

subprocess.call(cmd, stdin=subprocess.PIPE)

no go there ether

Can someone specify the syntax to make a shell call such that I can feed in a file redirection ?

Thanks in advance.

2
  • you should use a Python mysql interface instead of calling external mysql client Commented Sep 10, 2010 at 1:02
  • @user131527 The interface would work in this case yes. I was interested in how to redirect the file from within python anyway and this served as a good example Commented Sep 14, 2010 at 19:29

3 Answers 3

11

You have to feed the file into mysql stdin by yourself. This should do it.

import subprocess
...
filename = ...
cmd = ["mysql", "-h", ip, "-u", mysqlUser, dbName]
f = open(filename)
subprocess.call(cmd, stdin=f)
Sign up to request clarification or add additional context in comments.

Comments

5

The symbol < has this meaning (i. e. reading a file to stdin) only in shell. In Python you should use either of the following:

1) Read file contents in your process and push it to stdin of the child process:

fd = open(filename,  'rb')
try:
    subprocess.call(cmd, stdin=fd)
finally:
    fd.close()

2) Read file contents via shell (as you mentioned), but redirect stdin of your process accordingly:

# In file myprocess.py
subprocess.call(cmd, stdin=subprocess.PIPE)

# In shell command line
$ python myprocess.py < filename

2 Comments

It may be related to my config but specifying subprocess.PIPE as stdin just hung. Reading as a file worked well. Thanks!
@Sean, Possibly subprocess.call(cmd, stdin=subprocess.PIPE) in "2)" was meant to be subprocess.call(cmd, stdin=sys.stdin)?
0

As Andrey correctly noticed, the < redirection operator is interpreted by shell. Hence another possible solution:

import os
os.system("mysql -h " + ip + " -u " + mysqlUser + " " + dbName)

It works because os.system passes its argument to the shell.

Note that I assumed that all used variables come from a trusted source, otherwise you need to validate them in order to prevent arbitrary code execution. Also those variables should not contain whitespace (default IFS value) or shell special characters.

2 Comments

That makes os.system sound far more convenient then subprocess. I was mistaken to think that os.system was being Deprecated. Thanks for the answer.
Well, I would prefer subprocess-solution myself, it's superior in a number of ways (e.g. it should be more portable).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.