在一行命令行中执行多行语句

270 投票
17 回答
220976 浏览
提问于 2025-04-15 17:53

我正在使用Python,通过-c来执行一个单行的循环,也就是:

python -c "for r in range(10): print 'rob'"

这个没问题。不过,如果我在for循环之前导入一个模块,就会出现语法错误:

python -c "import sys; for r in range(10): print 'rob'"

  File "<string>", line 1
    import sys; for r in range(10): print 'rob'
              ^
SyntaxError: invalid syntax

这个怎么解决呢?

对我来说,把它写成一行很重要,这样我才能把它放进一个Makefile里。

17 个回答

72

问题其实不在于 import 语句本身,而是在 for 循环之前的任何东西。更具体来说,就是在内联块之前出现的任何内容。

比如,下面这些都是可以正常工作的:

python -c "import sys; print 'rob'"
python -c "import sys; sys.stdout.write('rob\n')"

如果 import 语句真的是个问题,那么这个代码应该能运行,但实际上并不能:

python -c "__import__('sys'); for r in range(10): print 'rob'"

对于你最基本的例子,你可以把它改成这样:

python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"

不过,lambda 只能执行表达式,而不能执行语句或多个语句,所以你可能还是无法实现你想要的功能。不过,借助生成器表达式、列表推导式、lambda、sys.stdout.write、内置的 "map" 函数,以及一些巧妙的字符串插值,你可以写出一些强大的单行代码。

问题是,你想做到什么程度?在什么情况下,写一个小的 .py 文件,让你的 makefile 去执行,反而会更好呢?

116

这种风格在makefile中也可以使用(实际上,它经常被使用)。

python - <<EOF
import random
for r in range(3): print(random.randint(1, 42))
EOF

或者使用硬制表符:

python - <<-EOF
    import random
    for r in range(3): print(random.randint(1, 42))
EOF
# Important: Replace the indentation above w/ hard tabs.

在上面的例子中,开头的制表符字符也会被去掉(这样可以达到一些结构化的效果)。

在EOF的位置,可以用任何一个在这里文档中没有出现的标记词,前提是它要在行的开头(你可以在bash的手册页中查看这里文档,或者访问这里)。

247

你可以这样做:

echo -e "import sys\nfor r in range(10): print 'rob'" | python

或者不使用管道:

python -c "exec(\"import sys\nfor r in range(10): print 'rob'\")"

或者这样:

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

或者参考 SilentGhost的回答 或者 Crast的回答

撰写回答