python-shelltools

The bucket of python shell helpers, no dependencies, simple API.

Supported platforms

  • Python2.6
  • Python2.7
  • Python3.3
  • PyPy1.9

Source Code

https://github.com/xando/python-shelltools


shelltools.run – subprocess wrapper

>>> from shelltools import run

>>> run('uname -r').stdout
3.7.0-7-generic

>>> run('uname -r', 'wc -c')
uname -r | wc -c

>>> run('uname -r', 'wc -c').stdout
16
run.stdout

Standard output from executed command

>>> run('uname -r').stdout
3.7.0-7-generic

>>> run('ls -la').stdout.lines
['total 20',
 'drwxrwxr-x 3 user user 4096 Dec 20 22:55 .',
 'drwxrwxr-x 5 user user 4096 Dec 20 22:57 ..',
 'drwxrwxr-x 2 user user 4096 Dec 20 22:37 dir',
 '-rw-rw-r-- 1 user user    0 Dec 20 22:52 file']

>>> run('ls -la').stdout.qlines
[['total 20'],
 ['drwxrwxr-x, 3, user, user, 4096, Dec, 20, 22:55, .'],
 ['drwxrwxr-x, 5, user, user, 4096, Dec, 20, 22:57, ..'],
 ['drwxrwxr-x, 2, user, user, 4096, Dec, 20, 22:37, dir'],
 ['-rw-rw-r--, 1, user, user,    0, Dec, 20, 22:52, file']]
run.stderr

Standard error from executed command

