Run shell command with input redirections from pyt

2019-04-05 00:15发布

问题:

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.

回答1:

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)


回答2:

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


回答3:

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.