def run_command(pattern_hosts, command, inventory_path=None, roles=None,
                extra_vars=None,
                on_error_continue=False):
    """Run a shell command on some remote hosts.

    Args:
        pattern_hosts (str): pattern to describe ansible hosts to target.
            see https://docs.ansible.com/ansible/latest/intro_patterns.html
        command (str): the command to run
        inventory_path (str): inventory to use
        extra_vars (dict): extra_vars to use
        on_error_continue(bool): Don't throw any exception in case a host is
            unreachable or the playbooks run with errors

    Raises:
        :py:class:`enoslib.errors.EnosFailedHostsError`: if a task returns an
            error on a host and ``on_error_continue==False``
        :py:class:`enoslib.errors.EnosUnreachableHostsError`: if a host is
            unreachable (through ssh) and ``on_error_continue==False``

    Returns:
        Dict combining the stdout and stderr of ok and failed hosts and every
        results of tasks executed (this may include the fact gathering tasks)

    Example:

    .. code-block:: python

        # Inventory
        [control1]
        enos-0
        [control2]
        enos-1

        # Python
        result = run_command("control*", "date", inventory)

        # Result
        {
            'failed': {},
            'ok':
            {
                u'enos-0':
                {
                    'stderr': u'',
                    'stdout': u'Tue Oct 31 04:53:04 GMT 2017'
                },
                u'enos-1':
                {
                    'stderr': u'',
                    'stdout': u'Tue Oct 31 04:53:05 GMT 2017'}
                },
            'results': [...]
        }

    If facts are gathers this is possible to use ansible templating

    .. code-block:: python

        result = run_command("control*", "ping -c 1
        {{hostvars['enos-1']['ansible_' + n1].ipv4.address}}", inventory)
    """

    def filter_results(results, status):
        _r = [r for r in results
              if r.status == status and r.task == COMMAND_NAME]
        s = dict([[r.host, {"stdout": r.payload.get("stdout"),
                            "stderr": r.payload.get("stderr")}]
                  for r in _r])
        return s

    play_source = {
        "hosts": pattern_hosts,
        "tasks": [{
            "name": COMMAND_NAME,
            "shell": command,
        }]
    }
    results = run_play(play_source,
                       inventory_path=inventory_path,
                       roles=roles,
                       extra_vars=extra_vars)
    ok = filter_results(results, STATUS_OK)
    failed = filter_results(results, STATUS_FAILED)
    return {"ok": ok, "failed": failed, "results": results}