语法错误:缺少;before语句-Python

语法错误:缺少;before语句-Python,python,python-3.x,mongodb,shell,subprocess,Python,Python 3.x,Mongodb,Shell,Subprocess,假设我有这个片段 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, s

假设我有这个片段

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
如果使用适当的值格式化字符串list_命令,并将其传递给具有shell=True的函数,则其工作正常。但出于安全考虑,我尽量避免这样做。 如果我用shell=False调用它,我会得到以下错误:

2020-08-31T14:08:49.291+0100 E查询[thread1]语法错误:缺少;声明@./mongo/user-01-09-2020:1:4之前 未能加载:./mongo/user-01-09-2020 253


您的
list_命令
是一个shell命令:特别是,它包括输入重定向(通过
<{path}
),这是shell的一个语法特性。要使用它,您需要
shell=True

如果不想使用
shell=True
,则需要更改构造参数的方式(单独的参数需要作为列表的单独项传递,而不是作为单个字符串传递),并且需要通过显式管道将脚本传递到标准输入,方法是设置其
input
参数:

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

使用输入引发了以下错误:TypeError:init()获取了意外的关键字参数“input”

我最后做了以下几件事:

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

我的错误是,您需要使用
run
而不是
call
。您的代码可以通过将
try
块替换为
with
来简化。但是整个代码都假设MongoDB脚本是由调用方写入文件的,这让我觉得很不方便,除非这些文件实际上已经存在。变量
p
也是不必要的;返回
子流程的结果。直接调用
。使用
cmd.split()
几乎肯定是个坏主意。如果某个参数包含空格怎么办?首先,最好不要将命令存储在单个字符串中,使用启动列表。谢谢你帮我节省时间!
import subprocess
def shell_exec(cmd: str, stdin=None):
  with open(stdin, 'rb') as f:
      return subprocess.call(cmd.split(), stdin=f)