Staraj się nie używać shell=True
jeśli możesz tego uniknąć. lepiej samemu tokenizować polecenie, aby pomóc sh.
subprocess.call(["psql", "-U", "{user}", "-h", "{ip}", "-d", "{db}", "-w", "{pw}", "-c", "{copy statement}"])
W takim przypadku instrukcja kopiowania może wyglądać tak, jak została przekazana dosłownie do psql, ponieważ nie ma powłoki cytowanie kwestii do uwzględnienia. (Uwaga:nadal trzeba to zacytować dla Pythona, więc ciąg pozostanie taki, jak jest).
Jeśli nadal chcesz używać shell=True
musisz uciec od literału ciągu zarówno dla pytona i powłoka
"\"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\\\"' NULL ''\""
utworzy ciąg w pytonie, który będzie
"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\"' NULL ''\"
Właśnie tego dowiedzieliśmy się, że potrzebujemy na naszej powłoce!
Edytuj (wyjaśniając coś z komentarzy):
subprocess.call
, gdy nie używasz shell=True
, przyjmuje iterację argumentów.
Więc możesz mieć
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)
Zobacz https://docs.python.org/2/library/ subprocess.html#subprocess.call lub https://docs.python.org/3/library/ subprocess.html#subprocess.call
dodatkowa edycja :- Pamiętaj, że aby uniknąć wstrzykiwania powłoki, powinieneś używać metody opisanej tutaj. Zobacz sekcję z ostrzeżeniami w https://docs.python. org/2/library/subprocess.html#frequently-used-arguments