Skip to main content
This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (
Help us improve Python packaging - Donate today!

Parallel shell using Func

Project Description

Func is a remote execution framework that allows you to execute python code or shell commands on as many servers as you want. You can extend it with your own modules and use the overlord api or a shell command to execute these.

What’s missing is an interactive shell and way to create simple scripts without resorting to python. I quite often use func to troubleshoot, a typical session goes like this:

  • Check the {contents of a file, status of a service, age of a cache}
  • On machines where it’s wrong, run a command to fix it
  • Lather, rinse repeat


This package requires func, which is not installable from PyPI, and pyparsing (which is). Once func is installed and configured, installing func-shell is as simple as:

$ pip install pyparsing func-shell


fsh has been built to make this a lot easier. Here’s a typical session, I needed to restart puppet on servers where it hung, with comments to explain:

Add all machines with ‘lhr1’ in their hostname to the current list of machines

fsh> + lhr1

Test reachability


Use only reachable hosts

fsh> = $ok

Tail the puppet log log

fsh> @tail /var/log/puppet/puppetd.log

Filter out hosts that have todays date in the log, they’re not hung

fsh> - x[1] =~ /2013-02-02/

And restart the puppet service

fsh> service.restart(‘puppet’) 0 0 0

To write that as a one-off python script, or in the python interactive interpreter is error-prone and tedious.

While you could do all this in python, fsh makes it easier and clearer with more concise syntax and easier to understand output.


There are 5 types of input:

  • Commands to modify the list of hosts, or fsh settings
  • Calls to func modules, such as
  • Shell commands to be executed via the command module
  • Sourcing another file with commands
  • Comments, which are lines starting with a # character (leading whitespace is allowed and ignored)

All these commands can be entered in an interactive shell, or in a file to be executed by the shell.

The list of hosts

  • + hostspec (add host to the set)
  • - hostspec (remove hosts from the set)
  • = hostspec (reset the current set)
  • ? [hostspec] (display the expansion of hostspec, or the current hosts)

These commands all manipulate the list of hosts that subsequent commands run on. A hostspec can take 3 forms: a hostname or glob, such as:

= dbserver-* + webapp-. -

A filename that contains a list of hosts, one per line:

  • < hostlist.txt

Or a filter expression that matches the results of the last executed command:

  • x[0] == 0
  • x[1] =~ /my-test-string/

You can also use the special strings $ok and $failed to refer to the hosts the last command succesfully ran on or failed to run. A succesful run is one that does not raise a python error and (in the case of a shell command) exited with status code 0.

Func parameters

fsh has a few internal variables you can set in the shell:

How many hosts to do in parallel:

set parallel 20

The timeout for commands:

set timeout 30

Verbosity (like in bash):

set +x set -x

Calling func module functions

Anything that looks like a function call to a func method, module.method(…), will be interpreted as such. Arguments to the method can only be literals. Examples: service.stop(‘named’) mymodule.mymethod([“foo”, “bar”, {“baz”: “quux”}])

The result of the command will be displayed. To suppress the displaying, prefix the call with an @ sign. This is useful if the result is only used for filtering hosts.

Shell commands

Anything that does not look like administrativa or func call will be executed as a shell command on the remote servers in the current host list. As with calls to func modules, the output is shown on screen unless you prefix the call with an @ sign. To see what’s in /srv/www, if it exists:

@test -e /srv/www - $failed ls -la /srv/www | grep html

Sourcing another file

Like regular shells, you can source another file with the . command:

. more_commands.fsh


The examples directory has examples with comments. If you have a neat example, submit a pull request on :-)

Release History

This version
History Node


History Node


History Node


History Node


History Node


Download Files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, Size & Hash SHA256 Hash Help File Type Python Version Upload Date
(8.7 kB) Copy SHA256 Hash SHA256
Source None May 29, 2013

Supported By

Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Google Google Cloud Servers