Executing Python multi-line statements in the one-line command-line












158















I'm using Python with -c to execute a one-liner loop, i.e.:



$ python -c "for r in range(10): print 'rob'"


This works fine. However, if I import a module before the for loop, I get a syntax error:



$ python -c "import sys; for r in range(10): print 'rob'"
File "<string>", line 1
import sys; for r in range(10): print 'rob'
^
SyntaxError: invalid syntax


Any idea how this can be fixed?



It's important to me to have this as a one-liner so that I can include it in a Makefile.










share|improve this question





























    158















    I'm using Python with -c to execute a one-liner loop, i.e.:



    $ python -c "for r in range(10): print 'rob'"


    This works fine. However, if I import a module before the for loop, I get a syntax error:



    $ python -c "import sys; for r in range(10): print 'rob'"
    File "<string>", line 1
    import sys; for r in range(10): print 'rob'
    ^
    SyntaxError: invalid syntax


    Any idea how this can be fixed?



    It's important to me to have this as a one-liner so that I can include it in a Makefile.










    share|improve this question



























      158












      158








      158


      45






      I'm using Python with -c to execute a one-liner loop, i.e.:



      $ python -c "for r in range(10): print 'rob'"


      This works fine. However, if I import a module before the for loop, I get a syntax error:



      $ python -c "import sys; for r in range(10): print 'rob'"
      File "<string>", line 1
      import sys; for r in range(10): print 'rob'
      ^
      SyntaxError: invalid syntax


      Any idea how this can be fixed?



      It's important to me to have this as a one-liner so that I can include it in a Makefile.










      share|improve this question
















      I'm using Python with -c to execute a one-liner loop, i.e.:



      $ python -c "for r in range(10): print 'rob'"


      This works fine. However, if I import a module before the for loop, I get a syntax error:



      $ python -c "import sys; for r in range(10): print 'rob'"
      File "<string>", line 1
      import sys; for r in range(10): print 'rob'
      ^
      SyntaxError: invalid syntax


      Any idea how this can be fixed?



      It's important to me to have this as a one-liner so that I can include it in a Makefile.







      python shell command-line heredoc






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited May 1 '17 at 23:12









      Aaron Hall

      176k51305255




      176k51305255










      asked Jan 11 '10 at 17:11









      user248237dfsfuser248237dfsf

      24.8k108265408




      24.8k108265408
























          18 Answers
          18






          active

          oldest

          votes


















          144














          you could do



          echo -e "import sysnfor r in range(10): print 'rob'" | python


          or w/out pipes:



          python -c "exec("import sysnfor r in range(10): print 'rob'")"



          or



          (echo "import sys" ; echo "for r in range(10): print 'rob'") | python


          or @SilentGhost's answer / @Crast's answer






          share|improve this answer

































            77














            this style can be used in makefiles too (and in fact it is used quite often).



            python - <<EOF
            import sys
            for r in range(3): print 'rob'
            EOF


            or



            python - <<-EOF
            import sys
            for r in range(3): print 'rob'
            EOF


            in latter case leading tab characters are removed too (and some structured outlook can be achieved)



            instead of EOF can stand any marker word not appearing in the here document at a beginning of a line (see also here documents in the bash manpage or here).






            share|improve this answer





















            • 9





              Nice. To also pass arguments, simply place them after <<EOF. Note, however, that it's better to quote the delimiter - e.g., <<'EOF' - so as to protect the contents of the here-document from up-front shell expansions.

              – mklement0
              Apr 10 '15 at 15:11



















            43














            The issue is not actually with the import statement, it's with anything being before the for loop. Or more specifically, anything appearing before an inlined block.



            For example, these all work:



            python -c "import sys; print 'rob'"
            python -c "import sys; sys.stdout.write('robn')"


            If import being a statement were an issue, this would work, but it doesn't:



            python -c "__import__('sys'); for r in range(10): print 'rob'"


            For your very basic example, you could rewrite it as this:



            python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"


            However, lambdas can only execute expressions, not statements or multiple statements, so you may still be unable to do the thing you want to do. However, between generator expressions, list comprehension, lambdas, sys.stdout.write, the "map" builtin, and some creative string interpolation, you can do some powerful one-liners.



            The question is, how far do you want to go, and at what point is it not better to write a small .py file which your makefile executes instead?






            share|improve this answer































              18
















              - To make this answer work with Python 3.x as well, print is called as a function: in 3.x, only print('foo') works, whereas 2.x also accepts print 'foo'.

              - For a cross-platform perspective that includes Windows, see kxr's helpful answer.



              In bash, ksh, or zsh:



              Use an ANSI C-quoted string ($'...'), which allows using n to represent newlines that are expanded to actual newlines before the string is passed to python:



              python -c $'import sysnfor r in range(10): print("rob")'


              Note the n between the import and for statements to effect a line break.



              To pass shell-variable values to such a command, it is safest to use arguments and access them via sys.argv inside the Python script:



              name='rob' # value to pass to the Python script
              python -c $'import sysnfor r in range(10): print(sys.argv[1])' "$name"


              See below for a discussion of the pros and cons of using an (escape sequence-preprocessed) double-quoted command string with embedded shell-variable references.



              To work safely with $'...' strings:





              • Double instances in your original source code.



                • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by $'...' (see man printf for the supported escapes)



              • Escape ' instances as '.




              If you must remain POSIX-compliant:



              Use printf with a command substitution:



              python -c "$(printf %b 'import sysnfor r in range(10): print("rob")')"


              To work safely with this type of string:





              • Double instances in your original source code.



                • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by printf (see man printf for the supported escape sequences).




              • Pass a single-quoted string to printf %b and escape embedded single quotes as ''' (sic).





                • Using single quotes protects the string's contents from interpretation by the shell.





                  • That said, for short Python scripts (as in this case) you can use a double-quoted string to incorporate shell variable values into your scripts - as long as you're aware of the associated pitfalls (see next point); e.g., the shell expands $HOME to the current user's home dir. in the following command:




                    • python -c "$(printf %b "import sysnfor r in range(10): print('rob is $HOME')")"




                  • However, the generally preferred approach is to pass values from the shell via arguments, and access them via sys.argv in Python; the equivalent of the above command is:




                    • python -c "$(printf %b 'import sysnfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"






                • While using a double-quoted string is more convenient - it allows you to use embedded single quotes unescaped and embedded double quotes as " - it also makes the string subject to interpretation by the shell, which may or may not be the intent; $ and ` characters in your source code that are not meant for the shell may cause a syntax error or alter the string unexpectedly.




                  • Additionally, the shell's own processing in double-quoted strings can get in the way; for instance, to get Python to produce literal output rob, you must pass ro\b to it; with a '...' shell string and doubled instances, we get:
                    python -c "$(printf %b 'import sysnprint("ro\\bs")')" # ok: 'robs'

                    By contrast, this does not work as intended with a "..." shell string:
                    python -c "$(printf %b "import sysnprint('ro\\bs')")" # !! INCORRECT: 'rs'

                    The shell interprets both "b" and "\b" as literal b, requiring a dizzying number of additional instances to achieve the desired effect:
                    python -c "$(printf %b "import sysnprint('ro\\\\bs')")"








              To pass the code via stdin rather than -c:



              Note: I'm focusing on single-line solutions here; xorho's answer shows how to use a multi-line here-document - be sure to quote the delimiter, however; e.g., <<'EOF', unless you explicitly want the shell to expand the string up front (which comes with the caveats noted above).





              In bash, ksh, or zsh:



              Combine an ANSI C-quoted string ($'...') with a here-string (<<<...):



              python - <<<$'import sysnfor r in range(10): print("rob")'


              - tells python explicitly to read from stdin (which it does by default).
              - is optional in this case, but if you also want to pass arguments to the scripts, you do need it to disambiguate the argument from a script filename:



              python - 'rob' <<<$'import sysnfor r in range(10): print(sys.argv[1])'




              If you must remain POSIX-compliant:



              Use printf as above, but with a pipeline so as to pass its output via stdin:



              printf %b 'import sysnfor r in range(10): print("rob")' | python


              With an argument:



              printf %b 'import sysnfor r in range(10): print(sys.argv[1])' | python - 'rob'





              share|improve this answer





















              • 1





                This should be the elected answer!

                – debuti
                Jan 16 at 17:25



















              12















              Any idea how this can be fixed?




              Your problem is created by the fact that Python statements, separated by ;, are only allowed to be "small statements", which are all one-liners. From the grammar file in the Python docs:




              stmt: simple_stmt | compound_stmt
              simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
              small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
              import_stmt | global_stmt | nonlocal_stmt | assert_stmt)



              Compound statements can't be included on the same line with other statements via semicolons - so doing this with the -c flag becomes very inconvenient.



              When demonstrating Python while in a bash shell environment, I find it very useful to include compound statements. The only simple way of doing this is with heredocs.



              Heredocs



              Use a heredoc (created with <<) and Python's command line interface option, -:



              $ python - <<-"EOF"
              import sys # 1 tab indent
              for r in range(10): # 1 tab indent
              print('rob') # 1 tab indent and 4 spaces
              EOF


              Adding the - after << (the <<-) allows you to use tabs to indent (Stackoverflow converts tabs to spaces, so I've indented 8 spaces to emphasize this). The leading tabs will be stripped.



              You can do it without the tabs with just <<:



              $ python - << "EOF"
              import sys
              for r in range(10):
              print('rob')
              EOF


              Putting quotes around EOF prevents parameter and arithmetic expansion. This makes the heredoc more robust.



              Critique of the accepted answer (and others)



              This is not very readable:




              echo -e "import sysnfor r in range(10): print 'rob'" | python



              Not very readable, and additionally difficult to debug in the case of an error:




              python -c "exec("import sys\nfor r in range(10): print 'rob'")"



              Perhaps a bit more readable, but still quite ugly:




              (echo "import sys" ; echo "for r in range(10): print 'rob'") | python



              You'll have a bad time if you have "'s in your python:




              $ python -c "import sys
              > for r in range(10): print 'rob'"



              Don't abuse map or list comprehensions to get for-loops:




              python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"



              These are all sad and bad. Don't do them.






              share|improve this answer





















              • 2





                ++ for the grammar info; the (non-expanding) here-doc is handy and the most robust solution, but obviously not a one-liner. If a single-line solution is a must, using an ANSI C-quoted string (bash, ksh, or zsh) is a reasonable solution: python -c $'import sysnfor r in range(10): print('rob')' (you'll only have to worry about escaping single quotes (which you can avoid by using double quotes) and backslashes).

                – mklement0
                Jul 7 '16 at 19:56





















              11














              just use return and type it on the next line:



              user@host:~$ python -c "import sys
              > for r in range(10): print 'rob'"
              rob
              rob
              ...





              share|improve this answer



















              • 5





                Seriously, you're going to sprain something if you keep doing this. python $(srcdir)/myscript.py for great justice.

                – Jason Orendorff
                Jan 11 '10 at 17:26



















              8














              The problem is not with the import statement. The problem is that the control flow statements don't work inlined in a python command. Replace that import statement with any other statement and you'll see the same problem.



              Think about it: python can't possibly inline everything. It uses indentation to group control-flow.






              share|improve this answer































                7














                If your system is Posix.2 compliant it should supply the printf utility:



                $ printf "print 'zap'nfor r in range(3): print 'rob'" | python
                zap
                rob
                rob
                rob





                share|improve this answer



















                • 2





                  Good solution, but I suggest using printf %b '...' | python for added robustness, because it prevents printf from interpreting sequences such as %d (format specifiers) in the input string. Also, unless you explicitly want to apply shell expansions to your Python command string up front (which can get confusing), it's better to use ' (single quotes) for the outer quoting, to avoid both the expansions and the backlash processing that the shell applies to double-quoted strings.

                  – mklement0
                  Jul 7 '16 at 14:40





















                7














                $ python2.6 -c "import sys; [sys.stdout.write('robn') for r in range(10)]"



                Works fine.
                Use "[ ]" to inline your for loop.






                share|improve this answer































                  4














                  (answered Nov 23 '10 at 19:48)
                  I'm not really a big Pythoner - but I found this syntax once, forgot where from, so I thought I'd document it:



                  if you use sys.stdout.write instead of print (the difference being, sys.stdout.write takes arguments as a function, in parenthesis - whereas print doesn't), then for a one-liner, you can get away with inverting the order of the command and the for, removing the semicolon, and enclosing the command in square brackets, i.e.:



                  python -c "import sys; [sys.stdout.write('robn') for r in range(10)]"


                  Have no idea how this syntax would be called in Python :)



                  Hope this helps,



                  Cheers!





                  (EDIT Tue Apr 9 20:57:30 2013) Well, I think I finally found what these square brackets in one-liners are about; they are "list comprehensions" (apparently); first note this in Python 2.7:



                  $ STR=abc
                  $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
                  <generator object <genexpr> at 0xb771461c>


                  So the command in round brackets/parenthesis is seen as a "generator object"; if we "iterate" through it by calling next() - then the command inside the parenthesis will be executed (note the "abc" in the output):



                  $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
                  abc
                  <generator object <genexpr> at 0xb777b734>


                  If we now use square brackets - note that we don't need to call next() to have the command execute, it executes immediately upon assignment; however, later inspection reveals that a is None:



                  $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
                  abc
                  [None]


                  This doesn't leave much info to look for, for the square brackets case - but I stumbled upon this page which I think explains:



                  Python Tips And Tricks – First Edition - Python Tutorials | Dream.In.Code:




                  If you recall, the standard format of a single line generator is a kind of one line 'for' loop inside brackets. This will produce a 'one-shot' iterable object which is an object you can iterate over in only one direction and which you can't re-use once you reach the end.



                  A 'list comprehension' looks almost the same as a regular one-line generator, except that the regular brackets - ( ) - are replaced by square brackets - [ ]. The major advanatge of alist comprehension is that produces a 'list', rather than a 'one-shot' iterable object, so that you can go back and forth through it, add elements, sort, etc.




                  And indeed it is a list - it's just its first element becomes none as soon as it is executed:



                  $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
                  abc
                  <type 'list'>
                  $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
                  abc
                  None


                  List comprehensions are otherwise documented in 5. Data Structures: 5.1.4. List Comprehensions — Python v2.7.4 documentation as "List comprehensions provide a concise way to create lists"; presumably, that's where the limited "executability" of lists comes into play in one-liners.



                  Well, hope I'm not terribly too off the mark here ...



                  EDIT2: and here is a one-liner command line with two non-nested for-loops; both enclosed within "list comprehension" square brackets:



                  $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
                  abc
                  01[None]
                  [None, None]


                  Notice that the second "list" b now has two elements, since its for loop explicitly ran twice; however, the result of sys.stdout.write() in both cases was (apparently) None.






                  share|improve this answer


























                  • This solution works on Windows as well!

                    – Nick
                    Jul 7 '15 at 16:36



















                  3














                  This variant is most portable for putting multi-line scripts on command-line on Windows and *nix, py2/3, without pipes:



                  python -c "exec("import sys nfor r in range(10): print('rob') ")"


                  (None of the other examples seen here so far did so)



                  Neat on Windows is:



                  python -c exec"""import sys nfor r in range(10): print 'rob' """
                  python -c exec("""import sys nfor r in range(10): print('rob') """)


                  Neat on bash/*nix is:



                  python -c $'import sys nfor r in range(10): print("rob")'




                  This function turns any multiline-script into a portable command-one-liner:



                  def py2cmdline(script):
                  exs = 'exec(%r)' % re.sub('rn|r', 'n', script.rstrip())
                  print('python -c "%s"' % exs.replace('"', r'"'))


                  Usage:



                  >>> py2cmdline(getcliptext())
                  python -c "exec('print 'AAtA'ntry:n for i in 1, 2, 3:n print i / 0nexcept:n print """longernmessage"""')"


                  Input was:



                  print 'AA   A'
                  try:
                  for i in 1, 2, 3:
                  print i / 0
                  except:
                  print """longer
                  message"""





                  share|improve this answer


























                  • ++ for the cross-platform angle and the converter. Your first command is as good as it gets in terms of portability (leaving PowerShell aside), but ultimately there is no single, fully robust cross-platform syntax, because the need to use double quotes then bears the risk of unwanted shell expansions, with Windows requiring escaping of different characters than POSIX-like shells. In PowerShell v3 or higher you can make your command lines work by inserting the "stop-parsing" option --% before the command-string argument.

                    – mklement0
                    Jul 7 '16 at 18:45











                  • @mklement0 "unwanted shell expansions": well, the insertion of shell expansions into something like print "path is %%PATH%%" resp. print "path is $PATH" is usually the option which one wants in a script or command-line - unless one escapes things as usual for the platform. Same with other languages. (The Python syntax itself does not regularly suggest the use of % and $'s in a competing way.)

                    – kxr
                    Aug 5 '16 at 7:07











                  • If you insert shell-variable references directly into the Python source code, it will by definition not be portable. My point is that even if you instead constructed platform-specific references in separate variables that you pass as arguments to a single, "shell-free" Python command, that may not always work, because you cannot protect the double-quoted string portably: e.g., what if you need literal $foo in your Python code? If you escape it as $foo for the benefit of POSIX-like shells, cmd.exe will still see the extra . It may be rare but it's worth knowing about.

                    – mklement0
                    Aug 6 '16 at 14:53











                  • Trying to do this in Windows PowerShell, but the problem is that python -c exec("""...""") doesn't produce any output whatsoever, no matter if the code in ... is able to be executed or not; I could put any gibberish there, and the result would be the same. I feel like the shell is "eating" both the stdout and stderr streams - how can I make it spit them out?

                    – Yury
                    Feb 1 at 6:26





















                  2














                  single/double quotes and backslash everywhere:



                  $ python -c 'exec("import sysnfor i in range(10): print "bob"")'


                  Much better:



                  $ python -c '
                  > import sys
                  > for i in range(10):
                  > print "bob"
                  > '





                  share|improve this answer































                    2














                    This script provides a Perl-like command line interface:



                    Pyliner - Script to run arbitrary Python code on the command line (Python recipe)






                    share|improve this answer


























                    • I think they wanted something to fix that, not to use another tool. Anyway nice hint

                      – enrico.bacis
                      Oct 29 '12 at 11:02











                    • I agree with @enrico.bacis, but I am still happy you added this answer. It answers the question I had when I Googled this page.

                      – tbc0
                      Jul 29 '13 at 18:05



















                    1














                    I wanted a solution with the following properties:




                    1. Readable

                    2. Read stdin for processing output of other tools


                    Both requirements were not provided in the other answers, so here's how to read stdin while doing everything on the command line:



                    grep special_string -r | sort | python3 <(cat <<EOF
                    import sys
                    for line in sys.stdin:
                    tokens = line.split()
                    if len(tokens) == 4:
                    print("%-45s %7.3f %s %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
                    EOF
                    )





                    share|improve this answer

































                      0














                      there is one more option, sys.stdout.write returns None, which keep the list empty





                      cat somefile.log|python -c "import sys;[line for line in sys.stdin if sys.stdout.write(line*2)]"





                      share|improve this answer

































                        0














                        I've written a simple web page for this. You can paste your multiple-line code there and it is converted into a working single-line statement.



                        Python Single Line Converter






                        share|improve this answer

































                          0














                          If you don't want to touch stdin and simulate as if you had passed "python cmdfile.py", you can do the following from a bash shell:



                          $ python  <(printf "word=raw_input('Enter word: ')nimport sysnfor i in range(5):n    print(word)")


                          As you can see, it allows you to use stdin for reading input data. Internally the shell creates the temporary file for the input command contents.






                          share|improve this answer


























                          • ++ for not "using up" stdin with the script itself (though -c "$(...)" does the same, and is POSIX-compliant); to give the <(...) construct a name: process substitution; it also works in ksh and zsh.

                            – mklement0
                            Jul 7 '16 at 19:54



















                          0














                          When I needed to do this, I use



                          python -c "$(echo -e "import sysnsys.stdout.write('Hello World!\n')")"


                          Note the triple backslash for the newline in the sys.stdout.write statement.






                          share|improve this answer


























                          • This works, but since you're using echo -e, which is nonstandard and requires bash, ksh, or zsh, you may as well use a $'...' string directly, which also simplifies the escaping: python -c $'import sysnsys.stdout.write("Hello World!\n")'

                            – mklement0
                            Jul 7 '16 at 18:35











                          Your Answer






                          StackExchange.ifUsing("editor", function () {
                          StackExchange.using("externalEditor", function () {
                          StackExchange.using("snippets", function () {
                          StackExchange.snippets.init();
                          });
                          });
                          }, "code-snippets");

                          StackExchange.ready(function() {
                          var channelOptions = {
                          tags: "".split(" "),
                          id: "1"
                          };
                          initTagRenderer("".split(" "), "".split(" "), channelOptions);

                          StackExchange.using("externalEditor", function() {
                          // Have to fire editor after snippets, if snippets enabled
                          if (StackExchange.settings.snippets.snippetsEnabled) {
                          StackExchange.using("snippets", function() {
                          createEditor();
                          });
                          }
                          else {
                          createEditor();
                          }
                          });

                          function createEditor() {
                          StackExchange.prepareEditor({
                          heartbeatType: 'answer',
                          autoActivateHeartbeat: false,
                          convertImagesToLinks: true,
                          noModals: true,
                          showLowRepImageUploadWarning: true,
                          reputationToPostImages: 10,
                          bindNavPrevention: true,
                          postfix: "",
                          imageUploader: {
                          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                          allowUrls: true
                          },
                          onDemand: true,
                          discardSelector: ".discard-answer"
                          ,immediatelyShowMarkdownHelp:true
                          });


                          }
                          });














                          draft saved

                          draft discarded


















                          StackExchange.ready(
                          function () {
                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2043453%2fexecuting-python-multi-line-statements-in-the-one-line-command-line%23new-answer', 'question_page');
                          }
                          );

                          Post as a guest















                          Required, but never shown

























                          18 Answers
                          18






                          active

                          oldest

                          votes








                          18 Answers
                          18






                          active

                          oldest

                          votes









                          active

                          oldest

                          votes






                          active

                          oldest

                          votes









                          144














                          you could do



                          echo -e "import sysnfor r in range(10): print 'rob'" | python


                          or w/out pipes:



                          python -c "exec("import sysnfor r in range(10): print 'rob'")"



                          or



                          (echo "import sys" ; echo "for r in range(10): print 'rob'") | python


                          or @SilentGhost's answer / @Crast's answer






                          share|improve this answer






























                            144














                            you could do



                            echo -e "import sysnfor r in range(10): print 'rob'" | python


                            or w/out pipes:



                            python -c "exec("import sysnfor r in range(10): print 'rob'")"



                            or



                            (echo "import sys" ; echo "for r in range(10): print 'rob'") | python


                            or @SilentGhost's answer / @Crast's answer






                            share|improve this answer




























                              144












                              144








                              144







                              you could do



                              echo -e "import sysnfor r in range(10): print 'rob'" | python


                              or w/out pipes:



                              python -c "exec("import sysnfor r in range(10): print 'rob'")"



                              or



                              (echo "import sys" ; echo "for r in range(10): print 'rob'") | python


                              or @SilentGhost's answer / @Crast's answer






                              share|improve this answer















                              you could do



                              echo -e "import sysnfor r in range(10): print 'rob'" | python


                              or w/out pipes:



                              python -c "exec("import sysnfor r in range(10): print 'rob'")"



                              or



                              (echo "import sys" ; echo "for r in range(10): print 'rob'") | python


                              or @SilentGhost's answer / @Crast's answer







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Nov 14 '18 at 21:43









                              lobeg25

                              53




                              53










                              answered Jan 11 '10 at 17:18









                              jspcaljspcal

                              39.3k45161




                              39.3k45161

























                                  77














                                  this style can be used in makefiles too (and in fact it is used quite often).



                                  python - <<EOF
                                  import sys
                                  for r in range(3): print 'rob'
                                  EOF


                                  or



                                  python - <<-EOF
                                  import sys
                                  for r in range(3): print 'rob'
                                  EOF


                                  in latter case leading tab characters are removed too (and some structured outlook can be achieved)



                                  instead of EOF can stand any marker word not appearing in the here document at a beginning of a line (see also here documents in the bash manpage or here).






                                  share|improve this answer





















                                  • 9





                                    Nice. To also pass arguments, simply place them after <<EOF. Note, however, that it's better to quote the delimiter - e.g., <<'EOF' - so as to protect the contents of the here-document from up-front shell expansions.

                                    – mklement0
                                    Apr 10 '15 at 15:11
















                                  77














                                  this style can be used in makefiles too (and in fact it is used quite often).



                                  python - <<EOF
                                  import sys
                                  for r in range(3): print 'rob'
                                  EOF


                                  or



                                  python - <<-EOF
                                  import sys
                                  for r in range(3): print 'rob'
                                  EOF


                                  in latter case leading tab characters are removed too (and some structured outlook can be achieved)



                                  instead of EOF can stand any marker word not appearing in the here document at a beginning of a line (see also here documents in the bash manpage or here).






                                  share|improve this answer





















                                  • 9





                                    Nice. To also pass arguments, simply place them after <<EOF. Note, however, that it's better to quote the delimiter - e.g., <<'EOF' - so as to protect the contents of the here-document from up-front shell expansions.

                                    – mklement0
                                    Apr 10 '15 at 15:11














                                  77












                                  77








                                  77







                                  this style can be used in makefiles too (and in fact it is used quite often).



                                  python - <<EOF
                                  import sys
                                  for r in range(3): print 'rob'
                                  EOF


                                  or



                                  python - <<-EOF
                                  import sys
                                  for r in range(3): print 'rob'
                                  EOF


                                  in latter case leading tab characters are removed too (and some structured outlook can be achieved)



                                  instead of EOF can stand any marker word not appearing in the here document at a beginning of a line (see also here documents in the bash manpage or here).






                                  share|improve this answer















                                  this style can be used in makefiles too (and in fact it is used quite often).



                                  python - <<EOF
                                  import sys
                                  for r in range(3): print 'rob'
                                  EOF


                                  or



                                  python - <<-EOF
                                  import sys
                                  for r in range(3): print 'rob'
                                  EOF


                                  in latter case leading tab characters are removed too (and some structured outlook can be achieved)



                                  instead of EOF can stand any marker word not appearing in the here document at a beginning of a line (see also here documents in the bash manpage or here).







                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Mar 25 '15 at 1:01









                                  Gavin Wahl

                                  786619




                                  786619










                                  answered Mar 1 '10 at 14:38









                                  xorhoxorho

                                  77142




                                  77142








                                  • 9





                                    Nice. To also pass arguments, simply place them after <<EOF. Note, however, that it's better to quote the delimiter - e.g., <<'EOF' - so as to protect the contents of the here-document from up-front shell expansions.

                                    – mklement0
                                    Apr 10 '15 at 15:11














                                  • 9





                                    Nice. To also pass arguments, simply place them after <<EOF. Note, however, that it's better to quote the delimiter - e.g., <<'EOF' - so as to protect the contents of the here-document from up-front shell expansions.

                                    – mklement0
                                    Apr 10 '15 at 15:11








                                  9




                                  9





                                  Nice. To also pass arguments, simply place them after <<EOF. Note, however, that it's better to quote the delimiter - e.g., <<'EOF' - so as to protect the contents of the here-document from up-front shell expansions.

                                  – mklement0
                                  Apr 10 '15 at 15:11





                                  Nice. To also pass arguments, simply place them after <<EOF. Note, however, that it's better to quote the delimiter - e.g., <<'EOF' - so as to protect the contents of the here-document from up-front shell expansions.

                                  – mklement0
                                  Apr 10 '15 at 15:11











                                  43














                                  The issue is not actually with the import statement, it's with anything being before the for loop. Or more specifically, anything appearing before an inlined block.



                                  For example, these all work:



                                  python -c "import sys; print 'rob'"
                                  python -c "import sys; sys.stdout.write('robn')"


                                  If import being a statement were an issue, this would work, but it doesn't:



                                  python -c "__import__('sys'); for r in range(10): print 'rob'"


                                  For your very basic example, you could rewrite it as this:



                                  python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"


                                  However, lambdas can only execute expressions, not statements or multiple statements, so you may still be unable to do the thing you want to do. However, between generator expressions, list comprehension, lambdas, sys.stdout.write, the "map" builtin, and some creative string interpolation, you can do some powerful one-liners.



                                  The question is, how far do you want to go, and at what point is it not better to write a small .py file which your makefile executes instead?






                                  share|improve this answer




























                                    43














                                    The issue is not actually with the import statement, it's with anything being before the for loop. Or more specifically, anything appearing before an inlined block.



                                    For example, these all work:



                                    python -c "import sys; print 'rob'"
                                    python -c "import sys; sys.stdout.write('robn')"


                                    If import being a statement were an issue, this would work, but it doesn't:



                                    python -c "__import__('sys'); for r in range(10): print 'rob'"


                                    For your very basic example, you could rewrite it as this:



                                    python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"


                                    However, lambdas can only execute expressions, not statements or multiple statements, so you may still be unable to do the thing you want to do. However, between generator expressions, list comprehension, lambdas, sys.stdout.write, the "map" builtin, and some creative string interpolation, you can do some powerful one-liners.



                                    The question is, how far do you want to go, and at what point is it not better to write a small .py file which your makefile executes instead?






                                    share|improve this answer


























                                      43












                                      43








                                      43







                                      The issue is not actually with the import statement, it's with anything being before the for loop. Or more specifically, anything appearing before an inlined block.



                                      For example, these all work:



                                      python -c "import sys; print 'rob'"
                                      python -c "import sys; sys.stdout.write('robn')"


                                      If import being a statement were an issue, this would work, but it doesn't:



                                      python -c "__import__('sys'); for r in range(10): print 'rob'"


                                      For your very basic example, you could rewrite it as this:



                                      python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"


                                      However, lambdas can only execute expressions, not statements or multiple statements, so you may still be unable to do the thing you want to do. However, between generator expressions, list comprehension, lambdas, sys.stdout.write, the "map" builtin, and some creative string interpolation, you can do some powerful one-liners.



                                      The question is, how far do you want to go, and at what point is it not better to write a small .py file which your makefile executes instead?






                                      share|improve this answer













                                      The issue is not actually with the import statement, it's with anything being before the for loop. Or more specifically, anything appearing before an inlined block.



                                      For example, these all work:



                                      python -c "import sys; print 'rob'"
                                      python -c "import sys; sys.stdout.write('robn')"


                                      If import being a statement were an issue, this would work, but it doesn't:



                                      python -c "__import__('sys'); for r in range(10): print 'rob'"


                                      For your very basic example, you could rewrite it as this:



                                      python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"


                                      However, lambdas can only execute expressions, not statements or multiple statements, so you may still be unable to do the thing you want to do. However, between generator expressions, list comprehension, lambdas, sys.stdout.write, the "map" builtin, and some creative string interpolation, you can do some powerful one-liners.



                                      The question is, how far do you want to go, and at what point is it not better to write a small .py file which your makefile executes instead?







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Jan 11 '10 at 17:39









                                      CrastCrast

                                      12.4k33250




                                      12.4k33250























                                          18
















                                          - To make this answer work with Python 3.x as well, print is called as a function: in 3.x, only print('foo') works, whereas 2.x also accepts print 'foo'.

                                          - For a cross-platform perspective that includes Windows, see kxr's helpful answer.



                                          In bash, ksh, or zsh:



                                          Use an ANSI C-quoted string ($'...'), which allows using n to represent newlines that are expanded to actual newlines before the string is passed to python:



                                          python -c $'import sysnfor r in range(10): print("rob")'


                                          Note the n between the import and for statements to effect a line break.



                                          To pass shell-variable values to such a command, it is safest to use arguments and access them via sys.argv inside the Python script:



                                          name='rob' # value to pass to the Python script
                                          python -c $'import sysnfor r in range(10): print(sys.argv[1])' "$name"


                                          See below for a discussion of the pros and cons of using an (escape sequence-preprocessed) double-quoted command string with embedded shell-variable references.



                                          To work safely with $'...' strings:





                                          • Double instances in your original source code.



                                            • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by $'...' (see man printf for the supported escapes)



                                          • Escape ' instances as '.




                                          If you must remain POSIX-compliant:



                                          Use printf with a command substitution:



                                          python -c "$(printf %b 'import sysnfor r in range(10): print("rob")')"


                                          To work safely with this type of string:





                                          • Double instances in your original source code.



                                            • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by printf (see man printf for the supported escape sequences).




                                          • Pass a single-quoted string to printf %b and escape embedded single quotes as ''' (sic).





                                            • Using single quotes protects the string's contents from interpretation by the shell.





                                              • That said, for short Python scripts (as in this case) you can use a double-quoted string to incorporate shell variable values into your scripts - as long as you're aware of the associated pitfalls (see next point); e.g., the shell expands $HOME to the current user's home dir. in the following command:




                                                • python -c "$(printf %b "import sysnfor r in range(10): print('rob is $HOME')")"




                                              • However, the generally preferred approach is to pass values from the shell via arguments, and access them via sys.argv in Python; the equivalent of the above command is:




                                                • python -c "$(printf %b 'import sysnfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"






                                            • While using a double-quoted string is more convenient - it allows you to use embedded single quotes unescaped and embedded double quotes as " - it also makes the string subject to interpretation by the shell, which may or may not be the intent; $ and ` characters in your source code that are not meant for the shell may cause a syntax error or alter the string unexpectedly.




                                              • Additionally, the shell's own processing in double-quoted strings can get in the way; for instance, to get Python to produce literal output rob, you must pass ro\b to it; with a '...' shell string and doubled instances, we get:
                                                python -c "$(printf %b 'import sysnprint("ro\\bs")')" # ok: 'robs'

                                                By contrast, this does not work as intended with a "..." shell string:
                                                python -c "$(printf %b "import sysnprint('ro\\bs')")" # !! INCORRECT: 'rs'

                                                The shell interprets both "b" and "\b" as literal b, requiring a dizzying number of additional instances to achieve the desired effect:
                                                python -c "$(printf %b "import sysnprint('ro\\\\bs')")"








                                          To pass the code via stdin rather than -c:



                                          Note: I'm focusing on single-line solutions here; xorho's answer shows how to use a multi-line here-document - be sure to quote the delimiter, however; e.g., <<'EOF', unless you explicitly want the shell to expand the string up front (which comes with the caveats noted above).





                                          In bash, ksh, or zsh:



                                          Combine an ANSI C-quoted string ($'...') with a here-string (<<<...):



                                          python - <<<$'import sysnfor r in range(10): print("rob")'


                                          - tells python explicitly to read from stdin (which it does by default).
                                          - is optional in this case, but if you also want to pass arguments to the scripts, you do need it to disambiguate the argument from a script filename:



                                          python - 'rob' <<<$'import sysnfor r in range(10): print(sys.argv[1])'




                                          If you must remain POSIX-compliant:



                                          Use printf as above, but with a pipeline so as to pass its output via stdin:



                                          printf %b 'import sysnfor r in range(10): print("rob")' | python


                                          With an argument:



                                          printf %b 'import sysnfor r in range(10): print(sys.argv[1])' | python - 'rob'





                                          share|improve this answer





















                                          • 1





                                            This should be the elected answer!

                                            – debuti
                                            Jan 16 at 17:25
















                                          18
















                                          - To make this answer work with Python 3.x as well, print is called as a function: in 3.x, only print('foo') works, whereas 2.x also accepts print 'foo'.

                                          - For a cross-platform perspective that includes Windows, see kxr's helpful answer.



                                          In bash, ksh, or zsh:



                                          Use an ANSI C-quoted string ($'...'), which allows using n to represent newlines that are expanded to actual newlines before the string is passed to python:



                                          python -c $'import sysnfor r in range(10): print("rob")'


                                          Note the n between the import and for statements to effect a line break.



                                          To pass shell-variable values to such a command, it is safest to use arguments and access them via sys.argv inside the Python script:



                                          name='rob' # value to pass to the Python script
                                          python -c $'import sysnfor r in range(10): print(sys.argv[1])' "$name"


                                          See below for a discussion of the pros and cons of using an (escape sequence-preprocessed) double-quoted command string with embedded shell-variable references.



                                          To work safely with $'...' strings:





                                          • Double instances in your original source code.



                                            • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by $'...' (see man printf for the supported escapes)



                                          • Escape ' instances as '.




                                          If you must remain POSIX-compliant:



                                          Use printf with a command substitution:



                                          python -c "$(printf %b 'import sysnfor r in range(10): print("rob")')"


                                          To work safely with this type of string:





                                          • Double instances in your original source code.



                                            • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by printf (see man printf for the supported escape sequences).




                                          • Pass a single-quoted string to printf %b and escape embedded single quotes as ''' (sic).





                                            • Using single quotes protects the string's contents from interpretation by the shell.





                                              • That said, for short Python scripts (as in this case) you can use a double-quoted string to incorporate shell variable values into your scripts - as long as you're aware of the associated pitfalls (see next point); e.g., the shell expands $HOME to the current user's home dir. in the following command:




                                                • python -c "$(printf %b "import sysnfor r in range(10): print('rob is $HOME')")"




                                              • However, the generally preferred approach is to pass values from the shell via arguments, and access them via sys.argv in Python; the equivalent of the above command is:




                                                • python -c "$(printf %b 'import sysnfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"






                                            • While using a double-quoted string is more convenient - it allows you to use embedded single quotes unescaped and embedded double quotes as " - it also makes the string subject to interpretation by the shell, which may or may not be the intent; $ and ` characters in your source code that are not meant for the shell may cause a syntax error or alter the string unexpectedly.




                                              • Additionally, the shell's own processing in double-quoted strings can get in the way; for instance, to get Python to produce literal output rob, you must pass ro\b to it; with a '...' shell string and doubled instances, we get:
                                                python -c "$(printf %b 'import sysnprint("ro\\bs")')" # ok: 'robs'

                                                By contrast, this does not work as intended with a "..." shell string:
                                                python -c "$(printf %b "import sysnprint('ro\\bs')")" # !! INCORRECT: 'rs'

                                                The shell interprets both "b" and "\b" as literal b, requiring a dizzying number of additional instances to achieve the desired effect:
                                                python -c "$(printf %b "import sysnprint('ro\\\\bs')")"








                                          To pass the code via stdin rather than -c:



                                          Note: I'm focusing on single-line solutions here; xorho's answer shows how to use a multi-line here-document - be sure to quote the delimiter, however; e.g., <<'EOF', unless you explicitly want the shell to expand the string up front (which comes with the caveats noted above).





                                          In bash, ksh, or zsh:



                                          Combine an ANSI C-quoted string ($'...') with a here-string (<<<...):



                                          python - <<<$'import sysnfor r in range(10): print("rob")'


                                          - tells python explicitly to read from stdin (which it does by default).
                                          - is optional in this case, but if you also want to pass arguments to the scripts, you do need it to disambiguate the argument from a script filename:



                                          python - 'rob' <<<$'import sysnfor r in range(10): print(sys.argv[1])'




                                          If you must remain POSIX-compliant:



                                          Use printf as above, but with a pipeline so as to pass its output via stdin:



                                          printf %b 'import sysnfor r in range(10): print("rob")' | python


                                          With an argument:



                                          printf %b 'import sysnfor r in range(10): print(sys.argv[1])' | python - 'rob'





                                          share|improve this answer





















                                          • 1





                                            This should be the elected answer!

                                            – debuti
                                            Jan 16 at 17:25














                                          18












                                          18








                                          18









                                          - To make this answer work with Python 3.x as well, print is called as a function: in 3.x, only print('foo') works, whereas 2.x also accepts print 'foo'.

                                          - For a cross-platform perspective that includes Windows, see kxr's helpful answer.



                                          In bash, ksh, or zsh:



                                          Use an ANSI C-quoted string ($'...'), which allows using n to represent newlines that are expanded to actual newlines before the string is passed to python:



                                          python -c $'import sysnfor r in range(10): print("rob")'


                                          Note the n between the import and for statements to effect a line break.



                                          To pass shell-variable values to such a command, it is safest to use arguments and access them via sys.argv inside the Python script:



                                          name='rob' # value to pass to the Python script
                                          python -c $'import sysnfor r in range(10): print(sys.argv[1])' "$name"


                                          See below for a discussion of the pros and cons of using an (escape sequence-preprocessed) double-quoted command string with embedded shell-variable references.



                                          To work safely with $'...' strings:





                                          • Double instances in your original source code.



                                            • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by $'...' (see man printf for the supported escapes)



                                          • Escape ' instances as '.




                                          If you must remain POSIX-compliant:



                                          Use printf with a command substitution:



                                          python -c "$(printf %b 'import sysnfor r in range(10): print("rob")')"


                                          To work safely with this type of string:





                                          • Double instances in your original source code.



                                            • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by printf (see man printf for the supported escape sequences).




                                          • Pass a single-quoted string to printf %b and escape embedded single quotes as ''' (sic).





                                            • Using single quotes protects the string's contents from interpretation by the shell.





                                              • That said, for short Python scripts (as in this case) you can use a double-quoted string to incorporate shell variable values into your scripts - as long as you're aware of the associated pitfalls (see next point); e.g., the shell expands $HOME to the current user's home dir. in the following command:




                                                • python -c "$(printf %b "import sysnfor r in range(10): print('rob is $HOME')")"




                                              • However, the generally preferred approach is to pass values from the shell via arguments, and access them via sys.argv in Python; the equivalent of the above command is:




                                                • python -c "$(printf %b 'import sysnfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"






                                            • While using a double-quoted string is more convenient - it allows you to use embedded single quotes unescaped and embedded double quotes as " - it also makes the string subject to interpretation by the shell, which may or may not be the intent; $ and ` characters in your source code that are not meant for the shell may cause a syntax error or alter the string unexpectedly.




                                              • Additionally, the shell's own processing in double-quoted strings can get in the way; for instance, to get Python to produce literal output rob, you must pass ro\b to it; with a '...' shell string and doubled instances, we get:
                                                python -c "$(printf %b 'import sysnprint("ro\\bs")')" # ok: 'robs'

                                                By contrast, this does not work as intended with a "..." shell string:
                                                python -c "$(printf %b "import sysnprint('ro\\bs')")" # !! INCORRECT: 'rs'

                                                The shell interprets both "b" and "\b" as literal b, requiring a dizzying number of additional instances to achieve the desired effect:
                                                python -c "$(printf %b "import sysnprint('ro\\\\bs')")"








                                          To pass the code via stdin rather than -c:



                                          Note: I'm focusing on single-line solutions here; xorho's answer shows how to use a multi-line here-document - be sure to quote the delimiter, however; e.g., <<'EOF', unless you explicitly want the shell to expand the string up front (which comes with the caveats noted above).





                                          In bash, ksh, or zsh:



                                          Combine an ANSI C-quoted string ($'...') with a here-string (<<<...):



                                          python - <<<$'import sysnfor r in range(10): print("rob")'


                                          - tells python explicitly to read from stdin (which it does by default).
                                          - is optional in this case, but if you also want to pass arguments to the scripts, you do need it to disambiguate the argument from a script filename:



                                          python - 'rob' <<<$'import sysnfor r in range(10): print(sys.argv[1])'




                                          If you must remain POSIX-compliant:



                                          Use printf as above, but with a pipeline so as to pass its output via stdin:



                                          printf %b 'import sysnfor r in range(10): print("rob")' | python


                                          With an argument:



                                          printf %b 'import sysnfor r in range(10): print(sys.argv[1])' | python - 'rob'





                                          share|improve this answer

















                                          - To make this answer work with Python 3.x as well, print is called as a function: in 3.x, only print('foo') works, whereas 2.x also accepts print 'foo'.

                                          - For a cross-platform perspective that includes Windows, see kxr's helpful answer.



                                          In bash, ksh, or zsh:



                                          Use an ANSI C-quoted string ($'...'), which allows using n to represent newlines that are expanded to actual newlines before the string is passed to python:



                                          python -c $'import sysnfor r in range(10): print("rob")'


                                          Note the n between the import and for statements to effect a line break.



                                          To pass shell-variable values to such a command, it is safest to use arguments and access them via sys.argv inside the Python script:



                                          name='rob' # value to pass to the Python script
                                          python -c $'import sysnfor r in range(10): print(sys.argv[1])' "$name"


                                          See below for a discussion of the pros and cons of using an (escape sequence-preprocessed) double-quoted command string with embedded shell-variable references.



                                          To work safely with $'...' strings:





                                          • Double instances in your original source code.



                                            • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by $'...' (see man printf for the supported escapes)



                                          • Escape ' instances as '.




                                          If you must remain POSIX-compliant:



                                          Use printf with a command substitution:



                                          python -c "$(printf %b 'import sysnfor r in range(10): print("rob")')"


                                          To work safely with this type of string:





                                          • Double instances in your original source code.



                                            • <char> sequences - such as n in this case, but also the usual suspects such as t, r, b - are expanded by printf (see man printf for the supported escape sequences).




                                          • Pass a single-quoted string to printf %b and escape embedded single quotes as ''' (sic).





                                            • Using single quotes protects the string's contents from interpretation by the shell.





                                              • That said, for short Python scripts (as in this case) you can use a double-quoted string to incorporate shell variable values into your scripts - as long as you're aware of the associated pitfalls (see next point); e.g., the shell expands $HOME to the current user's home dir. in the following command:




                                                • python -c "$(printf %b "import sysnfor r in range(10): print('rob is $HOME')")"




                                              • However, the generally preferred approach is to pass values from the shell via arguments, and access them via sys.argv in Python; the equivalent of the above command is:




                                                • python -c "$(printf %b 'import sysnfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"






                                            • While using a double-quoted string is more convenient - it allows you to use embedded single quotes unescaped and embedded double quotes as " - it also makes the string subject to interpretation by the shell, which may or may not be the intent; $ and ` characters in your source code that are not meant for the shell may cause a syntax error or alter the string unexpectedly.




                                              • Additionally, the shell's own processing in double-quoted strings can get in the way; for instance, to get Python to produce literal output rob, you must pass ro\b to it; with a '...' shell string and doubled instances, we get:
                                                python -c "$(printf %b 'import sysnprint("ro\\bs")')" # ok: 'robs'

                                                By contrast, this does not work as intended with a "..." shell string:
                                                python -c "$(printf %b "import sysnprint('ro\\bs')")" # !! INCORRECT: 'rs'

                                                The shell interprets both "b" and "\b" as literal b, requiring a dizzying number of additional instances to achieve the desired effect:
                                                python -c "$(printf %b "import sysnprint('ro\\\\bs')")"








                                          To pass the code via stdin rather than -c:



                                          Note: I'm focusing on single-line solutions here; xorho's answer shows how to use a multi-line here-document - be sure to quote the delimiter, however; e.g., <<'EOF', unless you explicitly want the shell to expand the string up front (which comes with the caveats noted above).





                                          In bash, ksh, or zsh:



                                          Combine an ANSI C-quoted string ($'...') with a here-string (<<<...):



                                          python - <<<$'import sysnfor r in range(10): print("rob")'


                                          - tells python explicitly to read from stdin (which it does by default).
                                          - is optional in this case, but if you also want to pass arguments to the scripts, you do need it to disambiguate the argument from a script filename:



                                          python - 'rob' <<<$'import sysnfor r in range(10): print(sys.argv[1])'




                                          If you must remain POSIX-compliant:



                                          Use printf as above, but with a pipeline so as to pass its output via stdin:



                                          printf %b 'import sysnfor r in range(10): print("rob")' | python


                                          With an argument:



                                          printf %b 'import sysnfor r in range(10): print(sys.argv[1])' | python - 'rob'






                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited May 23 '17 at 12:18









                                          Community

                                          11




                                          11










                                          answered Apr 10 '15 at 15:44









                                          mklement0mklement0

                                          132k21246284




                                          132k21246284








                                          • 1





                                            This should be the elected answer!

                                            – debuti
                                            Jan 16 at 17:25














                                          • 1





                                            This should be the elected answer!

                                            – debuti
                                            Jan 16 at 17:25








                                          1




                                          1





                                          This should be the elected answer!

                                          – debuti
                                          Jan 16 at 17:25





                                          This should be the elected answer!

                                          – debuti
                                          Jan 16 at 17:25











                                          12















                                          Any idea how this can be fixed?




                                          Your problem is created by the fact that Python statements, separated by ;, are only allowed to be "small statements", which are all one-liners. From the grammar file in the Python docs:




                                          stmt: simple_stmt | compound_stmt
                                          simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
                                          small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
                                          import_stmt | global_stmt | nonlocal_stmt | assert_stmt)



                                          Compound statements can't be included on the same line with other statements via semicolons - so doing this with the -c flag becomes very inconvenient.



                                          When demonstrating Python while in a bash shell environment, I find it very useful to include compound statements. The only simple way of doing this is with heredocs.



                                          Heredocs



                                          Use a heredoc (created with <<) and Python's command line interface option, -:



                                          $ python - <<-"EOF"
                                          import sys # 1 tab indent
                                          for r in range(10): # 1 tab indent
                                          print('rob') # 1 tab indent and 4 spaces
                                          EOF


                                          Adding the - after << (the <<-) allows you to use tabs to indent (Stackoverflow converts tabs to spaces, so I've indented 8 spaces to emphasize this). The leading tabs will be stripped.



                                          You can do it without the tabs with just <<:



                                          $ python - << "EOF"
                                          import sys
                                          for r in range(10):
                                          print('rob')
                                          EOF


                                          Putting quotes around EOF prevents parameter and arithmetic expansion. This makes the heredoc more robust.



                                          Critique of the accepted answer (and others)



                                          This is not very readable:




                                          echo -e "import sysnfor r in range(10): print 'rob'" | python



                                          Not very readable, and additionally difficult to debug in the case of an error:




                                          python -c "exec("import sys\nfor r in range(10): print 'rob'")"



                                          Perhaps a bit more readable, but still quite ugly:




                                          (echo "import sys" ; echo "for r in range(10): print 'rob'") | python



                                          You'll have a bad time if you have "'s in your python:




                                          $ python -c "import sys
                                          > for r in range(10): print 'rob'"



                                          Don't abuse map or list comprehensions to get for-loops:




                                          python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"



                                          These are all sad and bad. Don't do them.






                                          share|improve this answer





















                                          • 2





                                            ++ for the grammar info; the (non-expanding) here-doc is handy and the most robust solution, but obviously not a one-liner. If a single-line solution is a must, using an ANSI C-quoted string (bash, ksh, or zsh) is a reasonable solution: python -c $'import sysnfor r in range(10): print('rob')' (you'll only have to worry about escaping single quotes (which you can avoid by using double quotes) and backslashes).

                                            – mklement0
                                            Jul 7 '16 at 19:56


















                                          12















                                          Any idea how this can be fixed?




                                          Your problem is created by the fact that Python statements, separated by ;, are only allowed to be "small statements", which are all one-liners. From the grammar file in the Python docs:




                                          stmt: simple_stmt | compound_stmt
                                          simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
                                          small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
                                          import_stmt | global_stmt | nonlocal_stmt | assert_stmt)



                                          Compound statements can't be included on the same line with other statements via semicolons - so doing this with the -c flag becomes very inconvenient.



                                          When demonstrating Python while in a bash shell environment, I find it very useful to include compound statements. The only simple way of doing this is with heredocs.



                                          Heredocs



                                          Use a heredoc (created with <<) and Python's command line interface option, -:



                                          $ python - <<-"EOF"
                                          import sys # 1 tab indent
                                          for r in range(10): # 1 tab indent
                                          print('rob') # 1 tab indent and 4 spaces
                                          EOF


                                          Adding the - after << (the <<-) allows you to use tabs to indent (Stackoverflow converts tabs to spaces, so I've indented 8 spaces to emphasize this). The leading tabs will be stripped.



                                          You can do it without the tabs with just <<:



                                          $ python - << "EOF"
                                          import sys
                                          for r in range(10):
                                          print('rob')
                                          EOF


                                          Putting quotes around EOF prevents parameter and arithmetic expansion. This makes the heredoc more robust.



                                          Critique of the accepted answer (and others)



                                          This is not very readable:




                                          echo -e "import sysnfor r in range(10): print 'rob'" | python



                                          Not very readable, and additionally difficult to debug in the case of an error:




                                          python -c "exec("import sys\nfor r in range(10): print 'rob'")"



                                          Perhaps a bit more readable, but still quite ugly:




                                          (echo "import sys" ; echo "for r in range(10): print 'rob'") | python



                                          You'll have a bad time if you have "'s in your python:




                                          $ python -c "import sys
                                          > for r in range(10): print 'rob'"



                                          Don't abuse map or list comprehensions to get for-loops:




                                          python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"



                                          These are all sad and bad. Don't do them.






                                          share|improve this answer





















                                          • 2





                                            ++ for the grammar info; the (non-expanding) here-doc is handy and the most robust solution, but obviously not a one-liner. If a single-line solution is a must, using an ANSI C-quoted string (bash, ksh, or zsh) is a reasonable solution: python -c $'import sysnfor r in range(10): print('rob')' (you'll only have to worry about escaping single quotes (which you can avoid by using double quotes) and backslashes).

                                            – mklement0
                                            Jul 7 '16 at 19:56
















                                          12












                                          12








                                          12








                                          Any idea how this can be fixed?




                                          Your problem is created by the fact that Python statements, separated by ;, are only allowed to be "small statements", which are all one-liners. From the grammar file in the Python docs:




                                          stmt: simple_stmt | compound_stmt
                                          simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
                                          small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
                                          import_stmt | global_stmt | nonlocal_stmt | assert_stmt)



                                          Compound statements can't be included on the same line with other statements via semicolons - so doing this with the -c flag becomes very inconvenient.



                                          When demonstrating Python while in a bash shell environment, I find it very useful to include compound statements. The only simple way of doing this is with heredocs.



                                          Heredocs



                                          Use a heredoc (created with <<) and Python's command line interface option, -:



                                          $ python - <<-"EOF"
                                          import sys # 1 tab indent
                                          for r in range(10): # 1 tab indent
                                          print('rob') # 1 tab indent and 4 spaces
                                          EOF


                                          Adding the - after << (the <<-) allows you to use tabs to indent (Stackoverflow converts tabs to spaces, so I've indented 8 spaces to emphasize this). The leading tabs will be stripped.



                                          You can do it without the tabs with just <<:



                                          $ python - << "EOF"
                                          import sys
                                          for r in range(10):
                                          print('rob')
                                          EOF


                                          Putting quotes around EOF prevents parameter and arithmetic expansion. This makes the heredoc more robust.



                                          Critique of the accepted answer (and others)



                                          This is not very readable:




                                          echo -e "import sysnfor r in range(10): print 'rob'" | python



                                          Not very readable, and additionally difficult to debug in the case of an error:




                                          python -c "exec("import sys\nfor r in range(10): print 'rob'")"



                                          Perhaps a bit more readable, but still quite ugly:




                                          (echo "import sys" ; echo "for r in range(10): print 'rob'") | python



                                          You'll have a bad time if you have "'s in your python:




                                          $ python -c "import sys
                                          > for r in range(10): print 'rob'"



                                          Don't abuse map or list comprehensions to get for-loops:




                                          python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"



                                          These are all sad and bad. Don't do them.






                                          share|improve this answer
















                                          Any idea how this can be fixed?




                                          Your problem is created by the fact that Python statements, separated by ;, are only allowed to be "small statements", which are all one-liners. From the grammar file in the Python docs:




                                          stmt: simple_stmt | compound_stmt
                                          simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
                                          small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
                                          import_stmt | global_stmt | nonlocal_stmt | assert_stmt)



                                          Compound statements can't be included on the same line with other statements via semicolons - so doing this with the -c flag becomes very inconvenient.



                                          When demonstrating Python while in a bash shell environment, I find it very useful to include compound statements. The only simple way of doing this is with heredocs.



                                          Heredocs



                                          Use a heredoc (created with <<) and Python's command line interface option, -:



                                          $ python - <<-"EOF"
                                          import sys # 1 tab indent
                                          for r in range(10): # 1 tab indent
                                          print('rob') # 1 tab indent and 4 spaces
                                          EOF


                                          Adding the - after << (the <<-) allows you to use tabs to indent (Stackoverflow converts tabs to spaces, so I've indented 8 spaces to emphasize this). The leading tabs will be stripped.



                                          You can do it without the tabs with just <<:



                                          $ python - << "EOF"
                                          import sys
                                          for r in range(10):
                                          print('rob')
                                          EOF


                                          Putting quotes around EOF prevents parameter and arithmetic expansion. This makes the heredoc more robust.



                                          Critique of the accepted answer (and others)



                                          This is not very readable:




                                          echo -e "import sysnfor r in range(10): print 'rob'" | python



                                          Not very readable, and additionally difficult to debug in the case of an error:




                                          python -c "exec("import sys\nfor r in range(10): print 'rob'")"



                                          Perhaps a bit more readable, but still quite ugly:




                                          (echo "import sys" ; echo "for r in range(10): print 'rob'") | python



                                          You'll have a bad time if you have "'s in your python:




                                          $ python -c "import sys
                                          > for r in range(10): print 'rob'"



                                          Don't abuse map or list comprehensions to get for-loops:




                                          python -c "import sys; map(lambda x: sys.stdout.write('rob%dn' % x), range(10))"



                                          These are all sad and bad. Don't do them.







                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited Jul 7 '16 at 18:20

























                                          answered Jul 6 '16 at 23:56









                                          Aaron HallAaron Hall

                                          176k51305255




                                          176k51305255








                                          • 2





                                            ++ for the grammar info; the (non-expanding) here-doc is handy and the most robust solution, but obviously not a one-liner. If a single-line solution is a must, using an ANSI C-quoted string (bash, ksh, or zsh) is a reasonable solution: python -c $'import sysnfor r in range(10): print('rob')' (you'll only have to worry about escaping single quotes (which you can avoid by using double quotes) and backslashes).

                                            – mklement0
                                            Jul 7 '16 at 19:56
















                                          • 2





                                            ++ for the grammar info; the (non-expanding) here-doc is handy and the most robust solution, but obviously not a one-liner. If a single-line solution is a must, using an ANSI C-quoted string (bash, ksh, or zsh) is a reasonable solution: python -c $'import sysnfor r in range(10): print('rob')' (you'll only have to worry about escaping single quotes (which you can avoid by using double quotes) and backslashes).

                                            – mklement0
                                            Jul 7 '16 at 19:56










                                          2




                                          2





                                          ++ for the grammar info; the (non-expanding) here-doc is handy and the most robust solution, but obviously not a one-liner. If a single-line solution is a must, using an ANSI C-quoted string (bash, ksh, or zsh) is a reasonable solution: python -c $'import sysnfor r in range(10): print('rob')' (you'll only have to worry about escaping single quotes (which you can avoid by using double quotes) and backslashes).

                                          – mklement0
                                          Jul 7 '16 at 19:56







                                          ++ for the grammar info; the (non-expanding) here-doc is handy and the most robust solution, but obviously not a one-liner. If a single-line solution is a must, using an ANSI C-quoted string (bash, ksh, or zsh) is a reasonable solution: python -c $'import sysnfor r in range(10): print('rob')' (you'll only have to worry about escaping single quotes (which you can avoid by using double quotes) and backslashes).

                                          – mklement0
                                          Jul 7 '16 at 19:56













                                          11














                                          just use return and type it on the next line:



                                          user@host:~$ python -c "import sys
                                          > for r in range(10): print 'rob'"
                                          rob
                                          rob
                                          ...





                                          share|improve this answer



















                                          • 5





                                            Seriously, you're going to sprain something if you keep doing this. python $(srcdir)/myscript.py for great justice.

                                            – Jason Orendorff
                                            Jan 11 '10 at 17:26
















                                          11














                                          just use return and type it on the next line:



                                          user@host:~$ python -c "import sys
                                          > for r in range(10): print 'rob'"
                                          rob
                                          rob
                                          ...





                                          share|improve this answer



















                                          • 5





                                            Seriously, you're going to sprain something if you keep doing this. python $(srcdir)/myscript.py for great justice.

                                            – Jason Orendorff
                                            Jan 11 '10 at 17:26














                                          11












                                          11








                                          11







                                          just use return and type it on the next line:



                                          user@host:~$ python -c "import sys
                                          > for r in range(10): print 'rob'"
                                          rob
                                          rob
                                          ...





                                          share|improve this answer













                                          just use return and type it on the next line:



                                          user@host:~$ python -c "import sys
                                          > for r in range(10): print 'rob'"
                                          rob
                                          rob
                                          ...






                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Jan 11 '10 at 17:14









                                          SilentGhostSilentGhost

                                          195k47267263




                                          195k47267263








                                          • 5





                                            Seriously, you're going to sprain something if you keep doing this. python $(srcdir)/myscript.py for great justice.

                                            – Jason Orendorff
                                            Jan 11 '10 at 17:26














                                          • 5





                                            Seriously, you're going to sprain something if you keep doing this. python $(srcdir)/myscript.py for great justice.

                                            – Jason Orendorff
                                            Jan 11 '10 at 17:26








                                          5




                                          5





                                          Seriously, you're going to sprain something if you keep doing this. python $(srcdir)/myscript.py for great justice.

                                          – Jason Orendorff
                                          Jan 11 '10 at 17:26





                                          Seriously, you're going to sprain something if you keep doing this. python $(srcdir)/myscript.py for great justice.

                                          – Jason Orendorff
                                          Jan 11 '10 at 17:26











                                          8














                                          The problem is not with the import statement. The problem is that the control flow statements don't work inlined in a python command. Replace that import statement with any other statement and you'll see the same problem.



                                          Think about it: python can't possibly inline everything. It uses indentation to group control-flow.






                                          share|improve this answer




























                                            8














                                            The problem is not with the import statement. The problem is that the control flow statements don't work inlined in a python command. Replace that import statement with any other statement and you'll see the same problem.



                                            Think about it: python can't possibly inline everything. It uses indentation to group control-flow.






                                            share|improve this answer


























                                              8












                                              8








                                              8







                                              The problem is not with the import statement. The problem is that the control flow statements don't work inlined in a python command. Replace that import statement with any other statement and you'll see the same problem.



                                              Think about it: python can't possibly inline everything. It uses indentation to group control-flow.






                                              share|improve this answer













                                              The problem is not with the import statement. The problem is that the control flow statements don't work inlined in a python command. Replace that import statement with any other statement and you'll see the same problem.



                                              Think about it: python can't possibly inline everything. It uses indentation to group control-flow.







                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Jan 11 '10 at 17:19









                                              David BergerDavid Berger

                                              8,06633347




                                              8,06633347























                                                  7














                                                  If your system is Posix.2 compliant it should supply the printf utility:



                                                  $ printf "print 'zap'nfor r in range(3): print 'rob'" | python
                                                  zap
                                                  rob
                                                  rob
                                                  rob





                                                  share|improve this answer



















                                                  • 2





                                                    Good solution, but I suggest using printf %b '...' | python for added robustness, because it prevents printf from interpreting sequences such as %d (format specifiers) in the input string. Also, unless you explicitly want to apply shell expansions to your Python command string up front (which can get confusing), it's better to use ' (single quotes) for the outer quoting, to avoid both the expansions and the backlash processing that the shell applies to double-quoted strings.

                                                    – mklement0
                                                    Jul 7 '16 at 14:40


















                                                  7














                                                  If your system is Posix.2 compliant it should supply the printf utility:



                                                  $ printf "print 'zap'nfor r in range(3): print 'rob'" | python
                                                  zap
                                                  rob
                                                  rob
                                                  rob





                                                  share|improve this answer



















                                                  • 2





                                                    Good solution, but I suggest using printf %b '...' | python for added robustness, because it prevents printf from interpreting sequences such as %d (format specifiers) in the input string. Also, unless you explicitly want to apply shell expansions to your Python command string up front (which can get confusing), it's better to use ' (single quotes) for the outer quoting, to avoid both the expansions and the backlash processing that the shell applies to double-quoted strings.

                                                    – mklement0
                                                    Jul 7 '16 at 14:40
















                                                  7












                                                  7








                                                  7







                                                  If your system is Posix.2 compliant it should supply the printf utility:



                                                  $ printf "print 'zap'nfor r in range(3): print 'rob'" | python
                                                  zap
                                                  rob
                                                  rob
                                                  rob





                                                  share|improve this answer













                                                  If your system is Posix.2 compliant it should supply the printf utility:



                                                  $ printf "print 'zap'nfor r in range(3): print 'rob'" | python
                                                  zap
                                                  rob
                                                  rob
                                                  rob






                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered Jan 12 '10 at 1:33









                                                  Alex MartelliAlex Martelli

                                                  628k12810401280




                                                  628k12810401280








                                                  • 2





                                                    Good solution, but I suggest using printf %b '...' | python for added robustness, because it prevents printf from interpreting sequences such as %d (format specifiers) in the input string. Also, unless you explicitly want to apply shell expansions to your Python command string up front (which can get confusing), it's better to use ' (single quotes) for the outer quoting, to avoid both the expansions and the backlash processing that the shell applies to double-quoted strings.

                                                    – mklement0
                                                    Jul 7 '16 at 14:40
















                                                  • 2





                                                    Good solution, but I suggest using printf %b '...' | python for added robustness, because it prevents printf from interpreting sequences such as %d (format specifiers) in the input string. Also, unless you explicitly want to apply shell expansions to your Python command string up front (which can get confusing), it's better to use ' (single quotes) for the outer quoting, to avoid both the expansions and the backlash processing that the shell applies to double-quoted strings.

                                                    – mklement0
                                                    Jul 7 '16 at 14:40










                                                  2




                                                  2





                                                  Good solution, but I suggest using printf %b '...' | python for added robustness, because it prevents printf from interpreting sequences such as %d (format specifiers) in the input string. Also, unless you explicitly want to apply shell expansions to your Python command string up front (which can get confusing), it's better to use ' (single quotes) for the outer quoting, to avoid both the expansions and the backlash processing that the shell applies to double-quoted strings.

                                                  – mklement0
                                                  Jul 7 '16 at 14:40







                                                  Good solution, but I suggest using printf %b '...' | python for added robustness, because it prevents printf from interpreting sequences such as %d (format specifiers) in the input string. Also, unless you explicitly want to apply shell expansions to your Python command string up front (which can get confusing), it's better to use ' (single quotes) for the outer quoting, to avoid both the expansions and the backlash processing that the shell applies to double-quoted strings.

                                                  – mklement0
                                                  Jul 7 '16 at 14:40













                                                  7














                                                  $ python2.6 -c "import sys; [sys.stdout.write('robn') for r in range(10)]"



                                                  Works fine.
                                                  Use "[ ]" to inline your for loop.






                                                  share|improve this answer




























                                                    7














                                                    $ python2.6 -c "import sys; [sys.stdout.write('robn') for r in range(10)]"



                                                    Works fine.
                                                    Use "[ ]" to inline your for loop.






                                                    share|improve this answer


























                                                      7












                                                      7








                                                      7







                                                      $ python2.6 -c "import sys; [sys.stdout.write('robn') for r in range(10)]"



                                                      Works fine.
                                                      Use "[ ]" to inline your for loop.






                                                      share|improve this answer













                                                      $ python2.6 -c "import sys; [sys.stdout.write('robn') for r in range(10)]"



                                                      Works fine.
                                                      Use "[ ]" to inline your for loop.







                                                      share|improve this answer












                                                      share|improve this answer



                                                      share|improve this answer










                                                      answered Jan 11 '12 at 13:40









                                                      Pierre PericardPierre Pericard

                                                      7914




                                                      7914























                                                          4














                                                          (answered Nov 23 '10 at 19:48)
                                                          I'm not really a big Pythoner - but I found this syntax once, forgot where from, so I thought I'd document it:



                                                          if you use sys.stdout.write instead of print (the difference being, sys.stdout.write takes arguments as a function, in parenthesis - whereas print doesn't), then for a one-liner, you can get away with inverting the order of the command and the for, removing the semicolon, and enclosing the command in square brackets, i.e.:



                                                          python -c "import sys; [sys.stdout.write('robn') for r in range(10)]"


                                                          Have no idea how this syntax would be called in Python :)



                                                          Hope this helps,



                                                          Cheers!





                                                          (EDIT Tue Apr 9 20:57:30 2013) Well, I think I finally found what these square brackets in one-liners are about; they are "list comprehensions" (apparently); first note this in Python 2.7:



                                                          $ STR=abc
                                                          $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
                                                          <generator object <genexpr> at 0xb771461c>


                                                          So the command in round brackets/parenthesis is seen as a "generator object"; if we "iterate" through it by calling next() - then the command inside the parenthesis will be executed (note the "abc" in the output):



                                                          $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
                                                          abc
                                                          <generator object <genexpr> at 0xb777b734>


                                                          If we now use square brackets - note that we don't need to call next() to have the command execute, it executes immediately upon assignment; however, later inspection reveals that a is None:



                                                          $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
                                                          abc
                                                          [None]


                                                          This doesn't leave much info to look for, for the square brackets case - but I stumbled upon this page which I think explains:



                                                          Python Tips And Tricks – First Edition - Python Tutorials | Dream.In.Code:




                                                          If you recall, the standard format of a single line generator is a kind of one line 'for' loop inside brackets. This will produce a 'one-shot' iterable object which is an object you can iterate over in only one direction and which you can't re-use once you reach the end.



                                                          A 'list comprehension' looks almost the same as a regular one-line generator, except that the regular brackets - ( ) - are replaced by square brackets - [ ]. The major advanatge of alist comprehension is that produces a 'list', rather than a 'one-shot' iterable object, so that you can go back and forth through it, add elements, sort, etc.




                                                          And indeed it is a list - it's just its first element becomes none as soon as it is executed:



                                                          $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
                                                          abc
                                                          <type 'list'>
                                                          $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
                                                          abc
                                                          None


                                                          List comprehensions are otherwise documented in 5. Data Structures: 5.1.4. List Comprehensions — Python v2.7.4 documentation as "List comprehensions provide a concise way to create lists"; presumably, that's where the limited "executability" of lists comes into play in one-liners.



                                                          Well, hope I'm not terribly too off the mark here ...



                                                          EDIT2: and here is a one-liner command line with two non-nested for-loops; both enclosed within "list comprehension" square brackets:



                                                          $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
                                                          abc
                                                          01[None]
                                                          [None, None]


                                                          Notice that the second "list" b now has two elements, since its for loop explicitly ran twice; however, the result of sys.stdout.write() in both cases was (apparently) None.






                                                          share|improve this answer


























                                                          • This solution works on Windows as well!

                                                            – Nick
                                                            Jul 7 '15 at 16:36
















                                                          4














                                                          (answered Nov 23 '10 at 19:48)
                                                          I'm not really a big Pythoner - but I found this syntax once, forgot where from, so I thought I'd document it:



                                                          if you use sys.stdout.write instead of print (the difference being, sys.stdout.write takes arguments as a function, in parenthesis - whereas print doesn't), then for a one-liner, you can get away with inverting the order of the command and the for, removing the semicolon, and enclosing the command in square brackets, i.e.:



                                                          python -c "import sys; [sys.stdout.write('robn') for r in range(10)]"


                                                          Have no idea how this syntax would be called in Python :)



                                                          Hope this helps,



                                                          Cheers!





                                                          (EDIT Tue Apr 9 20:57:30 2013) Well, I think I finally found what these square brackets in one-liners are about; they are "list comprehensions" (apparently); first note this in Python 2.7:



                                                          $ STR=abc
                                                          $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
                                                          <generator object <genexpr> at 0xb771461c>


                                                          So the command in round brackets/parenthesis is seen as a "generator object"; if we "iterate" through it by calling next() - then the command inside the parenthesis will be executed (note the "abc" in the output):



                                                          $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
                                                          abc
                                                          <generator object <genexpr> at 0xb777b734>


                                                          If we now use square brackets - note that we don't need to call next() to have the command execute, it executes immediately upon assignment; however, later inspection reveals that a is None:



                                                          $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
                                                          abc
                                                          [None]


                                                          This doesn't leave much info to look for, for the square brackets case - but I stumbled upon this page which I think explains:



                                                          Python Tips And Tricks – First Edition - Python Tutorials | Dream.In.Code:




                                                          If you recall, the standard format of a single line generator is a kind of one line 'for' loop inside brackets. This will produce a 'one-shot' iterable object which is an object you can iterate over in only one direction and which you can't re-use once you reach the end.



                                                          A 'list comprehension' looks almost the same as a regular one-line generator, except that the regular brackets - ( ) - are replaced by square brackets - [ ]. The major advanatge of alist comprehension is that produces a 'list', rather than a 'one-shot' iterable object, so that you can go back and forth through it, add elements, sort, etc.




                                                          And indeed it is a list - it's just its first element becomes none as soon as it is executed:



                                                          $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
                                                          abc
                                                          <type 'list'>
                                                          $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
                                                          abc
                                                          None


                                                          List comprehensions are otherwise documented in 5. Data Structures: 5.1.4. List Comprehensions — Python v2.7.4 documentation as "List comprehensions provide a concise way to create lists"; presumably, that's where the limited "executability" of lists comes into play in one-liners.



                                                          Well, hope I'm not terribly too off the mark here ...



                                                          EDIT2: and here is a one-liner command line with two non-nested for-loops; both enclosed within "list comprehension" square brackets:



                                                          $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
                                                          abc
                                                          01[None]
                                                          [None, None]


                                                          Notice that the second "list" b now has two elements, since its for loop explicitly ran twice; however, the result of sys.stdout.write() in both cases was (apparently) None.






                                                          share|improve this answer


























                                                          • This solution works on Windows as well!

                                                            – Nick
                                                            Jul 7 '15 at 16:36














                                                          4












                                                          4








                                                          4







                                                          (answered Nov 23 '10 at 19:48)
                                                          I'm not really a big Pythoner - but I found this syntax once, forgot where from, so I thought I'd document it:



                                                          if you use sys.stdout.write instead of print (the difference being, sys.stdout.write takes arguments as a function, in parenthesis - whereas print doesn't), then for a one-liner, you can get away with inverting the order of the command and the for, removing the semicolon, and enclosing the command in square brackets, i.e.:



                                                          python -c "import sys; [sys.stdout.write('robn') for r in range(10)]"


                                                          Have no idea how this syntax would be called in Python :)



                                                          Hope this helps,



                                                          Cheers!





                                                          (EDIT Tue Apr 9 20:57:30 2013) Well, I think I finally found what these square brackets in one-liners are about; they are "list comprehensions" (apparently); first note this in Python 2.7:



                                                          $ STR=abc
                                                          $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
                                                          <generator object <genexpr> at 0xb771461c>


                                                          So the command in round brackets/parenthesis is seen as a "generator object"; if we "iterate" through it by calling next() - then the command inside the parenthesis will be executed (note the "abc" in the output):



                                                          $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
                                                          abc
                                                          <generator object <genexpr> at 0xb777b734>


                                                          If we now use square brackets - note that we don't need to call next() to have the command execute, it executes immediately upon assignment; however, later inspection reveals that a is None:



                                                          $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
                                                          abc
                                                          [None]


                                                          This doesn't leave much info to look for, for the square brackets case - but I stumbled upon this page which I think explains:



                                                          Python Tips And Tricks – First Edition - Python Tutorials | Dream.In.Code:




                                                          If you recall, the standard format of a single line generator is a kind of one line 'for' loop inside brackets. This will produce a 'one-shot' iterable object which is an object you can iterate over in only one direction and which you can't re-use once you reach the end.



                                                          A 'list comprehension' looks almost the same as a regular one-line generator, except that the regular brackets - ( ) - are replaced by square brackets - [ ]. The major advanatge of alist comprehension is that produces a 'list', rather than a 'one-shot' iterable object, so that you can go back and forth through it, add elements, sort, etc.




                                                          And indeed it is a list - it's just its first element becomes none as soon as it is executed:



                                                          $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
                                                          abc
                                                          <type 'list'>
                                                          $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
                                                          abc
                                                          None


                                                          List comprehensions are otherwise documented in 5. Data Structures: 5.1.4. List Comprehensions — Python v2.7.4 documentation as "List comprehensions provide a concise way to create lists"; presumably, that's where the limited "executability" of lists comes into play in one-liners.



                                                          Well, hope I'm not terribly too off the mark here ...



                                                          EDIT2: and here is a one-liner command line with two non-nested for-loops; both enclosed within "list comprehension" square brackets:



                                                          $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
                                                          abc
                                                          01[None]
                                                          [None, None]


                                                          Notice that the second "list" b now has two elements, since its for loop explicitly ran twice; however, the result of sys.stdout.write() in both cases was (apparently) None.






                                                          share|improve this answer















                                                          (answered Nov 23 '10 at 19:48)
                                                          I'm not really a big Pythoner - but I found this syntax once, forgot where from, so I thought I'd document it:



                                                          if you use sys.stdout.write instead of print (the difference being, sys.stdout.write takes arguments as a function, in parenthesis - whereas print doesn't), then for a one-liner, you can get away with inverting the order of the command and the for, removing the semicolon, and enclosing the command in square brackets, i.e.:



                                                          python -c "import sys; [sys.stdout.write('robn') for r in range(10)]"


                                                          Have no idea how this syntax would be called in Python :)



                                                          Hope this helps,



                                                          Cheers!





                                                          (EDIT Tue Apr 9 20:57:30 2013) Well, I think I finally found what these square brackets in one-liners are about; they are "list comprehensions" (apparently); first note this in Python 2.7:



                                                          $ STR=abc
                                                          $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
                                                          <generator object <genexpr> at 0xb771461c>


                                                          So the command in round brackets/parenthesis is seen as a "generator object"; if we "iterate" through it by calling next() - then the command inside the parenthesis will be executed (note the "abc" in the output):



                                                          $ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
                                                          abc
                                                          <generator object <genexpr> at 0xb777b734>


                                                          If we now use square brackets - note that we don't need to call next() to have the command execute, it executes immediately upon assignment; however, later inspection reveals that a is None:



                                                          $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
                                                          abc
                                                          [None]


                                                          This doesn't leave much info to look for, for the square brackets case - but I stumbled upon this page which I think explains:



                                                          Python Tips And Tricks – First Edition - Python Tutorials | Dream.In.Code:




                                                          If you recall, the standard format of a single line generator is a kind of one line 'for' loop inside brackets. This will produce a 'one-shot' iterable object which is an object you can iterate over in only one direction and which you can't re-use once you reach the end.



                                                          A 'list comprehension' looks almost the same as a regular one-line generator, except that the regular brackets - ( ) - are replaced by square brackets - [ ]. The major advanatge of alist comprehension is that produces a 'list', rather than a 'one-shot' iterable object, so that you can go back and forth through it, add elements, sort, etc.




                                                          And indeed it is a list - it's just its first element becomes none as soon as it is executed:



                                                          $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
                                                          abc
                                                          <type 'list'>
                                                          $ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
                                                          abc
                                                          None


                                                          List comprehensions are otherwise documented in 5. Data Structures: 5.1.4. List Comprehensions — Python v2.7.4 documentation as "List comprehensions provide a concise way to create lists"; presumably, that's where the limited "executability" of lists comes into play in one-liners.



                                                          Well, hope I'm not terribly too off the mark here ...



                                                          EDIT2: and here is a one-liner command line with two non-nested for-loops; both enclosed within "list comprehension" square brackets:



                                                          $ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
                                                          abc
                                                          01[None]
                                                          [None, None]


                                                          Notice that the second "list" b now has two elements, since its for loop explicitly ran twice; however, the result of sys.stdout.write() in both cases was (apparently) None.







                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited Apr 9 '13 at 19:32

























                                                          answered Nov 23 '10 at 19:48









                                                          sdaausdaau

                                                          20k28151205




                                                          20k28151205













                                                          • This solution works on Windows as well!

                                                            – Nick
                                                            Jul 7 '15 at 16:36



















                                                          • This solution works on Windows as well!

                                                            – Nick
                                                            Jul 7 '15 at 16:36

















                                                          This solution works on Windows as well!

                                                          – Nick
                                                          Jul 7 '15 at 16:36





                                                          This solution works on Windows as well!

                                                          – Nick
                                                          Jul 7 '15 at 16:36











                                                          3














                                                          This variant is most portable for putting multi-line scripts on command-line on Windows and *nix, py2/3, without pipes:



                                                          python -c "exec("import sys nfor r in range(10): print('rob') ")"


                                                          (None of the other examples seen here so far did so)



                                                          Neat on Windows is:



                                                          python -c exec"""import sys nfor r in range(10): print 'rob' """
                                                          python -c exec("""import sys nfor r in range(10): print('rob') """)


                                                          Neat on bash/*nix is:



                                                          python -c $'import sys nfor r in range(10): print("rob")'




                                                          This function turns any multiline-script into a portable command-one-liner:



                                                          def py2cmdline(script):
                                                          exs = 'exec(%r)' % re.sub('rn|r', 'n', script.rstrip())
                                                          print('python -c "%s"' % exs.replace('"', r'"'))


                                                          Usage:



                                                          >>> py2cmdline(getcliptext())
                                                          python -c "exec('print 'AAtA'ntry:n for i in 1, 2, 3:n print i / 0nexcept:n print """longernmessage"""')"


                                                          Input was:



                                                          print 'AA   A'
                                                          try:
                                                          for i in 1, 2, 3:
                                                          print i / 0
                                                          except:
                                                          print """longer
                                                          message"""





                                                          share|improve this answer


























                                                          • ++ for the cross-platform angle and the converter. Your first command is as good as it gets in terms of portability (leaving PowerShell aside), but ultimately there is no single, fully robust cross-platform syntax, because the need to use double quotes then bears the risk of unwanted shell expansions, with Windows requiring escaping of different characters than POSIX-like shells. In PowerShell v3 or higher you can make your command lines work by inserting the "stop-parsing" option --% before the command-string argument.

                                                            – mklement0
                                                            Jul 7 '16 at 18:45











                                                          • @mklement0 "unwanted shell expansions": well, the insertion of shell expansions into something like print "path is %%PATH%%" resp. print "path is $PATH" is usually the option which one wants in a script or command-line - unless one escapes things as usual for the platform. Same with other languages. (The Python syntax itself does not regularly suggest the use of % and $'s in a competing way.)

                                                            – kxr
                                                            Aug 5 '16 at 7:07











                                                          • If you insert shell-variable references directly into the Python source code, it will by definition not be portable. My point is that even if you instead constructed platform-specific references in separate variables that you pass as arguments to a single, "shell-free" Python command, that may not always work, because you cannot protect the double-quoted string portably: e.g., what if you need literal $foo in your Python code? If you escape it as $foo for the benefit of POSIX-like shells, cmd.exe will still see the extra . It may be rare but it's worth knowing about.

                                                            – mklement0
                                                            Aug 6 '16 at 14:53











                                                          • Trying to do this in Windows PowerShell, but the problem is that python -c exec("""...""") doesn't produce any output whatsoever, no matter if the code in ... is able to be executed or not; I could put any gibberish there, and the result would be the same. I feel like the shell is "eating" both the stdout and stderr streams - how can I make it spit them out?

                                                            – Yury
                                                            Feb 1 at 6:26


















                                                          3














                                                          This variant is most portable for putting multi-line scripts on command-line on Windows and *nix, py2/3, without pipes:



                                                          python -c "exec("import sys nfor r in range(10): print('rob') ")"


                                                          (None of the other examples seen here so far did so)



                                                          Neat on Windows is:



                                                          python -c exec"""import sys nfor r in range(10): print 'rob' """
                                                          python -c exec("""import sys nfor r in range(10): print('rob') """)


                                                          Neat on bash/*nix is:



                                                          python -c $'import sys nfor r in range(10): print("rob")'




                                                          This function turns any multiline-script into a portable command-one-liner:



                                                          def py2cmdline(script):
                                                          exs = 'exec(%r)' % re.sub('rn|r', 'n', script.rstrip())
                                                          print('python -c "%s"' % exs.replace('"', r'"'))


                                                          Usage:



                                                          >>> py2cmdline(getcliptext())
                                                          python -c "exec('print 'AAtA'ntry:n for i in 1, 2, 3:n print i / 0nexcept:n print """longernmessage"""')"


                                                          Input was:



                                                          print 'AA   A'
                                                          try:
                                                          for i in 1, 2, 3:
                                                          print i / 0
                                                          except:
                                                          print """longer
                                                          message"""





                                                          share|improve this answer


























                                                          • ++ for the cross-platform angle and the converter. Your first command is as good as it gets in terms of portability (leaving PowerShell aside), but ultimately there is no single, fully robust cross-platform syntax, because the need to use double quotes then bears the risk of unwanted shell expansions, with Windows requiring escaping of different characters than POSIX-like shells. In PowerShell v3 or higher you can make your command lines work by inserting the "stop-parsing" option --% before the command-string argument.

                                                            – mklement0
                                                            Jul 7 '16 at 18:45











                                                          • @mklement0 "unwanted shell expansions": well, the insertion of shell expansions into something like print "path is %%PATH%%" resp. print "path is $PATH" is usually the option which one wants in a script or command-line - unless one escapes things as usual for the platform. Same with other languages. (The Python syntax itself does not regularly suggest the use of % and $'s in a competing way.)

                                                            – kxr
                                                            Aug 5 '16 at 7:07











                                                          • If you insert shell-variable references directly into the Python source code, it will by definition not be portable. My point is that even if you instead constructed platform-specific references in separate variables that you pass as arguments to a single, "shell-free" Python command, that may not always work, because you cannot protect the double-quoted string portably: e.g., what if you need literal $foo in your Python code? If you escape it as $foo for the benefit of POSIX-like shells, cmd.exe will still see the extra . It may be rare but it's worth knowing about.

                                                            – mklement0
                                                            Aug 6 '16 at 14:53











                                                          • Trying to do this in Windows PowerShell, but the problem is that python -c exec("""...""") doesn't produce any output whatsoever, no matter if the code in ... is able to be executed or not; I could put any gibberish there, and the result would be the same. I feel like the shell is "eating" both the stdout and stderr streams - how can I make it spit them out?

                                                            – Yury
                                                            Feb 1 at 6:26
















                                                          3












                                                          3








                                                          3







                                                          This variant is most portable for putting multi-line scripts on command-line on Windows and *nix, py2/3, without pipes:



                                                          python -c "exec("import sys nfor r in range(10): print('rob') ")"


                                                          (None of the other examples seen here so far did so)



                                                          Neat on Windows is:



                                                          python -c exec"""import sys nfor r in range(10): print 'rob' """
                                                          python -c exec("""import sys nfor r in range(10): print('rob') """)


                                                          Neat on bash/*nix is:



                                                          python -c $'import sys nfor r in range(10): print("rob")'




                                                          This function turns any multiline-script into a portable command-one-liner:



                                                          def py2cmdline(script):
                                                          exs = 'exec(%r)' % re.sub('rn|r', 'n', script.rstrip())
                                                          print('python -c "%s"' % exs.replace('"', r'"'))


                                                          Usage:



                                                          >>> py2cmdline(getcliptext())
                                                          python -c "exec('print 'AAtA'ntry:n for i in 1, 2, 3:n print i / 0nexcept:n print """longernmessage"""')"


                                                          Input was:



                                                          print 'AA   A'
                                                          try:
                                                          for i in 1, 2, 3:
                                                          print i / 0
                                                          except:
                                                          print """longer
                                                          message"""





                                                          share|improve this answer















                                                          This variant is most portable for putting multi-line scripts on command-line on Windows and *nix, py2/3, without pipes:



                                                          python -c "exec("import sys nfor r in range(10): print('rob') ")"


                                                          (None of the other examples seen here so far did so)



                                                          Neat on Windows is:



                                                          python -c exec"""import sys nfor r in range(10): print 'rob' """
                                                          python -c exec("""import sys nfor r in range(10): print('rob') """)


                                                          Neat on bash/*nix is:



                                                          python -c $'import sys nfor r in range(10): print("rob")'




                                                          This function turns any multiline-script into a portable command-one-liner:



                                                          def py2cmdline(script):
                                                          exs = 'exec(%r)' % re.sub('rn|r', 'n', script.rstrip())
                                                          print('python -c "%s"' % exs.replace('"', r'"'))


                                                          Usage:



                                                          >>> py2cmdline(getcliptext())
                                                          python -c "exec('print 'AAtA'ntry:n for i in 1, 2, 3:n print i / 0nexcept:n print """longernmessage"""')"


                                                          Input was:



                                                          print 'AA   A'
                                                          try:
                                                          for i in 1, 2, 3:
                                                          print i / 0
                                                          except:
                                                          print """longer
                                                          message"""






                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited Feb 26 '16 at 15:11

























                                                          answered Feb 26 '16 at 12:32









                                                          kxrkxr

                                                          1,8291715




                                                          1,8291715













                                                          • ++ for the cross-platform angle and the converter. Your first command is as good as it gets in terms of portability (leaving PowerShell aside), but ultimately there is no single, fully robust cross-platform syntax, because the need to use double quotes then bears the risk of unwanted shell expansions, with Windows requiring escaping of different characters than POSIX-like shells. In PowerShell v3 or higher you can make your command lines work by inserting the "stop-parsing" option --% before the command-string argument.

                                                            – mklement0
                                                            Jul 7 '16 at 18:45











                                                          • @mklement0 "unwanted shell expansions": well, the insertion of shell expansions into something like print "path is %%PATH%%" resp. print "path is $PATH" is usually the option which one wants in a script or command-line - unless one escapes things as usual for the platform. Same with other languages. (The Python syntax itself does not regularly suggest the use of % and $'s in a competing way.)

                                                            – kxr
                                                            Aug 5 '16 at 7:07











                                                          • If you insert shell-variable references directly into the Python source code, it will by definition not be portable. My point is that even if you instead constructed platform-specific references in separate variables that you pass as arguments to a single, "shell-free" Python command, that may not always work, because you cannot protect the double-quoted string portably: e.g., what if you need literal $foo in your Python code? If you escape it as $foo for the benefit of POSIX-like shells, cmd.exe will still see the extra . It may be rare but it's worth knowing about.

                                                            – mklement0
                                                            Aug 6 '16 at 14:53











                                                          • Trying to do this in Windows PowerShell, but the problem is that python -c exec("""...""") doesn't produce any output whatsoever, no matter if the code in ... is able to be executed or not; I could put any gibberish there, and the result would be the same. I feel like the shell is "eating" both the stdout and stderr streams - how can I make it spit them out?

                                                            – Yury
                                                            Feb 1 at 6:26





















                                                          • ++ for the cross-platform angle and the converter. Your first command is as good as it gets in terms of portability (leaving PowerShell aside), but ultimately there is no single, fully robust cross-platform syntax, because the need to use double quotes then bears the risk of unwanted shell expansions, with Windows requiring escaping of different characters than POSIX-like shells. In PowerShell v3 or higher you can make your command lines work by inserting the "stop-parsing" option --% before the command-string argument.

                                                            – mklement0
                                                            Jul 7 '16 at 18:45











                                                          • @mklement0 "unwanted shell expansions": well, the insertion of shell expansions into something like print "path is %%PATH%%" resp. print "path is $PATH" is usually the option which one wants in a script or command-line - unless one escapes things as usual for the platform. Same with other languages. (The Python syntax itself does not regularly suggest the use of % and $'s in a competing way.)

                                                            – kxr
                                                            Aug 5 '16 at 7:07











                                                          • If you insert shell-variable references directly into the Python source code, it will by definition not be portable. My point is that even if you instead constructed platform-specific references in separate variables that you pass as arguments to a single, "shell-free" Python command, that may not always work, because you cannot protect the double-quoted string portably: e.g., what if you need literal $foo in your Python code? If you escape it as $foo for the benefit of POSIX-like shells, cmd.exe will still see the extra . It may be rare but it's worth knowing about.

                                                            – mklement0
                                                            Aug 6 '16 at 14:53











                                                          • Trying to do this in Windows PowerShell, but the problem is that python -c exec("""...""") doesn't produce any output whatsoever, no matter if the code in ... is able to be executed or not; I could put any gibberish there, and the result would be the same. I feel like the shell is "eating" both the stdout and stderr streams - how can I make it spit them out?

                                                            – Yury
                                                            Feb 1 at 6:26



















                                                          ++ for the cross-platform angle and the converter. Your first command is as good as it gets in terms of portability (leaving PowerShell aside), but ultimately there is no single, fully robust cross-platform syntax, because the need to use double quotes then bears the risk of unwanted shell expansions, with Windows requiring escaping of different characters than POSIX-like shells. In PowerShell v3 or higher you can make your command lines work by inserting the "stop-parsing" option --% before the command-string argument.

                                                          – mklement0
                                                          Jul 7 '16 at 18:45





                                                          ++ for the cross-platform angle and the converter. Your first command is as good as it gets in terms of portability (leaving PowerShell aside), but ultimately there is no single, fully robust cross-platform syntax, because the need to use double quotes then bears the risk of unwanted shell expansions, with Windows requiring escaping of different characters than POSIX-like shells. In PowerShell v3 or higher you can make your command lines work by inserting the "stop-parsing" option --% before the command-string argument.

                                                          – mklement0
                                                          Jul 7 '16 at 18:45













                                                          @mklement0 "unwanted shell expansions": well, the insertion of shell expansions into something like print "path is %%PATH%%" resp. print "path is $PATH" is usually the option which one wants in a script or command-line - unless one escapes things as usual for the platform. Same with other languages. (The Python syntax itself does not regularly suggest the use of % and $'s in a competing way.)

                                                          – kxr
                                                          Aug 5 '16 at 7:07





                                                          @mklement0 "unwanted shell expansions": well, the insertion of shell expansions into something like print "path is %%PATH%%" resp. print "path is $PATH" is usually the option which one wants in a script or command-line - unless one escapes things as usual for the platform. Same with other languages. (The Python syntax itself does not regularly suggest the use of % and $'s in a competing way.)

                                                          – kxr
                                                          Aug 5 '16 at 7:07













                                                          If you insert shell-variable references directly into the Python source code, it will by definition not be portable. My point is that even if you instead constructed platform-specific references in separate variables that you pass as arguments to a single, "shell-free" Python command, that may not always work, because you cannot protect the double-quoted string portably: e.g., what if you need literal $foo in your Python code? If you escape it as $foo for the benefit of POSIX-like shells, cmd.exe will still see the extra . It may be rare but it's worth knowing about.

                                                          – mklement0
                                                          Aug 6 '16 at 14:53





                                                          If you insert shell-variable references directly into the Python source code, it will by definition not be portable. My point is that even if you instead constructed platform-specific references in separate variables that you pass as arguments to a single, "shell-free" Python command, that may not always work, because you cannot protect the double-quoted string portably: e.g., what if you need literal $foo in your Python code? If you escape it as $foo for the benefit of POSIX-like shells, cmd.exe will still see the extra . It may be rare but it's worth knowing about.

                                                          – mklement0
                                                          Aug 6 '16 at 14:53













                                                          Trying to do this in Windows PowerShell, but the problem is that python -c exec("""...""") doesn't produce any output whatsoever, no matter if the code in ... is able to be executed or not; I could put any gibberish there, and the result would be the same. I feel like the shell is "eating" both the stdout and stderr streams - how can I make it spit them out?

                                                          – Yury
                                                          Feb 1 at 6:26







                                                          Trying to do this in Windows PowerShell, but the problem is that python -c exec("""...""") doesn't produce any output whatsoever, no matter if the code in ... is able to be executed or not; I could put any gibberish there, and the result would be the same. I feel like the shell is "eating" both the stdout and stderr streams - how can I make it spit them out?

                                                          – Yury
                                                          Feb 1 at 6:26













                                                          2














                                                          single/double quotes and backslash everywhere:



                                                          $ python -c 'exec("import sysnfor i in range(10): print "bob"")'


                                                          Much better:



                                                          $ python -c '
                                                          > import sys
                                                          > for i in range(10):
                                                          > print "bob"
                                                          > '





                                                          share|improve this answer




























                                                            2














                                                            single/double quotes and backslash everywhere:



                                                            $ python -c 'exec("import sysnfor i in range(10): print "bob"")'


                                                            Much better:



                                                            $ python -c '
                                                            > import sys
                                                            > for i in range(10):
                                                            > print "bob"
                                                            > '





                                                            share|improve this answer


























                                                              2












                                                              2








                                                              2







                                                              single/double quotes and backslash everywhere:



                                                              $ python -c 'exec("import sysnfor i in range(10): print "bob"")'


                                                              Much better:



                                                              $ python -c '
                                                              > import sys
                                                              > for i in range(10):
                                                              > print "bob"
                                                              > '





                                                              share|improve this answer













                                                              single/double quotes and backslash everywhere:



                                                              $ python -c 'exec("import sysnfor i in range(10): print "bob"")'


                                                              Much better:



                                                              $ python -c '
                                                              > import sys
                                                              > for i in range(10):
                                                              > print "bob"
                                                              > '






                                                              share|improve this answer












                                                              share|improve this answer



                                                              share|improve this answer










                                                              answered Dec 11 '11 at 8:17









                                                              kevkev

                                                              105k27212236




                                                              105k27212236























                                                                  2














                                                                  This script provides a Perl-like command line interface:



                                                                  Pyliner - Script to run arbitrary Python code on the command line (Python recipe)






                                                                  share|improve this answer


























                                                                  • I think they wanted something to fix that, not to use another tool. Anyway nice hint

                                                                    – enrico.bacis
                                                                    Oct 29 '12 at 11:02











                                                                  • I agree with @enrico.bacis, but I am still happy you added this answer. It answers the question I had when I Googled this page.

                                                                    – tbc0
                                                                    Jul 29 '13 at 18:05
















                                                                  2














                                                                  This script provides a Perl-like command line interface:



                                                                  Pyliner - Script to run arbitrary Python code on the command line (Python recipe)






                                                                  share|improve this answer


























                                                                  • I think they wanted something to fix that, not to use another tool. Anyway nice hint

                                                                    – enrico.bacis
                                                                    Oct 29 '12 at 11:02











                                                                  • I agree with @enrico.bacis, but I am still happy you added this answer. It answers the question I had when I Googled this page.

                                                                    – tbc0
                                                                    Jul 29 '13 at 18:05














                                                                  2












                                                                  2








                                                                  2







                                                                  This script provides a Perl-like command line interface:



                                                                  Pyliner - Script to run arbitrary Python code on the command line (Python recipe)






                                                                  share|improve this answer















                                                                  This script provides a Perl-like command line interface:



                                                                  Pyliner - Script to run arbitrary Python code on the command line (Python recipe)







                                                                  share|improve this answer














                                                                  share|improve this answer



                                                                  share|improve this answer








                                                                  edited Oct 29 '12 at 11:05









                                                                  The Unfun Cat

                                                                  10.8k166692




                                                                  10.8k166692










                                                                  answered Feb 16 '12 at 18:37









                                                                  Drew GulinoDrew Gulino

                                                                  291




                                                                  291













                                                                  • I think they wanted something to fix that, not to use another tool. Anyway nice hint

                                                                    – enrico.bacis
                                                                    Oct 29 '12 at 11:02











                                                                  • I agree with @enrico.bacis, but I am still happy you added this answer. It answers the question I had when I Googled this page.

                                                                    – tbc0
                                                                    Jul 29 '13 at 18:05



















                                                                  • I think they wanted something to fix that, not to use another tool. Anyway nice hint

                                                                    – enrico.bacis
                                                                    Oct 29 '12 at 11:02











                                                                  • I agree with @enrico.bacis, but I am still happy you added this answer. It answers the question I had when I Googled this page.

                                                                    – tbc0
                                                                    Jul 29 '13 at 18:05

















                                                                  I think they wanted something to fix that, not to use another tool. Anyway nice hint

                                                                  – enrico.bacis
                                                                  Oct 29 '12 at 11:02





                                                                  I think they wanted something to fix that, not to use another tool. Anyway nice hint

                                                                  – enrico.bacis
                                                                  Oct 29 '12 at 11:02













                                                                  I agree with @enrico.bacis, but I am still happy you added this answer. It answers the question I had when I Googled this page.

                                                                  – tbc0
                                                                  Jul 29 '13 at 18:05





                                                                  I agree with @enrico.bacis, but I am still happy you added this answer. It answers the question I had when I Googled this page.

                                                                  – tbc0
                                                                  Jul 29 '13 at 18:05











                                                                  1














                                                                  I wanted a solution with the following properties:




                                                                  1. Readable

                                                                  2. Read stdin for processing output of other tools


                                                                  Both requirements were not provided in the other answers, so here's how to read stdin while doing everything on the command line:



                                                                  grep special_string -r | sort | python3 <(cat <<EOF
                                                                  import sys
                                                                  for line in sys.stdin:
                                                                  tokens = line.split()
                                                                  if len(tokens) == 4:
                                                                  print("%-45s %7.3f %s %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
                                                                  EOF
                                                                  )





                                                                  share|improve this answer






























                                                                    1














                                                                    I wanted a solution with the following properties:




                                                                    1. Readable

                                                                    2. Read stdin for processing output of other tools


                                                                    Both requirements were not provided in the other answers, so here's how to read stdin while doing everything on the command line:



                                                                    grep special_string -r | sort | python3 <(cat <<EOF
                                                                    import sys
                                                                    for line in sys.stdin:
                                                                    tokens = line.split()
                                                                    if len(tokens) == 4:
                                                                    print("%-45s %7.3f %s %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
                                                                    EOF
                                                                    )





                                                                    share|improve this answer




























                                                                      1












                                                                      1








                                                                      1







                                                                      I wanted a solution with the following properties:




                                                                      1. Readable

                                                                      2. Read stdin for processing output of other tools


                                                                      Both requirements were not provided in the other answers, so here's how to read stdin while doing everything on the command line:



                                                                      grep special_string -r | sort | python3 <(cat <<EOF
                                                                      import sys
                                                                      for line in sys.stdin:
                                                                      tokens = line.split()
                                                                      if len(tokens) == 4:
                                                                      print("%-45s %7.3f %s %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
                                                                      EOF
                                                                      )





                                                                      share|improve this answer















                                                                      I wanted a solution with the following properties:




                                                                      1. Readable

                                                                      2. Read stdin for processing output of other tools


                                                                      Both requirements were not provided in the other answers, so here's how to read stdin while doing everything on the command line:



                                                                      grep special_string -r | sort | python3 <(cat <<EOF
                                                                      import sys
                                                                      for line in sys.stdin:
                                                                      tokens = line.split()
                                                                      if len(tokens) == 4:
                                                                      print("%-45s %7.3f %s %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
                                                                      EOF
                                                                      )






                                                                      share|improve this answer














                                                                      share|improve this answer



                                                                      share|improve this answer








                                                                      edited Nov 27 '18 at 19:52

























                                                                      answered Nov 27 '18 at 18:32









                                                                      NickNick

                                                                      1,6032020




                                                                      1,6032020























                                                                          0














                                                                          there is one more option, sys.stdout.write returns None, which keep the list empty





                                                                          cat somefile.log|python -c "import sys;[line for line in sys.stdin if sys.stdout.write(line*2)]"





                                                                          share|improve this answer






























                                                                            0














                                                                            there is one more option, sys.stdout.write returns None, which keep the list empty





                                                                            cat somefile.log|python -c "import sys;[line for line in sys.stdin if sys.stdout.write(line*2)]"





                                                                            share|improve this answer




























                                                                              0












                                                                              0








                                                                              0







                                                                              there is one more option, sys.stdout.write returns None, which keep the list empty





                                                                              cat somefile.log|python -c "import sys;[line for line in sys.stdin if sys.stdout.write(line*2)]"





                                                                              share|improve this answer















                                                                              there is one more option, sys.stdout.write returns None, which keep the list empty





                                                                              cat somefile.log|python -c "import sys;[line for line in sys.stdin if sys.stdout.write(line*2)]"






                                                                              share|improve this answer














                                                                              share|improve this answer



                                                                              share|improve this answer








                                                                              edited Jun 6 '14 at 4:30

























                                                                              answered Jun 6 '14 at 4:22









                                                                              user993533user993533

                                                                              5813




                                                                              5813























                                                                                  0














                                                                                  I've written a simple web page for this. You can paste your multiple-line code there and it is converted into a working single-line statement.



                                                                                  Python Single Line Converter






                                                                                  share|improve this answer






























                                                                                    0














                                                                                    I've written a simple web page for this. You can paste your multiple-line code there and it is converted into a working single-line statement.



                                                                                    Python Single Line Converter






                                                                                    share|improve this answer




























                                                                                      0












                                                                                      0








                                                                                      0







                                                                                      I've written a simple web page for this. You can paste your multiple-line code there and it is converted into a working single-line statement.



                                                                                      Python Single Line Converter






                                                                                      share|improve this answer















                                                                                      I've written a simple web page for this. You can paste your multiple-line code there and it is converted into a working single-line statement.



                                                                                      Python Single Line Converter







                                                                                      share|improve this answer














                                                                                      share|improve this answer



                                                                                      share|improve this answer








                                                                                      edited Apr 10 '15 at 15:58









                                                                                      mklement0

                                                                                      132k21246284




                                                                                      132k21246284










                                                                                      answered Aug 11 '14 at 14:09









                                                                                      jagtttjagttt

                                                                                      6041724




                                                                                      6041724























                                                                                          0














                                                                                          If you don't want to touch stdin and simulate as if you had passed "python cmdfile.py", you can do the following from a bash shell:



                                                                                          $ python  <(printf "word=raw_input('Enter word: ')nimport sysnfor i in range(5):n    print(word)")


                                                                                          As you can see, it allows you to use stdin for reading input data. Internally the shell creates the temporary file for the input command contents.






                                                                                          share|improve this answer


























                                                                                          • ++ for not "using up" stdin with the script itself (though -c "$(...)" does the same, and is POSIX-compliant); to give the <(...) construct a name: process substitution; it also works in ksh and zsh.

                                                                                            – mklement0
                                                                                            Jul 7 '16 at 19:54
















                                                                                          0














                                                                                          If you don't want to touch stdin and simulate as if you had passed "python cmdfile.py", you can do the following from a bash shell:



                                                                                          $ python  <(printf "word=raw_input('Enter word: ')nimport sysnfor i in range(5):n    print(word)")


                                                                                          As you can see, it allows you to use stdin for reading input data. Internally the shell creates the temporary file for the input command contents.






                                                                                          share|improve this answer


























                                                                                          • ++ for not "using up" stdin with the script itself (though -c "$(...)" does the same, and is POSIX-compliant); to give the <(...) construct a name: process substitution; it also works in ksh and zsh.

                                                                                            – mklement0
                                                                                            Jul 7 '16 at 19:54














                                                                                          0












                                                                                          0








                                                                                          0







                                                                                          If you don't want to touch stdin and simulate as if you had passed "python cmdfile.py", you can do the following from a bash shell:



                                                                                          $ python  <(printf "word=raw_input('Enter word: ')nimport sysnfor i in range(5):n    print(word)")


                                                                                          As you can see, it allows you to use stdin for reading input data. Internally the shell creates the temporary file for the input command contents.






                                                                                          share|improve this answer















                                                                                          If you don't want to touch stdin and simulate as if you had passed "python cmdfile.py", you can do the following from a bash shell:



                                                                                          $ python  <(printf "word=raw_input('Enter word: ')nimport sysnfor i in range(5):n    print(word)")


                                                                                          As you can see, it allows you to use stdin for reading input data. Internally the shell creates the temporary file for the input command contents.







                                                                                          share|improve this answer














                                                                                          share|improve this answer



                                                                                          share|improve this answer








                                                                                          edited Jul 7 '16 at 18:24









                                                                                          mklement0

                                                                                          132k21246284




                                                                                          132k21246284










                                                                                          answered Jan 10 '13 at 14:06









                                                                                          ThavaThava

                                                                                          1,1731411




                                                                                          1,1731411













                                                                                          • ++ for not "using up" stdin with the script itself (though -c "$(...)" does the same, and is POSIX-compliant); to give the <(...) construct a name: process substitution; it also works in ksh and zsh.

                                                                                            – mklement0
                                                                                            Jul 7 '16 at 19:54



















                                                                                          • ++ for not "using up" stdin with the script itself (though -c "$(...)" does the same, and is POSIX-compliant); to give the <(...) construct a name: process substitution; it also works in ksh and zsh.

                                                                                            – mklement0
                                                                                            Jul 7 '16 at 19:54

















                                                                                          ++ for not "using up" stdin with the script itself (though -c "$(...)" does the same, and is POSIX-compliant); to give the <(...) construct a name: process substitution; it also works in ksh and zsh.

                                                                                          – mklement0
                                                                                          Jul 7 '16 at 19:54





                                                                                          ++ for not "using up" stdin with the script itself (though -c "$(...)" does the same, and is POSIX-compliant); to give the <(...) construct a name: process substitution; it also works in ksh and zsh.

                                                                                          – mklement0
                                                                                          Jul 7 '16 at 19:54











                                                                                          0














                                                                                          When I needed to do this, I use



                                                                                          python -c "$(echo -e "import sysnsys.stdout.write('Hello World!\n')")"


                                                                                          Note the triple backslash for the newline in the sys.stdout.write statement.






                                                                                          share|improve this answer


























                                                                                          • This works, but since you're using echo -e, which is nonstandard and requires bash, ksh, or zsh, you may as well use a $'...' string directly, which also simplifies the escaping: python -c $'import sysnsys.stdout.write("Hello World!\n")'

                                                                                            – mklement0
                                                                                            Jul 7 '16 at 18:35
















                                                                                          0














                                                                                          When I needed to do this, I use



                                                                                          python -c "$(echo -e "import sysnsys.stdout.write('Hello World!\n')")"


                                                                                          Note the triple backslash for the newline in the sys.stdout.write statement.






                                                                                          share|improve this answer


























                                                                                          • This works, but since you're using echo -e, which is nonstandard and requires bash, ksh, or zsh, you may as well use a $'...' string directly, which also simplifies the escaping: python -c $'import sysnsys.stdout.write("Hello World!\n")'

                                                                                            – mklement0
                                                                                            Jul 7 '16 at 18:35














                                                                                          0












                                                                                          0








                                                                                          0







                                                                                          When I needed to do this, I use



                                                                                          python -c "$(echo -e "import sysnsys.stdout.write('Hello World!\n')")"


                                                                                          Note the triple backslash for the newline in the sys.stdout.write statement.






                                                                                          share|improve this answer















                                                                                          When I needed to do this, I use



                                                                                          python -c "$(echo -e "import sysnsys.stdout.write('Hello World!\n')")"


                                                                                          Note the triple backslash for the newline in the sys.stdout.write statement.







                                                                                          share|improve this answer














                                                                                          share|improve this answer



                                                                                          share|improve this answer








                                                                                          edited Jul 7 '16 at 18:25









                                                                                          mklement0

                                                                                          132k21246284




                                                                                          132k21246284










                                                                                          answered Feb 14 '13 at 11:11









                                                                                          DevilholkDevilholk

                                                                                          11




                                                                                          11













                                                                                          • This works, but since you're using echo -e, which is nonstandard and requires bash, ksh, or zsh, you may as well use a $'...' string directly, which also simplifies the escaping: python -c $'import sysnsys.stdout.write("Hello World!\n")'

                                                                                            – mklement0
                                                                                            Jul 7 '16 at 18:35



















                                                                                          • This works, but since you're using echo -e, which is nonstandard and requires bash, ksh, or zsh, you may as well use a $'...' string directly, which also simplifies the escaping: python -c $'import sysnsys.stdout.write("Hello World!\n")'

                                                                                            – mklement0
                                                                                            Jul 7 '16 at 18:35

















                                                                                          This works, but since you're using echo -e, which is nonstandard and requires bash, ksh, or zsh, you may as well use a $'...' string directly, which also simplifies the escaping: python -c $'import sysnsys.stdout.write("Hello World!\n")'

                                                                                          – mklement0
                                                                                          Jul 7 '16 at 18:35





                                                                                          This works, but since you're using echo -e, which is nonstandard and requires bash, ksh, or zsh, you may as well use a $'...' string directly, which also simplifies the escaping: python -c $'import sysnsys.stdout.write("Hello World!\n")'

                                                                                          – mklement0
                                                                                          Jul 7 '16 at 18:35


















                                                                                          draft saved

                                                                                          draft discarded




















































                                                                                          Thanks for contributing an answer to Stack Overflow!


                                                                                          • Please be sure to answer the question. Provide details and share your research!

                                                                                          But avoid



                                                                                          • Asking for help, clarification, or responding to other answers.

                                                                                          • Making statements based on opinion; back them up with references or personal experience.


                                                                                          To learn more, see our tips on writing great answers.




                                                                                          draft saved


                                                                                          draft discarded














                                                                                          StackExchange.ready(
                                                                                          function () {
                                                                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2043453%2fexecuting-python-multi-line-statements-in-the-one-line-command-line%23new-answer', 'question_page');
                                                                                          }
                                                                                          );

                                                                                          Post as a guest















                                                                                          Required, but never shown





















































                                                                                          Required, but never shown














                                                                                          Required, but never shown












                                                                                          Required, but never shown







                                                                                          Required, but never shown

































                                                                                          Required, but never shown














                                                                                          Required, but never shown












                                                                                          Required, but never shown







                                                                                          Required, but never shown







                                                                                          Popular posts from this blog

                                                                                          Florida Star v. B. J. F.

                                                                                          Error while running script in elastic search , gateway timeout

                                                                                          Adding quotations to stringified JSON object values