Returns the names of all open can/vcan interfaces using
    the ``ip link list`` command. If the lookup fails, an error
    is logged to the console and an empty list is returned.

    :rtype: an iterable of :class:`str`

def find_available_interfaces():
    """Returns the names of all open can/vcan interfaces using
    the ``ip link list`` command. If the lookup fails, an error
    is logged to the console and an empty list is returned.

    :rtype: an iterable of :class:`str`
    """

    try:
        # it might be good to add "type vcan", but that might (?) exclude physical can devices
        command = ["ip", "-o", "link", "list", "up"]
        output = subprocess.check_output(command, universal_newlines=True)

    except Exception as e: # subprocess.CalledProcessError was too specific
        log.error("failed to fetch opened can devices: %s", e)
        return []

    else:
        #log.debug("find_available_interfaces(): output=\n%s", output)
        # output contains some lines like "1: vcan42: <NOARP,UP,LOWER_UP> ..."
        # extract the "vcan42" of each line
        interface_names = [line.split(": ", 3)[1] for line in output.splitlines()]
        log.debug("find_available_interfaces(): detected: %s", interface_names)
        return filter(_PATTERN_CAN_INTERFACE.match, interface_names)