我使用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 3使这个答案生效。X以及,print被称为一个函数:在3。X,只有print('foo')可以工作,而2。X也接受打印'foo'。 -关于跨平台(包括Windows)的观点,请参阅kxr的有用答案。

在bash、ksh或zsh中:

使用ANSI c引号字符串($'…'),它允许使用\n表示在字符串传递给python之前展开为实际换行的换行:

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

注意import语句和for语句之间的\n可以产生换行。

要将shell变量值传递给这样的命令,最安全的方法是使用参数并通过sys. js访问它们。Python脚本中的argv:

name='rob' # value to pass to the Python script
python -c $'import sys\nfor r in range(10): print(sys.argv[1])' "$name"

关于使用(转义序列预处理)双引号命令字符串与嵌入的shell变量引用的优缺点,请参见下面的讨论。

使用$'安全工作…的字符串:

在原始源代码中使用双实例。 \<char>序列-例如本例中的\n,但也有常见的嫌疑,例如\t, \r, \b -被$'…’(参见man printf了解支持的转义) 转义“实例为\”。


如果你必须保持posix兼容:

使用printf替换命令:

python -c "$(printf %b 'import sys\nfor r in range(10): print("rob")')"

要安全地使用这种类型的字符串:

Double \ instances in your original source code. \<char> sequences - such as \n in this case, but also the usual suspects such as \t, \r, \b - are expanded by printf (see man printf for the supported escape sequences). Pass a single-quoted string to printf %b and escape embedded single quotes as '\'' (sic). Using single quotes protects the string's contents from interpretation by the shell. That said, for short Python scripts (as in this case) you can use a double-quoted string to incorporate shell variable values into your scripts - as long as you're aware of the associated pitfalls (see next point); e.g., the shell expands $HOME to the current user's home dir. in the following command: python -c "$(printf %b "import sys\nfor r in range(10): print('rob is $HOME')")" However, the generally preferred approach is to pass values from the shell via arguments, and access them via sys.argv in Python; the equivalent of the above command is: python -c "$(printf %b 'import sys\nfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME" While using a double-quoted string is more convenient - it allows you to use embedded single quotes unescaped and embedded double quotes as \" - it also makes the string subject to interpretation by the shell, which may or may not be the intent; $ and ` characters in your source code that are not meant for the shell may cause a syntax error or alter the string unexpectedly. Additionally, the shell's own \ processing in double-quoted strings can get in the way; for instance, to get Python to produce literal output ro\b, you must pass ro\\b to it; with a '...' shell string and doubled \ instances, we get: python -c "$(printf %b 'import sys\nprint("ro\\\\bs")')" # ok: 'ro\bs' By contrast, this does not work as intended with a "..." shell string: python -c "$(printf %b "import sys\nprint('ro\\\\bs')")" # !! INCORRECT: 'rs' The shell interprets both "\b" and "\\b" as literal \b, requiring a dizzying number of additional \ instances to achieve the desired effect: python -c "$(printf %b "import sys\nprint('ro\\\\\\\\bs')")"


通过stdin而不是-c来传递代码:

注意:这里我关注的是单线解决方案;Xorho的回答展示了如何使用多行here-document -但一定要引用分隔符;例如,<<'EOF',除非你明确地想让shell在前面展开字符串(这与上面提到的注意事项一起出现)。


在bash、ksh或zsh中:

将ANSI c引号字符串($'…')与here字符串(<<<…)组合:

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

-告诉python显式地从stdin读取(默认情况下)。 -在这种情况下是可选的,但如果你还想向脚本传递参数,你确实需要它来消除脚本文件名的参数歧义:

python - 'rob' <<<$'import sys\nfor r in range(10): print(sys.argv[1])'

如果你必须保持posix兼容:

像上面一样使用printf,但是使用管道,以便通过stdin传递输出:

printf %b 'import sys\nfor r in range(10): print("rob")' | python

带论点:

printf %b 'import sys\nfor r in range(10): print(sys.argv[1])' | python - 'rob'

其他回答

问题不在于import语句。问题是控制流语句不能内联在Python解释器命令中工作。将该import语句替换为任何其他语句,您将看到相同的问题。

想想看:Python不可能内联所有东西。它使用缩进来分组控制流。

-使用Python 3使这个答案生效。X以及,print被称为一个函数:在3。X,只有print('foo')可以工作,而2。X也接受打印'foo'。 -关于跨平台(包括Windows)的观点,请参阅kxr的有用答案。

