If statements and one line python scripts from command line

后端 未结 4 1237
没有蜡笔的小新
没有蜡笔的小新 2020-12-20 16:17

Why do I receive a syntax error for the following one liner python code?

python -c \'import re; if True: print \"HELLO\";\'
  File \"\", line 1         


        
相关标签:
4条回答
  • 2020-12-20 16:45

    One option to work around this limitation is to specify the command with the $'string' format using the newline escape sequence \n.

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

    Note: this is supported by shells such as bash and zsh, but is not valid POSIX sh.

    As mentioned by @slaadvak, there are some other workarounds here: Executing Python multi-line statements in the one-line command-line

    0 讨论(0)
  • 2020-12-20 16:46

    Why do I receive a syntax error for the following one liner python code?

    Python grammar might forbid small_stmt ';' compound_stmt. -c argument is probably is interpreted as 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>
    

    Note: there is a newline at the end of simple_stmt. if_stmt is not small_stmt it can't follow another small_stmt after ';'. A newline is necessary to introduce compound_stmt after small_stmt.

    It is not an issue because bash allows multiline arguments, just don't close the opening single quote until you done e.g.:

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

    Note: > are printed by the shell itself here. It is not entered by hand.

    0 讨论(0)
  • 2020-12-20 16:56

    The problem isn't with the import statement specifically, its that you have anything before a control flow statement. This won't work, either:

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

    According to the Python reference (https://docs.python.org/2/reference/compound_stmts.html), ';' can only be used to combine "simple statements" together. In this case you're combining the simple statement import re, with if True:. if True isn't a simple statement, because it's introducing flow control, and is therefore a compound statement. At least that's how I interpret the documentation.

    Here's the full text from the Python reference:

    Compound statements consist of one or more ‘clauses.’ A clause consists of a header and a ‘suite.’ The clause headers of a particular compound statement are all at the same indentation level. Each clause header begins with a uniquely identifying keyword and ends with a colon. A suite is a group of statements controlled by a clause. A suite can be one or more semicolon-separated simple statements on the same line as the header, following the header’s colon, or it can be one or more indented statements on subsequent lines

    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)* [";"]
    
    0 讨论(0)
  • 2020-12-20 16:56

    You can embed newlines directly in the argument.

    $ python -c 'import re
    > if True:
    >  print "HELLO"
    > '
    
    0 讨论(0)
提交回复
热议问题