>>> run('rm not_existing_directory').stderr
rm: cannot remove `not_existing_directory': No such file or directory
run.status

Status code of executed command

>>> run('uname -r').status
0

>>> run('rm not_existing_directory').status
1
run.chain

The full chain of command executed

>>> run('uname -r', 'wc -c').chain
[uname -r, uname -r | wc -c]

To get statuses from all component commands

>>> [e.status for e in run('uname -r', 'wc -c').chain]
[0, 0]
run.pipe

To pipe data in

from shelltools import run

run('grep something', data=run.stdin)
$ ps aux | python script.py

shelltools.path – path manipulation

>>> from shelltools import path

>>> path('/var/log')
/var/log

>>> path('/var', 'log')
/var/log

>>> path('/var', 'log', 'syslog')
/var/log/syslog

>>> [(element.user, element.group, element.mod) for element in path('.')]
[('user', 'user', '0664'),
 ('user', 'user', '0664'),
 ('user', 'user', '0664'),
 ('user', 'user', '0664'),
 ('user', 'user', '0664'),
 ('user', 'user', '0664'),
 ('user', 'user', '0664'),
 ('user', 'user', '0775'),
 ('user', 'user', '0664')]

Path is also a instance of basestring so all methods implemented for string/unicode should work as well.

>>> path('.').absolute().split('/')
['', 'home', 'user', 'Projects', 'python-shelltools']

>>> path('/home/user/test_tmp_directory').replace('_', '-')
'/home/user/test-tmp-directory'

>>> location = path('/home/user/test_tmp_directory')
>>> location.mv(location.replace('_', '-'))
path.user

Path attribute, returns name of the user owner of the path.

>>> path('/home/user').user
user
path.group

Path attribute, returns name of the group owner of the path.

>>> path('/etc/').group
root
path.mod

To get Unix path permissions.

>>> path('.').mod
'0775'
path.absolute

Returns a normalised absolutized version of the pathname path.

>>> path('.').absolute
/home/user/Projects/shelltools
Return type:path
path.basename

Returns the path basename.

>>> path('/home/user/Projects/shelltools').basename
shelltools
Return type:path
path.dir

Returns the directory path of pathname path.

>>> path('/var/log/syslog').dir
/var/log
Return type:path
path.a_time

Return the time of last access of path. The return value is a number giving the number of seconds since the epoch.

>>> path('/var/log/syslog').a_time
1358549788.7512302
Return type:float
path.m_time

Return the time of last modification of path. The return value is a number giving the number of seconds since the epoch.

>>> path('/var/log/syslog').m_time
1358549788.7512302
Return type:float
path.size

Return the size of path in bytes

>>> path('.').size
4096
Return type:int
path.exists

Returns True if path refers to an existing path. Returns False for broken symbolic links.

>>> path('/var/log').exists
True
Return type:bool
path.is_dir()

Return True if path is an existing directory. This follows symbolic links, so both is_link() and is_dir() can be true for the same path.

>>> path('/var/log').is_dir()
True
Return type:bool
path.is_file()

Return True if path is an existing regular file. This follows symbolic links, so both is_link() and is_file() can be true for the same path.

>>> path('/var/log/syslog').is_file()
True
Return type:bool
path.mkdir(p=False)
Parameters:p – if changed will behave like mkdir -p, creating all directories recursively.
>>> path('dir').mkdir().exists
True
>>> path('/home/user/another/dir',p=True).mkdir().exists
True
Return type:path
path.rm(r=False)

Removing file or directory, r parameter needs to be applied to remove directory recursively.

>>> path('file').rm()
file
>>> path('/tmp').rm(r=True)
/tmp
Return type:path
path.cp(target, r=False)

Copy the file or the contents the directory to target destination, r parameter needs to be applied to perform this action recursively inside directory.

>>> path('dir').cp('dir_copy')
dir_copy
>>> path('file1').cp('file_copy')
file_copy
>>> path('file1').cp('file_copy').exists
True
Return type:path
path.ln(target, s=True)

Create a link pointing to source named link_name, default call will create symbolic link, change s=False to create hard link.

>>> path('/tmp/').ln('/home/user/tmp')
'/home/user/tmp'
Return type:path

Unlink path from the poiting location.

>>> path('/home/user/tmp').is_link()
True
>>> path('/home/user/tmp').unlink()
'/home/user/tmp'
Return type:path
path.touch()

Imitates call of Unix’s touch.

>>> path('file').touch()
file
Return type:path
path.ls(pattern='*', sort=None)

Display content of the directory, use pattern as filtering parameter, change order by defining sort function.

>>> path('/var/log').ls()
[/var/log/boot.log, /var/log/dmesg, /var/log/faillog, /var/log/kern.log, /var/log/gdm]
>>> path('/var/log/').ls('*log')
[/var/log/boot.log, /var/log/faillog, /var/log/kern.log]

path(‘.’).ls(sort=lambda x: not x.startswith(‘_’)) [_themes, _build, _static, _templates, Makefile, conf.py, index.rst]

Return type:list
path.ls_files(patern='*', sort=None)

Returns files inside given path.

>>> path('.').ls_files()
[/var/log/boot.log, /var/log/dmesg, /var/log/faillog, /var/log/kern.log]
Return type:list
path.ls_dirs(patern='*', sort=None)

Returns directories inside given path.

>>> path('.').ls_dirs()
[/var/log/gdm]]
Return type:list
path.walk(pattern='*', r=False, sort=None)

Location walk generator

>>> for element in path('.').walk():
        print element
/var/log/boot.log
/var/log/dmesg
/var/log/faillog
/var/log/kern.log
/var/log/gdm
Return type:generator
path.chmod(mode)

To change path access permissions

>>> path('test').chmod('0775')
>>> path('test').mod
'0775'
path.open(mode=None, buffering=None)

Open a file, returning an object of the File Objects.

>>> path('/var/log','syslog').open('r')
<open file '/var/log/syslog', mode 'r' at 0x294c5d0>

shelltools.text – text helpers

static text.text_list(words, last_word='and')
>>> text_list(['a', 'b', 'c', 'd'])
'a, b, c and d'

>>> text_list(['a', 'b', 'c'], 'or')
'a, b or c'

>>> text_list(['a', 'b'], 'or')
'a or b'

>>> text_list(['a'])
'a'

>>> text_list([])
''
static text.wrap(text, width)

A word-wrap function that preserves existing line breaks and most spaces in the text. Expects that existing line breaks are posix newlines.

>>> print wrap("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis sollicitudin ", 30)
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Duis sollicitudin
text.progress()
from shelltools.text import progress

for i in progress(range(10)):
    sleep(0.2)
[                                ] 0/5 - 00:00:00
[######                          ] 1/5 - 00:00:00
[############                    ] 2/5 - 00:00:00
[###################             ] 3/5 - 00:00:00
[#########################       ] 4/5 - 00:00:00
[################################] 5/5 - 00:00:00
classmethod progress.dots(it, label='', hide=False)

Progress iterator. Prints a dot for each item being iterated

for i in progress.dots(range(10)):
    sleep(0.2)
.
..
...
....
.....
classmethod progress.mill(it, label='', hide=False, expected_size=None)

Progress iterator. Prints a mill while iterating over the items.

for i in progress.mill(range(10)):
    sleep(0.2)
| 0/5
/ 1/5
- 2/5
\ 3/5
| 4/5
/ 5/5