SyntaxError: missing ; before statement - Python

Viewed 85

Let's say I have this snippet

list_command = 'mongo --host {host} --port {port} ' \
             '--username {username} --password {password} --authenticationDatabase {database} < {path}'


def shell_exec(cmd: str):
    import subprocess
    p = subprocess.call(cmd, shell=True)
    return p

Let's say these are the commands I'm trying to run on mongo

use users
show collections
db.base.find().pretty()

If format the string list_command with the appropriate values and pass it to the function with shell=True, it works fine. But I'm trying to avoid it for security purposes. If I call it with shell=False, I get the following error:

2020-08-31T14:08:49.291+0100 E QUERY [thread1] SyntaxError: missing ; before statement @./mongo/user-01-09-2020:1:4 failed to load: ./mongo/user-01-09-2020 253

2 Answers

Your list_command is a shell command: in particular, it includes input redirection (via < {path}), which is a syntactic feature of the shell. To use it you need shell=True.

If you don’t want to use shell=True, you need to change the way you construct the argument (separate arguments need to be passed as separate items of a list rather than as a single string), and you need to pass the script into the standard input via an explicit pipe, by setting its input parameter:

cmd = ['mongo', '--host', '{host}', '--port', …]
subprocess.run(cmd, input=mongodb_script)

Using input raised the following error: TypeError: init() got an unexpected keyword argument 'input'.

I ended up doing the following:

import subprocess
def shell_exec(cmd: str, stdin=None):
  with open(stdin, 'rb') as f:
      return subprocess.call(cmd.split(), stdin=f)
Related