【问题标题】:If statements and one line python scripts from command lineIf语句和命令行中的一行python脚本
【发布时间】:2014-06-11 14:35:00
【问题描述】:

为什么我会收到以下单行 Python 代码的语法错误?

python -c 'import re; if True: print "HELLO";'
  File "<string>", line 1
    import re; if True: print "HELLO";
                ^
SyntaxError: invalid syntax

以下代码可以正常工作

python -c 'if True: print "HELLO";'

如何更改我的一行以从命令行在一行上执行我想要的脚本?

【问题讨论】:

  • 不是答案:你为什么要把东西放在一行?有什么好处,为什么比真正的脚本更好?
  • 好处是我在运行它的系统上没有任何文件写入权限。另外,我通常想将一个衬里复制并粘贴给朋友,这样他们就不必创建文件并授予这些执行权限。
  • 这看起来像是一个副本:stackoverflow.com/questions/2043453/… 至少,该链接包含很多不错的解决方法..
  • @slaadvak 我同意这是该问题的副本,但我更喜欢下面提供的 Rynants 答案,而不是那里提供的答案。 @Ashkan 这个问题回答了为什么python文件中不能存在一个衬垫,但没有回答如何在命令行上编写一行python代码,这就是我想要做的。

标签: python bash shell command-line


【解决方案1】:

问题不在于具体的导入语句,而在于您在控制流语句之前有任何内容。这也行不通:

dan@dan:~> python -c 'a = "1234" ; if True: print "hi"'
  File "<string>", line 1
    a = "1234" ; if True: print "hi"
                  ^
SyntaxError: invalid syntax

根据 Python 参考资料 (https://docs.python.org/2/reference/compound_stmts.html),';'只能用于将“简单语句”组合在一起。在这种情况下,您将简单的语句import reif True: 组合在一起。 if True 不是一个简单的语句,因为它引入了流控制,因此是一个复合语句。至少我是这样解释文档的。

以下是 Python 参考的全文:

复合语句由一个或多个“子句”组成。一个子句 由一个标题和一个“套​​件”组成。特定的子句标题 复合语句都在相同的缩进级别。每个子句 标头以唯一标识关键字开头并以 冒号。套件是由子句控制的一组语句。一种 套件可以是一个或多个分号分隔的简单语句 与标题相同的行,在标题的冒号之后,也可以是 后续行中的一个或多个缩进语句

compound_stmt ::=  if_stmt
                   | while_stmt
                   | for_stmt
                   | try_stmt
                   | with_stmt
                   | funcdef
                   | classdef
                   | decorated
suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]

【讨论】:

  • 赞成,因为这个答案为我的问题提供了“为什么”。 Rynant 提供了解决方法。
【解决方案2】:

您可以直接在参数中嵌入换行符。

$ python -c 'import re
> if True:
>  print "HELLO"
> '

【讨论】:

  • 你是怎么做到的?有什么特殊的键盘组合吗?因为只需按 Enter 即可执行该行而不嵌入新的换行符。
  • 如果您使用任何 POSIX 兼容的 shell,在带引号的字符串中间按 Enter 不应执行该命令(除非,例如,您更改了默认的 readline 绑定输入键)。
  • 我使用的是 Ubuntu。这可能是 bash shell 而不是 POSIX 兼容的 shell?
  • bash 在这个意义上是 POSIX 兼容的。
  • 事实证明,这仅适用于从头到尾键入,而无需使用箭头键进行任何更改。这不太理想,但仍然很高兴知道。谢谢。
【解决方案3】:

解决此限制的一个选项是使用换行符转义序列\n 指定具有$'string' 格式的命令。

python -c $'import re\nif True: print "HELLO";'

注意:这由 bash 和 zsh 等 shell 支持,但不是有效的 POSIX sh。

正如@slaadvak 所述,这里还有一些其他解决方法:Executing Python multi-line statements in the one-line command-line

【讨论】:

  • 这是一个扩展示例:python -c $'print 123\nx = 20\nif x > 20:\n\tprint "x > 20"\nelse:\n\tprint "x
【解决方案4】:

为什么我会收到以下单行 Python 代码的语法错误?

Python grammar 可能会禁止small_stmt ';' compound_stmt-c 参数可能被解释为file_input

fileinput: (NEWLINE | stmt)* ENDMARKER
stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: import_stmt <in this case>
compound_stmt: if_stmt <in this case>

注意:simple_stmt 末尾有一个换行符。 if_stmt 不是small_stmt,它不能在';' 之后关注另一个small_stmt。在small_stmt 之后引入compound_stmt 需要换行。

这不是问题,因为bash 允许多行参数,只是在完成之前不要关闭开头的单引号,例如:

$ python -c '
> import re
> if 1:
>   print(1)
> '
1

注意:&gt; 在这里由 shell 本身打印。它不是手动输入的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多