Creating a Terminal Program with Python

Question:

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
Asked By: Niels

||

Answers:

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.

Answered By: Brien

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 programs. A typical command-line program has no interactive user experience, instead relying on shell’s history and init file for customization.

What you want to create is a curses application, that uses the full capabilities of the TTY as an interactive platform, for better or worse. To do that, look up curses.

Answered By: user4815162342

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.

Answered By: MJ Howard

You should take a look at the cmd module.

See the Python Cookbook for examples of its use.

Answered By: Noctis Skytower

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!

😀

HAVE FUN!

-ox

Answered By: ox.
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.