Using Python command line
Recently I had a task to write a command file for Windows that run a simple Python commands via python –c command. The manual says that command may contain multiple statements separated by newlines. Unfortunately, Windows console doesn’t allow it (and Ctrl-T trick doesn’t help) so I had to find a workaround. The intuition and language reference helped me to find out that the simple statements can be separated by semicolons like in C/C++ (however, these languages allow to separate all the commands, not
the only simple ones).
Let me give an example. Imagine that accidentally I want to know the error message corresponding to the error code 9. Of course, I can read manuals and documentation, but there is a more simple way:
But this "trick" works only with simple statements. It is not allowed to mix simple and compound statements, so the following command will not work: python -c "import os;for i in range(42):print i,os.strerror(i)". The only way to make it workable – put compound statement on the upper level (identical imports doesn't matter, the real import will be executed only once):
Also I want to notice one more feature of Python command line – executing modules content. Python contains many useful modules and some of them are more useful than
someone can think – they can be executed. For example, SimpleHTTPServer allows you to share your current directory information and files via HTTP protocol:
I’ve gathered information about executable modules and want to share it with you:
Most useful modules will be described in my next article. Enjoy!
the only simple ones).
Let me give an example. Imagine that accidentally I want to know the error message corresponding to the error code 9. Of course, I can read manuals and documentation, but there is a more simple way:
$ python -c "import os;print os.strerror(9)" Bad file descriptor
But this "trick" works only with simple statements. It is not allowed to mix simple and compound statements, so the following command will not work: python -c "import os;for i in range(42):print i,os.strerror(i)". The only way to make it workable – put compound statement on the upper level (identical imports doesn't matter, the real import will be executed only once):
$ python -c "for i in range(43):import os;print i,os.strerror(i)" 0 No error 1 Operation not permitted 2 No such file or directory 3 No such process 4 Interrupted function call 5 Input/output error 6 No such device or address 7 Arg list too long 8 Exec format error 9 Bad file descriptor 10 No child processes 11 Resource temporarily unavailable 12 Not enough space 13 Permission denied 14 Bad address 15 Unknown error 16 Resource device 17 File exists 18 Improper link 19 No such device 20 Not a directory 21 Is a directory 22 Invalid argument 23 Too many open files in system 24 Too many open files 25 Inappropriate I/O control operation 26 Unknown error 27 File too large 28 No space left on device 29 Invalid seek 30 Read-only file system 31 Too many links 32 Broken pipe 33 Domain error 34 Result too large 35 Unknown error 36 Resource deadlock avoided 37 Unknown error 38 Filename too long 39 No locks available 40 Function not implemented 41 Directory not empty 42 Illegal byte sequence
Also I want to notice one more feature of Python command line – executing modules content. Python contains many useful modules and some of them are more useful than
someone can think – they can be executed. For example, SimpleHTTPServer allows you to share your current directory information and files via HTTP protocol:
$ python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 port 8000 ...
I’ve gathered information about executable modules and want to share it with you:
Command | Functionality |
---|---|
python -m site | Print some useful information (sys.path, USER_BASE, USER_SITE) |
python -m StringIO | Read information about the file (default: /etc/passwd) |
python -m calendar | Show the console calendar |
python -m zipfile | Zip/unzip analogue |
python -m platform | Print the platform information |
python -m mailcap | Show and execute MIME types handlers |
python -m binhex | Convert the binary file to hex |
python -m sgmllib | Parse the html file |
python -m htmllib | Show the html file in the text mode |
python -m webbrowser | Start the default web browser for the required URL |
python -m urllib | Print the content of the remote site |
python -m ftplib | Simple FTP client |
python -m poplib | Print information about the remote mailbox |
python -m smtpd | RFC 2821 SMTP proxy |
python -m telnetlib | Simple telnet client |
python -m SimpleHTTPServer | Simple HTTP server |
python -m CGIHTTPServer | CGI-savvy HTTP server |
python -m aifc | Print information about the .aiff file |
python -m sndhdr | Print information about sound files |
python -m locale | Print locale information |
python -m shlex | Split the file to tokens |
python -m pydoc | Python documentation tool |
python -m doctest | Doctest runner |
python -m unittest | Unittest runner |
python -m pdb | Python debugger |
python -m timeit | Tool for measuring execution time of small code snippets |
python -m trace | Trace Python program or function execution |
python -m code | Python interpreter emulator |
python -m tokenize | Split the file to tokens with detailed information |
python -m pyclbr | Describe Python module classes and methods |
python -m compileall | Compile all .py files to .pyc (.pyo) files |
python -m filecmp | Compare two directory |
python -m gzip | Gzip/gunzip analogue |
python -m base64 | RFC 3548: Base16, Base32, Base64 data encoder |
python -m quopri | Convert to/from quoted-printable transport encoding as per RFC 1521 |
python -m cProfile | Profile Python code via 'lsprof' profiler |
python -m profile | Profile Python code |
python -m uu | Implement UUencode and UUdecode functions |
python -m dis | Disassemble of Python byte code into mnemonics |
python -m formatter | Generic output formatter |
Most useful modules will be described in my next article. Enjoy!
Hi!
ReplyDeleteNice and useful post, though I've got the following import error:
viktor@viktor-laptop:~$ python -m pydoc -p 8800
Traceback (most recent call last):
File "/usr/lib/python2.6/runpy.py", line 122, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib/python2.6/runpy.py", line 34, in _run_code
exec code in run_globals
File "/usr/lib/python2.6/pydoc.py", line 2340, in
if __name__ == '__main__': cli()
File "/usr/lib/python2.6/pydoc.py", line 2290, in cli
serve(port, ready, stopped)
File "/usr/lib/python2.6/pydoc.py", line 1979, in serve
import BaseHTTPServer, mimetools, select
ImportError: No module named BaseHTTPServer
However, it doesn't occur when i'm using this code:
viktor@viktor-laptop:~$ python -c "import pydoc; pydoc.cli()" -p 8800
pydoc server ready at http://localhost:8800/
What do you think about it?
(I'm using python2.6 on ubuntu 9.04)
Thanks in advance.
"-m" option terminates the option list, so you can't pass "-p" option for pydoc module (or at least it doesn't work as intended to work):
ReplyDelete$ python -h | grep "^\-m"
-m mod : run library module as a script (terminates option list)
However, there is pydoc script in the /usr/bin directory that exactly resemble the code you mentioned:
$ cat /usr/bin/pydoc
#! /usr/bin/python2.6
import pydoc
if __name__ == '__main__':
pydoc.cli()
So you can just call pydoc script with the all required options and enjoy Python documentation:
$ pydoc -p 8800
pydoc server ready at http://localhost:8800/
So, the "-m" option is not so useful as can be, but you can always emulate its behavior. First, you need to know the module path. You can do it like this:
$ python -c "import pydoc;print pydoc"
<module 'pydoc' from '/usr/lib/python2.6/pydoc.pyc'>
And then just start the required script:
$ python /usr/lib/python2.6/pydoc.pyc -p 8800
pydoc server ready at http://localhost:8800/
Hope it helps, if you have further questions or suggestions let me know. Good luck!