일부 Python DBus를 포착할 수 없습니다(오류 제외).

일부 Python DBus를 포착할 수 없습니다(오류 제외).

Python에서 다음과 같이 치명적이지 않은 오류가 발생했습니다 stderr.

오류: dbus.proxies: 내부 검사 오류: 1.4:/org/freedesktop/Thermald: dbus.Exceptions.DBusException: org.freedesktop.DBus.Error.AccessDenied: 메시지 보내기 거부, 2개의 일치 규칙 type="method_call",sender= ":1.974" (uid=1000 pid=20020 comm="/usr/bin/python ./mmm") 인터페이스="org.freedesktop.DBus.Introspectable" member="Introspect" 오류 이름="(설정 아님)" request_reply="0" 목적지=":1.4" (uid=0 pid=1309 comm="/usr/sbin/Thermald --no-daemon --dbus-enable")

블록 대신에 정통적인 "인용문"을 사용해서 죄송합니다 code. 오른쪽으로 8마일 스크롤하는 시간을 절약하고 싶습니다.

다음을 사용하여 오류를 잡을 수 있습니다.

    except dbus.exceptions.DBusException as err:
        # Same as dbus.DBusException
        print('\ndbus.exceptions.DBusException:', service)
        print(err.message+'\n')
        return False
    except dbus.DBusException as err:
        # Same as dbus.exceptions.DBusException
        print('\ndbus.DBusException:', service)
        print(err.message+'\n')
        return False

그러나 그것은 단지 내 제외를 생성합니다.최대이전 오류 메시지. 하지만 일반적으로 발생하는 이전 오류 메시지는 억제되지 않습니까? ? ?

dbus.exceptions.DBusException: org.freedesktop.thermald
Rejected send message, 2 matched rules; type="method_call", sender=":1.974" (uid=1000 pid=20020 comm="/usr/bin/python ./mmm ") interface="org.freedesktop.DBus.Introspectable" member="Introspect" error name="(unset)" requested_reply="0" destination=":1.4" (uid=0 pid=1309 comm="/usr/sbin/thermald --no-daemon --dbus-enable ")

다음과 같이 총 4개의 시스템 서비스 DBus "액세스 거부" 오류가 발생합니다.

ERROR:dbus.proxies:Introspect error on :1.19:/fi/epitest/hostap/WPASupplicant:
ERROR:dbus.proxies:Introspect error on :1.19:/fi/w1/wpa_supplicant1:
ERROR:dbus.proxies:Introspect error on :1.20:/org/freedesktop/NetworkManager/dnsmasq:
ERROR:dbus.proxies:Introspect error on :1.4:/org/freedesktop/thermald:

이것은 일반적인 Ubuntu 버그인 것 같습니다(저는 16.04.6 LTS, 커널 4.14.170, Gnome 3.18을 사용하고 있습니다). 나는 이러한 버그를 고치고 싶지 않습니다. 내 프로젝트에서는 이러한 DBus 서비스를 확인할 필요가 없습니다. 오류 메시지를 표시하지 않으려고 합니다.

FWIW 또한 두 개의 세션 서비스 DBUS 오류가 발생합니다.할 수 있는성공적으로 캡처되었습니다:


==============   Session services   ================

Object path: '/org/freedesktop/network-manager-applet' contains invalid character '-'
Object path: '/org/nautilus-actions/DBus' contains invalid character '-'

나는 이것으로부터 생각한다우편 엽서예를 들어 이스케이프해야 할 수도 있습니다 \-. 이러한 오류의 실제 의미와 해결 방법을 아는 것도 좋습니다.

FWIW 여기에 내 코드가 다시 있습니다.

    def refresh_listdata(self, listdata):

        import json

        # If we delete list and append nothing appears (garbage collecctor).
        # listdata = []

        listdata *= 0   # https://stackoverflow.com/a/44349418/6929343

        bus = dbus.SystemBus()
        print ('\n=============   System services   =================\n')

        for service in dbus.SystemBus().list_names():
            # Skip over ":1.20", ":1.65", etc.
            if not service.startswith(":") :
                # print(service)
                object_path=service.replace(".", "/")
                object_path = "/" + object_path
                dictionary = self.rec_intro(bus, service, object_path)
                # print(dictionary)
                if dictionary != False :
                    listdata.append(dictionary)

        bus = dbus.SessionBus()
        print ('\n==============   Session services   ================\n')

        for service in dbus.SessionBus().list_names():
            if not service.startswith(":") :
                # print(service)
                object_path=service.replace(".", "/")
                object_path = "/" + object_path
                dictionary = self.rec_intro(bus, service, object_path)
                # print(dictionary)
                if dictionary != False :
                    listdata.append(dictionary)

#        print ("\nlistdata[0]\n", listdata[0])
#        print(json.dumps(listdata[0], indent=4, sort_keys=True))

    def rec_intro(self, bus, service, object_path, 
                       paths=None, serviceDict=None):

        from xml.etree import ElementTree

        #print(object_path)
        if paths == None:
            paths = {}
        paths[object_path] = {}

        if "-" in object_path :
            print ("Object path: '" + object_path + \
            "' contains invalid character '-'")
            return False

        try:
            obj = bus.get_object(service, object_path)
        except:
            print('Cannot get object: ', service, object_path)
            return False

        try:
            iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
        except:
            print('Interface error:', obj)
            return False

        try:
            xml_string = iface.Introspect()
