"If"语句和一行Python脚本从命令行。

10

为什么我对以下这行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";'

我该如何将我的一行命令更改为在单行命令行上执行所需脚本的命令?


1
不是答案:为什么你想把东西放到一行里?有什么好处,为什么它比真正的脚本更好? - guettli
1
如何将多个语句放在一行中 - a5hk
1
这看起来像是重复的内容:https://dev59.com/NXI-5IYBdhLWcg3wCztn至少,该链接包含了很多不错的解决方法。 - slaadvak
1
如果您在系统上没有写入权限,但可以通过ssh连接到它,则可以使用以下命令:cat scripts/myscript.py | ssh localhost python - guettli
如果你真的想在Python oneliners中使用re,那么pythonpy(https://github.com/Russell91/pythonpy)可能会引起你的兴趣:echo me2 | py -x 're.sub("me", "you", x)' => you2 - RussellStewart
显示剩余6条评论
4个回答

13

以下是一个扩展示例:python -c $'print 123\nx = 20\nif x > 20:\n\tprint "x > 20"\nelse:\n\tprint "x <= 20"' - Blisterpeanuts

6
问题不在于import语句本身,而是在于控制流语句之前有其他内容。以下代码也无法正常工作:
dan@dan:~> python -c 'a = "1234" ; if True: print "hi"'
  File "<string>", line 1
    a = "1234" ; if True: print "hi"
                  ^
SyntaxError: invalid syntax

根据Python参考文献(7. Compound statements),';'只能用于将“简单语句”组合在一起。在这种情况下,您正在将简单语句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)* [";"]

1
这个答案提供了我的问题的“为什么”,因此我点赞了。而Rynant的回答则提供了解决方法。 - AffluentOwl

3
您可以直接在参数中嵌入换行符。
python -c 'import re
> if True:
>   print "HELLO"
> '

你怎么做到这一点的?有什么特殊的键盘组合吗?因为只是按回车键会执行该行而不嵌入新的换行符。 - AffluentOwl
2
如果您正在使用任何符合POSIX标准的shell,在引号字符串中按Enter键不应执行命令(除非例如您已更改Enter键的默认“readline”绑定)。 - chepner
我正在使用Ubuntu。那可能是一个Bash shell,而不是符合POSIX标准的shell吗? - AffluentOwl
1
在这个意义上,bash 是符合 POSIX 标准的。 - chepner
结果发现只有在从头到尾输入时才适用,而不必使用箭头键进行任何更改。这不是很理想,但仍然很好知道。谢谢。 - AffluentOwl

2
以下是这个问题的英译中翻译:
为什么我在下面这个 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。 必须使用换行符来引入compound_stmt以代替small_stmt
这不是问题,因为Bash允许多行参数。 只需不要关闭开头的单引号,直到完成即可,例如:
python -c '
> import re
> if 1:
>   print(1)
> '

1

注意:这里的>是由shell本身打印的,而不是手动输入的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接