Snažte se nepoužívat shell=True
pokud se tomu můžete vyhnout. lepší je tokenizovat příkaz sami, abyste pomohli sh.
subprocess.call(["psql", "-U", "{user}", "-h", "{ip}", "-d", "{db}", "-w", "{pw}", "-c", "{copy statement}"])
V tomto případě může být vaše kopie příkazu tak, jak je předána doslovně do psql, protože neexistují žádné shell problémy s citacemi, které je třeba vzít v úvahu. (N.B. to stále musíme citovat pro python, takže řetězec zůstane tak, jak je).
Pokud přesto chcete použít shell=True
pak musíte escapovat řetězcový literál pro python a shell
"\"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\\\"' NULL ''\""
vytvoří v pythonu řetězec, který bude
"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\"' NULL ''\"
Což jsme zjistili, že potřebujeme na našem shellu na prvním místě!
Upravit (něco objasňuje z komentářů):
subprocess.call
, když nepoužíváte shell=True
, bere opakovatelnost argumentů.
Takže byste mohli mít
psql_command = "\"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\\\"' NULL ''\""
# user, hostname, password, dbname all defined elsewhere above.
command = ["psql",
"-U", user,
"-h", hostname,
"-d", dbname,
"-w", password,
"-c", psql_command,
]
subprocess.call(command)
Viz https://docs.python.org/2/library/ subprocess.html#subprocess.call nebo https://docs.python.org/3/library/ subprocess.html#subprocess.call
extra úprava:- Vezměte prosím na vědomí, že abyste se vyhnuli vstřikování shellu, měli byste použít metodu popsanou zde. Viz část s upozorněním na https://docs.python. org/2/library/subprocess.html#frequently-used-arguments