#        except DBusException as err:
#            # NOT DEFINED!
#            print('\nDBusException:', service)
#            print(err.message+'\n')
#            return False
        except dbus.proxies as err:
            print('\ndbus.proxies:Introspect error:', service)
            print(err.message+'\n')
            return False
#        except org.freedesktop.DBus.Error.AccessDenied as err:
#            # NOT DEFINED!
#            print('\norg.freedesktop.DBus.Error.AccessDenied:', service)
#            print(err.message)
#            return False
        except dbus.exceptions.DBusException as err:
            # Same as dbus.DBusException
            print('\ndbus.exceptions.DBusException:', service)
            print(err.message+'\n')
            return False
        except dbus.DBusException as err:
            # Same as dbus.exceptions.DBusException
            print('\ndbus.DBusException:', service)
            print(err.message+'\n')
            return False
        except:
            print('No permissions to:', bus, service, object_path)
            return False

        for child in ElementTree.fromstring(xml_string):
            if child.tag == 'node':
                if object_path == '/':
                    object_path = ''
                new_path = '/'.join((object_path,
                                     child.attrib['name']))
                self.rec_intro(bus, service, new_path)
            else:
                if object_path == "":
                    object_path = "/"
                functiondict = {}
                paths[object_path][child.attrib["name"]] = functiondict
                for func in child.getchildren():
                    if func.tag not in functiondict.keys():
                        functiondict[func.tag] = []
                    functiondict[func.tag].append(func.attrib["name"])

        if serviceDict == None:
            serviceDict = {}
        serviceDict[service] = paths
        return serviceDict

답변1

알고 보니 systemd에 대한 dbus의 "설계 결함"으로 인해 이 문제가 발생한 것은 제가 처음이 아닙니다. 해결책은 다음과 같습니다.

    def BuildNoPermissions(self, bus):
        ''' Errors add 5 seconds:

        ERROR:dbus.proxies:Introspect error on :1.4:/org/freedesktop/thermald:
        dbus.exceptions.DBusException: org.freedesktop.DBus.Error.AccessDenied:

        Trap this error by first:
        Build list of objects with no introspection.

        Add to list if entry:
            <policy context="default">
                <deny own="fi.epitest.hostap.WPASupplicant"/>
                <deny own="fi.w1.wpa_supplicant1"/>
            </policy>
        ...exists. Add each deny entry to list to trap error:
        ERROR:dbus.proxies:Introspect error on :1.19:/fi/w1/wpa_supplicant1 ...

        Then before introspecting dbus make sure item isn't on list. If it is
        on list then create necessary "No permissions" entry instead.

        Now all that is left is:

        ERROR:dbus.proxies:Introspect error on :1.1450:/org/freedesktop/
        NetworkManager/dnsmasq:

        Found in:
        /etc/dbus-1/system.d/org.freedesktop.NetworkManager.conf:
                        <deny own="org.freedesktop.NetworkManager.dnsmasq"/>

        Problem is NetworkManager has Introspect but denies dnsmasq so check
        deny for all *.conf files even ones with introspect.

        NOTE: when running with sudo things get worse:

        ERROR:dbus.proxies:Introspect error on :1.19:/fi/epitest/hostap/
        WPASupplicant/Interfaces/62: dbus.exceptions.DBusException:
        org.freedesktop.DBus.Error.NoReply: Message recipient disconnected 
        from message bus without replying

        ... and then Ubuntu prints system crash message with option to report.
        '''
#        print ('\n=============   BuildNoPermissions   =================\n')
#        print (bus, '\n')
        result = os.popen("grep -Li introspect /etc/dbus-1/system.d/*"). \
                          read().splitlines()

        for line in result:
            base=os.path.basename(line)     # remove path prefix
            base=os.path.splitext(base)[0]  # remove extension suffix
            ''' Must open up file to see if <deny> is used and add them
            '''
#            print (base)
            self.NoPermissions.append(base)

        result = os.popen("grep 'deny own' /etc/dbus-1/system.d/*"). \
                          read().splitlines()
        for deny in result:
            # [1::2] is a slicing which extracts odd values
            d = deny.split('"')[1::2]
            self.NoPermissions.append(d[0])
            # Only 1 per line, so take index 0
            # print (d[0])

모든 댓글에 대해 죄송합니다. 댓글을 삭제하는 것(또는 더 나쁘게는 다시 작성하는 것)보다는 그대로 두는 것이 더 좋습니다.

루틴을 호출하기 위해 원래 함수가 수정됩니다.

        bus = dbus.SystemBus()
        self.BuildNoPermissions(bus)
#        print ('\n=============   System services   =================\n')
#        print (self.NoPermissions, '\n')
        for service in bus.list_names():
            # Skip over ":1.20", ":1.65", etc.
            if not service.startswith(":") :
                denied = False
                for deny in self.NoPermissions:
                    if deny == service:
                        denied = True
                        break
                if denied: continue

                # print(service)
                object_path=service.replace(".", "/")
                object_path = "/" + object_path
                dictionary = self.rec_intro(bus, service, object_path)
                # print(dictionary)
                if dictionary != False :
                    listdata.append(dictionary)

-보너스 답변... 객체 경로 이름을 제거하세요 .

    if "-" in object_path :
        # Bug: https://bugs.launchpad.net/snappy/+bug/1449722
        object_path = object_path.replace("-", "")

관련 정보