Python3 run a complex shell command with multiple intended quotations

Python3 run a complex shell command with multiple intended quotations



When i run from bash:


# su -c "psql -d mapping -c "INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');"" postgres



It works fine, but when i try from python:


subprocess.run("su -c "psql -d mapping -c "INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');"" postgres")



It fails, i have tried different quotation marks and all failing. Could you please help?





You are needing to pass the internal slashes to bash, so try \"INSERT......\"" postgres..... Notice the backslash-backslash -- the first one escapes the second, the third one escapes the double quote inside the double-quoted command in bash.
– mrunion
Sep 5 '18 at 19:27






still the same issue with: subprocess.call("su -c "psql -d mapping -c \"INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');\"" postgres")
– user2913139
Sep 5 '18 at 20:01






Instead of calling subprocess.run, use a "print(...)" statement to print out what is getting output. Also, you say it fails -- what error message is being displayed?
– mrunion
Sep 5 '18 at 20:03





if i run print() i got he following error: python3 search.py File "search.py", line 49 print('su -c "psql -d mapping -c \"INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');\"" postgres") ^ SyntaxError: invalid syntax
– user2913139
Sep 5 '18 at 20:06





when run from subprocess.call i got error: FileNotFoundError: [Errno 2] No such file or directory:...............
– user2913139
Sep 5 '18 at 20:07




1 Answer
1



There are two solutions, depending on whether or not you use the shell from Python. The trivial but inefficient solution is to pass the string with shell=True and basically just add Python quoting around it.


shell=True


subprocess.run(r'''su -c "psql -d mapping -c "INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');"" postgres''', shell=True,
# For good measure, you should check its status
check=True)



More efficiently and perhaps in fact more readably, you can remove the shell from the equation, and split the command into strings yourself.


subprocess.run([
'su', '-c',
# The argument to "su -c" should be one string
# Because we escaped the shell, the double quotes don't need escaping
'''psql -d mapping -c "INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');"''',
'postgres'],
check=True)



Notice how with shell=True the first argument is a string which gets passed to the shell, whereas without it, you pass a list of tokens directly to the OS-level exec() or (somewhat less straightforwardly on Windows) CreateProcess(). Notice also how in the first instance I used an r'...' string to avoid having Python meddle with the backslashes in the string.


shell=True


exec()


CreateProcess()


r'...'





For more on this, perhaps see also my answer at stackoverflow.com/questions/4256107/…
– tripleee
Sep 6 '18 at 5:32



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ

Node.js puppeteer - Use values from array in a loop to cycle through pages