Executes a command through the shell. Spaces should breakup the args. Usage: execute('grep', 'TODO', '*')
    NOTE: Any kwargs will be converted to args in the destination command.
    E.g. execute('grep', 'TODO', '*', **{'--before-context': 5}) will be $grep todo * --before-context=5

def execute(script, *args, **kwargs):
    """
    Executes a command through the shell. Spaces should breakup the args. Usage: execute('grep', 'TODO', '*')
    NOTE: Any kwargs will be converted to args in the destination command.
    E.g. execute('grep', 'TODO', '*', **{'--before-context': 5}) will be $grep todo * --before-context=5
    """

    popen_args = [script] + list(args)
    if kwargs:
        popen_args.extend(_kwargs_to_execute_args(kwargs))

    try:
        return check_call(popen_args, shell=False)
    except CalledProcessError as ex:
        _print(ex)
        sys.exit(ex.returncode)
    except Exception as ex:
        _print('Error: {} with script: {} and args {}'.format(ex, script, args))
        sys.exit(1)