Cerca di non usare shell=True
se puoi evitarlo. meglio tokenizzare tu stesso il comando per aiutare sh.
subprocess.call(["psql", "-U", "{user}", "-h", "{ip}", "-d", "{db}", "-w", "{pw}", "-c", "{copy statement}"])
In questo caso, la tua dichiarazione di copia potrebbe essere passata a psql alla lettera, perché non ci sono shell citando problemi da tenere in considerazione. (NB devo ancora citarlo per Python, quindi la stringa rimarrebbe così com'è).
Se vuoi ancora usare shell=True
quindi devi sfuggire alla stringa letterale sia per python che guscio
"\"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\\\"' NULL ''\""
creerà una stringa in Python che sarà
"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\"' NULL ''\"
Che è ciò di cui abbiamo scoperto che avevamo bisogno sulla nostra shell in primo luogo!
Modifica (chiarire qualcosa dai commenti):
subprocess.call
, quando non si utilizza shell=True
, accetta un iterabile di argomenti.
Quindi potresti avere
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)
Vedi https://docs.python.org/2/library/ subprocess.html#subprocess.call o https://docs.python.org/3/library/ subprocess.html#subprocess.call
modifica extra :- Si noti che per evitare l'iniezione di shell, è necessario utilizzare il metodo descritto qui. Consulta la sezione di avviso di https://docs.python. org/2/library/subprocess.html#argomenti-usati frequentemente