循环子流程因语法错误而失败

时间:2018-07-27 10:55:11

标签: python shell subprocess

我有一个简单的脚本,以便了解如何在子进程调用中运行shell for loop。我正在虚拟环境和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

我在这里做什么错了?

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

我只是在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命令)您的过程)?数组形式避免了这个问题。