2014-04-25 5 views
7

Warum erhalte ich einen Syntaxfehler für den folgenden Einstrich Python-Code?If-Anweisungen und eine Zeile Python-Skripts von der Befehlszeile

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

Der folgende Code funktioniert gut

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

Wie kann ich meine eine Zeile ändern mein soll Skript auf einer einzigen Zeile von der Kommandozeile ausführen?

+1

Keine Antwort: Warum wollen Sie Zeug in eine Zeile stecken? Was ist der Vorteil, warum ist es besser als ein echtes Skript? – guettli

+0

Der Vorteil ist, dass ich keine Datei Schreibberechtigungen auf dem System habe, auf dem ich dies ausführe. Außerdem möchte ich häufig einen Liner kopieren und an Freunde einfügen, und das macht es so, dass sie keine Dateien erstellen und diese Ausführungsberechtigungen gewähren müssen. – AffluentOwl

+1

siehe http://stackoverflow.com/questions/6167127/how-to-put-multiple-statements-in-one-line – Ashkan

Antwort

6

Eine Möglichkeit um diese Einschränkung zu arbeiten, ist den Befehl mit dem $'string' Format geben Sie die Escape-Sequenz Newline mit \n.

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

Hinweis: Dies wird von Shells wie bash und zsh unterstützt, ist aber nicht gültig POSIX sh.

Wie @slaadvak erwähnt, gibt es einige andere Abhilfen hier: Executing Python multi-line statements in the one-line command-line

4

Das Problem ist nicht mit der Import-Anweisung speziell, es ist, dass Sie alles vor einer Kontrolle Flow-Statement haben. Das wird nicht funktionieren, entweder:

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

Nach der Python-Referenz (https://docs.python.org/2/reference/compound_stmts.html), ';' kann nur verwendet werden, um "einfache Aussagen" miteinander zu kombinieren. In diesem Fall kombinieren Sie die einfache Anweisung import re mit if True:. if True ist keine einfache Aussage, weil es die Flusskontrolle einführt und daher eine zusammengesetzte Aussage ist. Zumindest interpretiere ich die Dokumentation so.

Hier ist der vollständige Text aus dem Referenz Python: 'Klauseln'

Compound-Anweisungen bestehen aus einem oder mehreren A-Klausel besteht aus einem Kopf und einem Die Klausel Header eines bestimmten 'Suite.' zusammengesetzte Anweisung sind alle auf der gleichen Einrückungsebene. Jede Klausel Header beginnt mit einem eindeutig identifizierenden Schlüsselwort und endet mit einem Doppelpunkt. Eine Suite ist eine Gruppe von Anweisungen, die durch eine Klausel gesteuert werden. Eine Suite kann eine oder mehr durch Semikolon getrennte einfache Aussagen über die gleichen Zeilen wie die Kopfzeile sein, nach dem Doppelpunkt Header, oder es kann

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

Upvoted als diese Antwort bietet das "warum" zu meiner Frage. Und Rynant bietet die Problemumgehung. – AffluentOwl

1

Sie eine oder mehr eingekerbte Aussagen auf nachfolgende Zeilen sein kann Zeilenumbrüche direkt in das Argument einbetten.

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

Wie machst du das? Gibt es eine spezielle Tastaturkombination? Denn nur durch Drücken der Eingabetaste wird die Zeile ausgeführt, ohne dass ein neuer Zeilenumbruch eingefügt wird. – AffluentOwl

+2

Wenn Sie eine POSIX-kompatible Shell verwenden, sollte das Drücken der Eingabetaste in der Mitte einer Zeichenfolge in Anführungszeichen den Befehl nicht ausführen (es sei denn, Sie haben beispielsweise die Standardbindung "readline" für die Eingabetaste geändert). – chepner

+0

Ich benutze Ubuntu. Ist das vielleicht eine Bash Shell anstelle einer POSIX-konformen Shell? – AffluentOwl

1

Warum erhalte ich einen Syntaxfehler für die folgenden ein Python-Code-Liner?

Python grammar könnte verbieten small_stmt ';' compound_stmt. -c Argument wahrscheinlich ist, wird als file_input interpretiert:

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> 

Hinweis: ein Newline am Ende des simple_stmt ist.if_stmt ist nicht small_stmt es kann nicht folgen small_stmt nach ';'. Eine neue Zeile ist erforderlich, um compound_stmt nach small_stmt einzuführen.

Es ist kein Problem, weil bash mehrzeilige Argumente erlaubt, schließen Sie einfach nicht die Öffnung Apostroph bis z.B .: getan

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

Hinweis: > werden von der Shell selbst hier gedruckt. Es wird nicht von Hand eingegeben.

Verwandte Themen