A colleague recently sent me a bash script that included some inline Python. The command he used was of the form:
$ echo -e 'from foo import bar\nfor i in range(10):\n bar(i+1).thing = "something"\n\n' | python
The command worked just fine, but I asked why he didn't use python -c
. On further investigation, we were unable to translate this to a form that python -c
would accept as it appears that Python disallows statements prior to a for loop even when delimited by a semicolon.
The first example below shows that you can import, and print out the imported object. The second example shows that you can use a for loop and print from the for loop. The third example combines the first two, and results in a SyntaxError
. And finally, the forth example shows the SyntaxError
results when using an expression prior to the for loop:
$ python -c "from sys import argv; print argv"
['-c']
$ python -c "for v in [1,2,3,4]: print v"
1
2
3
4
$ python -c "from sys import argv; for v in argv: print v"
File "<string>", line 1
from sys import argv; for v in argv: print v
^
SyntaxError: invalid syntax
$ python -c "x = 5; for i in [1,2,3]: print i"
File "<string>", line 1
x = 5; for i in [1,2,3]: print i
^
SyntaxError: invalid syntax
In hindsight, the SyntaxError
is not that surprising given that the code is not valid when saved in a script, and that the grammar for statements combined with whitespace restrictions can impose this type of limitation. That being said, is there a way to allow a statement prior to a compound statement through python -c
?
To clarify CDspace's answer, note that in Bash, unlike Python, newlines do not terminate string literals. So you can do the following:
$python -c 'import sys
for i in range(10):
print(i)
'
Another option:
python -c "exec(\"x = 5\nfor i in [1,2,3]:\n\tprint(i)\")"
Tested and Works for both windows CMD, and Bash.
From the docs (emphasis added), try it with newlines instead of semi-colons.
When called with -c command, it executes the Python statement(s) given as command. Here command may contain multiple statements separated by newlines. Leading whitespace is significant in Python statements!
You already have an answer regarding -c
but for your use case, a here document has the advantage of not having string quoting issues as does a -c
parameter wrapped in ''
or ""
, because you can use any unique delimiter that you want that will not appear in your script anywhere.
python <<'PYSCRIPT'
for i in range(10):
print(i)
PYSCRIPT
(Single quotes around the initial delimiter if you don't want expansion of shell variables, no quotes if you do.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With