34

I recently started learning python. I have created some basic webapps with Django and wrote some simple scripts. After using VIM as a Python IDE I really fell I love with "Terminal programs" (is there an official term for this?). Right now I am capable of doing simple things like asking someones age and printing it to the screen. However this comes down to running a .py script and after this script is done the normal bash return. I would like create a program that I can run from the command line and that would allow the same user experience as VIM (one that you open and close). For example I created a simple script to import RSS feeds. It would be cool if I could open my terminal type the name of my program -> program would open -> Then I would like to use commands like :findsomething. Basically have real interaction with my program.

To conclude:

  • How would I go about creating such a program?
  • What kinds of modules, books or site would you recommend
1
  • 5
    What you're describing is a terminal application, not a command line program Commented Jun 27, 2013 at 20:49

5 Answers 5

31

On a *nix system (linux/unix),
if you:

$ chmod 0744 your_file.py

-rwxr--r--   your_file.py

and add the path to python as the first line of your_file.py:

#!/usr/bin/python

or (in my case):

#!/usr/local/bin/python

Once you do that, instead of running it like this:

$ python your_file.py

You can run it like this:

$ ./your_file.py

or even rename it to yourfile and run it like this:

$ ./yourfile

and if you then copy yourfile to your bin (i.e. #!/usr/bin/, or #!/usr/local/bin/) you can run it like this:

$ yourfile

Then you can...

Use raw_input() to solicit and get input from you user.

your_file.py:

#!/usr/local/bin/python

import os

while(True):
    # cntrl-c to quit
    input = raw_input('your_prompt$ ')
    input = input.split()
    if input[0] == 'ls':
        dire = '.'
        if len(input) > 1:
            dire = input[1]
        print('\n'.join(os.listdir(dire)))
    else:
        print('error')

your_file.py use example:

$ chmod 744 your_file.py 
$ cp your_file.py /usr/local/bin/your_file 
$ your_file 
your_prompt$ ls
list_argv.py
your_file.py
your_ls.py
your_subprocess.py
your_prompt$ ls .
list_argv.py
your_file.py
your_ls.py
your_subprocess.py
your_prompt$ pwd
error
your_prompt$ ^CTraceback (most recent call last):
  File "/usr/local/bin/your_file", line 7, in <module>
    input = raw_input('your_prompt$ ')
KeyboardInterrupt
$

Grab arguments with sys.argv from the command line when you run your script:

list_argv.py:

#!/usr/local/bin/python

import sys

print(sys.argv)

list_argv.py use example:

$ python list_argv.py 
['list_argv.py']
$ python list_argv.py hello
['list_argv.py', 'hello']
$ python list_argv.py hey yo
['list_argv.py', 'hey', 'yo']

$ chmod 744 list_argv.py 
$ ./list_argv.py 
['./list_argv.py']
$ ./list_argv.py hi
['./list_argv.py', 'hi']
$ ./list_argv.py hey yo
['./list_argv.py', 'hey', 'yo']

$ cp list_argv.py /usr/local/bin/list_argv
$ list_argv hey yo
['/usr/local/bin/list_argv', 'hey', 'yo']

Replace raw_input() with sys.argv.

'your_ls.py':

#!/usr/local/bin/python

import sys
import os

dire = '.'
if len(sys.argv) > 1:
    dire = sys.argv[1]
print('\n'.join(os.listdir(dire)))

'your_ls.py' use example:

$ chmod 744 your_ls.py 
$ cp your_ls.py /usr/local/bin/your_ls
$ your_ls 
list_argv.py
your_file.py
your_ls.py
your_subprocess.py
$ your_ls .
list_argv.py
your_file.py
your_ls.py
your_subprocess.py
$ your_ls blah
Traceback (most recent call last):
  File "/usr/local/bin/your_ls", line 9, in <module>
    print('\n'.join(os.listdir(dire)))
OSError: [Errno 2] No such file or directory: 'blah'

Use subprocess.Popen to access anything you could from the command line.

your_subprocess.py:

#!/usr/local/bin/python

import os
import subprocess

while(True):
    # cntrl-c to quit
    input = raw_input('your_prompt$ ')

    process = subprocess.Popen(input, shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)

    out, err = process.communicate()

    print(out)
    print(err)

your_subprocess.py use example:

$ chmod 744 your_subprocess.py 
$ cp your_subprocess.py /usr/local/bin/your_subprocess
$ your_subprocess 
your_prompt$ ls
list_argv.py
your_file.py
your_ls.py
your_subprocess.py


your_prompt$ ls .
list_argv.py
your_file.py
your_ls.py
your_subprocess.py


your_prompt$ pwd
/Users/ox/_workspace/cmd_ln


your_prompt$ blah

/bin/sh: blah: command not found

your_prompt$ ^CTraceback (most recent call last):
  File "/usr/local/bin/your_subprocess", line 8, in <module>
    input = raw_input('your_prompt$ ')
KeyboardInterrupt
$

BREAK STUFF!

:-D

HAVE FUN!

-ox

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks!! Your answer is super useful. Do you know how to install python command line app by pip or brew?
sudo pip install ipython hold the sudo if you are in a python virtual environment and checkout ipython notebook: pip install ipython[notebook] it is so freaking cool!
21

A true command-line program is something in the vein of ls or grep; it is started from the command-line, but it's non-interactive and can be used in pipelines and combined with other command-line programs. A typical command-line program is not interactive on its own, instead relying on shell for interaction, and on an init file for customization.

What you want to create is a TUI (text user interface) application, that uses the full capabilities of the TTY as an interactive platform. To do that, look up curses.

1 Comment

Thanks I started learning the curses module. Seems be exactly what I was looking for!
10

You should take a look at the cmd module.

See the Python Cookbook for examples of its use.

Comments

5

THe simplest way to do an interactive console application would be:

while True:
    command = raw_input('command? ').strip()
    if command == 'say_hello':
        print('Hello')
    elif command == 'other_thing':
        print('Doing something else')
    elif command == 'quit':
        break
    else:
        print('Invalid Command.')

That's the basic structure. If you want something more vim-like, you'll probably need to use the curses library.

1 Comment

This is the only answer that properly addresses the author's question.
0

If you want to create an standalone binary for a UNIX system, use freeze. If you want one for a Windows system, look into py2exe. To control locations of output on your screen, use the curses module.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.