【问题标题】:Subprocess for loop fails with syntax error子进程 for 循环失败并出现语法错误
【发布时间】:2018-07-27 10:55:10
【问题描述】:

我有一个简单的脚本来了解如何在子进程调用中运行 shell for 循环。我在虚拟环境和 BASH shell 中从 GNU/Linux 运行它。

脚本:

from subprocess import call

shellCommand = ['for','c','in','$(seq 1 10)','do','echo','$c','done']
call(shellCommand, shell=True)

还有错误信息:

c: 1: c: Syntax error: Bad for loop variable

我在这里做错了什么?

【问题讨论】:

  • 这不是有效的 shell 语法,不。这不是真正的 Python 问题,直接从 shell 运行相同的命令会失败。
  • 对于 shell 命令,只需传入单个字符串,而不是列表:shell_command = 'for c in $(seq 1 10); do echo $c; done', then call(shell_command, shell=True)`。注意我添加的分号。

标签: python shell subprocess


【解决方案1】:

有两个问题:

  • 您的 shell 语法无效,缺少关键分号或换行符。
  • 您不能将完整的 shell 脚本作为单独的参数传递。

正确的语法是:

for c in $(seq 1 10); do echo $c; done

注意for ... in ... 之后的; 部分,do 之前的部分,以及do ... done 块内每个命令之后的另一个。你也可以使用换行符:

for c in $(seq 1 10)
do
    echo $c
done

把你的整个shell脚本放在一个参数中;参数被传递给sh -c ...-c 开关期望整个脚本在一个参数值中:

shell_command = 'for c in $(seq 1 10); do echo $c; done'
call(shell_command, shell=True)

或者,或者,使用换行符:

shell_command = 'for c in $(seq 1 10)\ndo\n    echo $c\ndone'
call(shell_command, shell=True)

shell_command = '''
for c in $(seq 1 10)
do
    echo $c
done
'''
call(shell_command, shell=True)

【讨论】:

    【解决方案2】:

    我只是在 Python 层做这种事情。

    # for i in $(seq 10); do ...; done
    for i in range(10):
      subprocess.call([...])
    
    # for f in *.py; do ...; done
    py_files = [f for f in os.listdir('.') where f.endswith('*.py')]
    for f in py_files:
      subprocess.call([..., f, ...])
    

    如果可能,您应该避免使用shell=True,因为它实际上很危险。考虑一个包含; 的文件名或用户输入:如何防止它不按预期执行(以及如何防止调用者代表您的进程运行任何shell 命令) ?数组形式避免了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 2017-04-12
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      • 1970-01-01
      相关资源
      最近更新 更多