在bash、ksh或zsh中:

使用ANSI c引号字符串($'…'),它允许使用\n表示在字符串传递给python之前展开为实际换行的换行:

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

注意import语句和for语句之间的\n可以产生换行。

要将shell变量值传递给这样的命令,最安全的方法是使用参数并通过sys. js访问它们。Python脚本中的argv:

name='rob' # value to pass to the Python script
python -c $'import sys\nfor r in range(10): print(sys.argv[1])' "$name"

关于使用(转义序列预处理)双引号命令字符串与嵌入的shell变量引用的优缺点,请参见下面的讨论。

使用$'安全工作…的字符串:

在原始源代码中使用双实例。 \<char>序列-例如本例中的\n,但也有常见的嫌疑,例如\t, \r, \b -被$'…’(参见man printf了解支持的转义) 转义“实例为\”。


如果你必须保持posix兼容:

使用printf替换命令:

python -c "$(printf %b 'import sys\nfor r in range(10): print("rob")')"

要安全地使用这种类型的字符串:

Double \ instances in your original source code. \<char> sequences - such as \n in this case, but also the usual suspects such as \t, \r, \b - are expanded by printf (see man printf for the supported escape sequences). Pass a single-quoted string to printf %b and escape embedded single quotes as '\'' (sic). Using single quotes protects the string's contents from interpretation by the shell. That said, for short Python scripts (as in this case) you can use a double-quoted string to incorporate shell variable values into your scripts - as long as you're aware of the associated pitfalls (see next point); e.g., the shell expands $HOME to the current user's home dir. in the following command: python -c "$(printf %b "import sys\nfor r in range(10): print('rob is $HOME')")" However, the generally preferred approach is to pass values from the shell via arguments, and access them via sys.argv in Python; the equivalent of the above command is: python -c "$(printf %b 'import sys\nfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME" While using a double-quoted string is more convenient - it allows you to use embedded single quotes unescaped and embedded double quotes as \" - it also makes the string subject to interpretation by the shell, which may or may not be the intent; $ and ` characters in your source code that are not meant for the shell may cause a syntax error or alter the string unexpectedly. Additionally, the shell's own \ processing in double-quoted strings can get in the way; for instance, to get Python to produce literal output ro\b, you must pass ro\\b to it; with a '...' shell string and doubled \ instances, we get: python -c "$(printf %b 'import sys\nprint("ro\\\\bs")')" # ok: 'ro\bs' By contrast, this does not work as intended with a "..." shell string: python -c "$(printf %b "import sys\nprint('ro\\\\bs')")" # !! INCORRECT: 'rs' The shell interprets both "\b" and "\\b" as literal \b, requiring a dizzying number of additional \ instances to achieve the desired effect: python -c "$(printf %b "import sys\nprint('ro\\\\\\\\bs')")"


通过stdin而不是-c来传递代码:

注意:这里我关注的是单线解决方案;Xorho的回答展示了如何使用多行here-document -但一定要引用分隔符;例如,<<'EOF',除非你明确地想让shell在前面展开字符串(这与上面提到的注意事项一起出现)。


在bash、ksh或zsh中:

将ANSI c引号字符串($'…')与here字符串(<<<…)组合:

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

-告诉python显式地从stdin读取(默认情况下)。 -在这种情况下是可选的,但如果你还想向脚本传递参数,你确实需要它来消除脚本文件名的参数歧义:

python - 'rob' <<<$'import sys\nfor r in range(10): print(sys.argv[1])'

如果你必须保持posix兼容:

像上面一样使用printf,但是使用管道,以便通过stdin传递输出:

printf %b 'import sys\nfor r in range(10): print("rob")' | python

带论点:

printf %b 'import sys\nfor r in range(10): print(sys.argv[1])' | python - 'rob'

你可以这样做

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

或没有管道:

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

Or

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

或者沉默鬼的回答,或者卡斯特的回答。

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

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

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

我想要一个具有以下属性的解决方案:

可读的 读取标准输入以处理其他工具的输出

这两个要求在其他答案中都没有提供,所以下面是如何在命令行上执行所有操作时读取标准输入:

grep special_string -r | sort | python3 <(cat <<EOF
import sys
for line in sys.stdin:
    tokens = line.split()
    if len(tokens) == 4:
        print("%-45s %7.3f    %s    %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
EOF
)