Trate de no usar shell=True
si puedes evitarlo. es mejor tokenizar el comando usted mismo para ayudar a sh.
subprocess.call(["psql", "-U", "{user}", "-h", "{ip}", "-d", "{db}", "-w", "{pw}", "-c", "{copy statement}"])
En este caso, su declaración de copia podría ser tal como se pasa a psql textualmente, porque no hay shell citando cuestiones a tener en cuenta. (N.B. todavía tengo que citar esto para python, por lo que la cadena permanecería como está).
Si aún desea usar shell=True
entonces tienes que escapar del literal de cadena tanto para python como para concha
"\"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\\\"' NULL ''\""
creará una cadena en python que será
"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\"' NULL ''\"
¡Que es lo que descubrimos que necesitábamos en nuestro caparazón en primer lugar!
Editar (aclarando algo de los comentarios):
subprocess.call
, cuando no se usa shell=True
, toma un iterable de argumentos.
Entonces podrías tener
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)
Consulte https://docs.python.org/2/library/ subproceso.html#subproceso.llamar o https://docs.python.org/3/library/ subproceso.html#subproceso.llamar
edición adicional:- Tenga en cuenta que para evitar la inyección de shell, debe utilizar el método descrito aquí. Consulte la sección de advertencia de https://docs.python. org/2/library/subprocess.html#frequently-used-arguments