我使用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中。


当前回答

如果你不想触摸标准输入并模拟你已经传递了"python cmdfile.py",你可以在Bash shell中执行以下操作:

python <(printf "word=raw_input('Enter word: ')\nimport sys\nfor i in range(5):\n    print(word)")

如您所见,它允许您使用标准输入读取输入数据。shell在内部为输入命令内容创建临时文件。

其他回答

单/双引号和反斜杠无处不在:

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

更好:

python -c '
import sys
for i in range(10):
  print("bob")
'

注意:在某些系统上,可执行python适用于python 2,可能不可用。可执行的python3是针对python3的。

问题并不在于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))"

然而,lambdas只能执行表达式,而不能执行语句或多条语句,因此您可能仍然无法执行您想要执行的事情。然而,在生成器表达式、列表理解、lambdas、sys.stdout之间。写,“映射”内置,和一些创造性的字符串插值,你可以做一些强大的一行程序。

问题是,您想要走多远,以及在什么情况下编写一个小的.py文件而让makefile执行不是更好?

python2.6 -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

工作很好。

使用“[]”内联for循环。

当我需要这样做时,我使用:

python -c "$(echo -e "import sys\nsys.stdout.write('Hello, World!\\\n')")"

注意sys.stdout.write语句中的换行符有三个反斜杠。

你知道怎么解决吗?

你的问题是由这样一个事实造成的:Python语句,用;分隔,只允许是“小语句”,它们都是一行程序。来自Python文档中的语法文件:

标准时间: simple_stmt |compound_stmt simple_stmt: small_stmt (“;”small_stmt)* [“;”]换行符 small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt |global_stmt |nonlocal_stmt |assert_stmt)

复合语句不能通过分号与其他语句包含在同一行中——因此使用-c标志来做到这一点非常不方便。

在bash shell环境中演示Python时,我发现包含复合语句非常有用。唯一可靠的简单方法是使用heredocs (posix shell的东西)。

赫里多克斯

使用heredoc(使用<<创建)和Python的命令行接口选项,-:

$ python - <<-"EOF"
        import sys                    # 1 tab indent
        for r in range(10):           # 1 tab indent
            print('rob')              # 1 tab indent and 4 spaces
EOF

在<<之后添加-(<<-)允许您使用制表符缩进(Stackoverflow将制表符转换为空格,因此我缩进了8个空格以强调这一点)。前面的制表符将被剥离。

你可以在没有标签的情况下使用<<:

$ python - << "EOF"
import sys
for r in range(10):
    print('rob')
EOF

在EOF周围加上引号可以防止参数和算术扩展。这使得heredoc更加健壮。

Bash多行字符串

如果你使用双引号,你会得到shell- expand:

$ python -c "
> import sys
> for p in '$PATH'.split(':'):
>     print(p)
> "
/usr/sbin
/usr/bin
/sbin
/bin
...

为了避免shell扩展,请使用单引号:

$ python -c '
> import sys
> for p in "$PATH".split(":"):
>     print(p)
> '
$PATH

注意,我们需要在Python中对字面量交换引号字符-我们基本上不能使用由BASH解释的引号字符。我们可以交替使用它们,就像在Python中一样——但这看起来已经很混乱了,这就是为什么我不建议这样做:

$ python -c '
import sys
for p in "'"$PATH"'".split(":"):
    print(p)
'
/usr/sbin
/usr/bin
/sbin
/bin
...

对已接受答案(和其他答案)的批评

这不是很好读:

Echo -e "import sys\nfor rin range(10): print 'rob'" | python

可读性不强,而且在出现错误的情况下很难调试:

Python -c "exec(\"import sys\\nfor rin range(10): print 'rob'\")"

也许可读性更强一些,但仍然很难看:

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

如果你的python里有",你就会过得很糟糕:

$ python -c "import sys . > for rin range(10): print 'rob'"

不要滥用map或list推导式来获取for循环:

import sys;Map (lambda x: sys.stdout。Write ('rob%d\n' % x), range(10))"

这些都是悲伤而糟糕的。不要这样做。