UDEV Fehler

  • Hi, wenn ich mein Smartphone per USB verbinde möchte ich, dass sich mein Script automatisch öffnet.
    Mit

    Code
    udevadm info --query=all --path="/sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4" --attribute walk

    bekam ich die nötigen "ATTR" Informationen.
    In "/etc/udev/rules.d" habe ich in der Datei "99-com.rules" die Zeile

    Code
    KERNEL=="sd*", SUBSYSTEMS=="usb", ATTR{serial}=="a2cee515", ATTR{idProduct}=="6860", ACTION=="add", RUN+="/home/pi/Desktop/test.py"

    eingefügt.
    Wenn ich nun aber mein Smartphone per USB verbinde, reagiert mein raspberry zwar darauf, und bietet mir an über "mtp://[usb:001,010]/" auf die Datein zuzugreifen,
    aber mein Script wird nicht ausgeführt :/

    Kann mir jemand sagen was ich falsch gemacht habe?

  • Im Skript steht gerade einfach

    Code
    print("Hello World")

    , also ist erstmal nur zum testen.
    Ich hänge jetzt mal den Python Part davor und versuche es nochmal.
    Automatisch zusammengefügt:
    Hat leider nichts geholfen...
    Brauch ich vielleicht mehr "ATTR" Informationen oder so?

    Einmal editiert, zuletzt von Issei (22. April 2017 um 18:51)

  • Und wie bzw wo denkst du soll dir diese print Ausgabe angezeigt werden? :fies:

    Das wird so nichts.

    Wenn du eine Konsole auf machst und dort ein Python Script ausführst, wird ein Ausgabekanal auf deine Konsole erzeugt um dir dort sowas wie print's anzuzeigen - einfach formuliert.
    Wenn du aber ein Script über crontab, /etc/rc.local oder udev ausführst, gibt es keinen Ausgabekanal - wohin auch?
    Stell dir vor du bindest ein Script für einen anderen Benutzer ein - möchtest du dann jedesmal eine "Nachricht" angezeigt bekommen? Zugespammt werden mit irgendwelchen Ausgaben?

    Was genau hast du vor? Was soll das Script machen?

  • Das Skript soll alle Fotos vom Handy automatisch auf den Pi überspielen.
    Das wäre mein Skript bis jetzt:

    Code
    import glob, shutil
    
    
    source = "/mtp://[usb:001,055]/Phone/Pictures/Ballons" and "mtp://[usb:001,055]/Phone/Pictures/Familie" and "mtp://[usb:001,055]/Phone/Pictures/Florida" and "mtp://[usb:001,055]/Phone/Pictures/Ramona" and "mtp://[usb:001,055]/Phone/Pictures/Screenshots"
    dest = "/home/pi/Desktop/Photos and videos"
    
    
    for file in glob.glob(source + ".jpg"):
        shutil.copy(file, dest)
  • Ok, vielleicht habe ich auch einfach einen Fehler im Skript.
    Wenn ich es manuell ausführe importiert es auch keine Fotos.
    Ist dir beim Code irgendein Fehler aufgefallen?
    Sonst müsste ich einfach einen neuen Thread aufmachen.

  • Schämst du dich nicht? ;)
    UDEV kann nicht zaubern :fies:

    Wo hast du den Code denn her?

    Alleine schon die "source" Zeile funktioniert bei mir nicht so wie es suggeriert wird

    Code
    >>> source = "/mtp://[usb:001,055]/Phone/Pictures/Ballons" and "mtp://[usb:001,055]/Phone/Pictures/Familie" and "mtp://[usb:001,055]/Phone/Pictures/Florida" and "mtp://[usb:001,055]/Phone/Pictures/Ramona" and "mtp://[usb:001,055]/Phone/Pictures/Screenshots"
    >>> source
    'mtp://[usb:001,055]/Phone/Pictures/Screenshots'
    >>>

    Es sind also nicht mehrere Einträge sondern nur noch der letzte.

    Auch die "for" Schleife funktioniert so nicht, weil source + ".jpg" das zu "mtp://[usb:001,055]/Phone/Pictures/Screenshots.jpg" gemacht wird.
    Wenn dann müsste es irgendwie so lauten:
    [code=php]for file in glob.glob(source + "/*.jpg"):[/php]

  • Ja, tut mir leid mit UDEV :D
    Ich habe den Code jetzt nach deinem Beispiel abgeändert, aber er funktioniert trotzdem noch nicht.
    Müssten nicht zumindest die Screenshots importiert werden?
    Ich bin mir nicht ganz sicher, aber vielleicht liegt es am Dateipfad.
    Immer wenn ich mein Handy verbinde, geht die zweite Zahl um 1 höher.
    Also jetzt ist der Pfad "mtp://[usb:001,025]/", beim nächsten mal "mtp://[usb:001,026]/".
    Ich weiß das ich dafür für den Code auch noch eine Lösung finden müsste, aber eines nach dem anderen :rolleyes:.
    Kann man vielleicht sonst irgendwie auf die Fotos vom Pi zugreifen, also gibt es einen zweiten Dateipfad?

  • Der Vorteil an UDEV ist dass das Device in der Rule bekannt ist. Man kann also dem Script das neue Device übergeben. Siehe dazu auch FAQ => Nützliche Links / Linksammlung => udev
    Du musst dann halt im Script eine entsprechende Handhabung vornehmen damit die Übergabe auch verwendet wird.

    Desweiteren sind bei Linux Leerzeichen in Datei und Verzeichnissen eher schlecht. "/home/pi/Desktop/Photos and videos" Ist also nicht wirklich toll, es fehlt aber auch das abschließende " / ". Würde es dir sehr weh tun das Verzeichnis so umzubenennen: "/home/pi/Desktop/Photos_and_videos/" :huh:
    (natürlich muss das Verzeichnis auch existieren!)

  • Ne, das abzuändern ist kein Thema :thumbs1:
    Mein Code ist jetzt

    Code
    import glob, shutil
    
    
    source = "mtp://[usb:001,025]/Phone/Pictures/Ballons" and "mtp://[usb:001,025]/Phone/Pictures/Familie" and "mtp://[usb:001,025]/Phone/Pictures/Florida" and "mtp://[usb:001,025]/Phone/Pictures/Ramona" and "mtp://[usb:001,025]/Phone/Pictures/Screenshots/"
    dest = "/home/pi/Desktop/Photos_and_videos/"
    
    
    for file in glob.glob(source + "/*.jpg"):
       shutil.copy(file, dest)

    Ich wusste nicht ganz ob hinter "Screenshots" nun auch ein "/" musste oder nicht, aber ich habe es auf beide Arten probiert und beide wurden wieder nichts :s
    Und klar, der Ordner existiert auf dem Desktop.
    Das ist echt zum verzweifeln :wallbash:

  • Und du bist sicher dass das Device über MTP richtig eingebunden wurde?

    Wie gesagt, übergib das Device was von udev erkennt wurde dem Python Script. Setze "source" als Liste ohne "device path" und setz dann in der for das device + source ein.

    Ungefähr so:

    Code
    KERNEL=="sd*", SUBSYSTEMS=="usb", ATTR{serial}=="a2cee515", ATTR{idProduct}=="6860", ACTION=="add", RUN+="/home/pi/Desktop/test.py /dev/%k"

    [code=php]
    import os
    import sys
    import glob
    import shutil

    source = sys.argv[1]

    folders = [
    "/Phone/Pictures/Ballons/",
    "/Phone/Pictures/Familie/",
    "/Phone/Pictures/Florida/",
    "/Phone/Pictures/Ramona/",
    "/Phone/Pictures/Screenshots/",
    ]
    dest = "/home/pi/Desktop/Photos_and_videos/"

    for dir in folders:
    if not os.path.exists(dir):
    continue
    print "checking %s" % dir
    for file in glob.glob(source + dir + "*.jpg"):
    print "copy file %s to %s" % (file, dest)
    shutil.copy(file, dest)
    [/php]

    Aber wie gesagt musst du sicherstellen das mtp richtig funktioniert.

  • Bin mir da ziemlich sicher/wie genau könnte ich das denn überprüfen?
    Zumindest kann ich direkt über MTP auf alle Dateien vom Handy zugreifen, ohne Probleme.
    Wenn ich den Code so ausführen möchte, bekomme ich die Fehlermeldung

    Code
    Traceback (most recent call last):
      File "/home/pi/Desktop/Import2.py", line 6, in <module>
        source = sys.argv[1]
    IndexError: list index out of range

    Ich habe woanders im Internet gelesen, dass man über MTP nicht auf normale Dateioperationen zugreifen kann.
    Muss man da vielleicht irgendeinen Umweg gehen?

  • Was genau soll man denn übergeben?
    Im Internet habe ich den Fehler jetzt auf mehreren Seiten gefunden, wo man "sys.argv[1]" zu "sys.argv[1:]" machen sollte.
    Danach kam keine Fehlermeldung mehr, aber es funktionierte trotzdem nicht.
    Ich habe auch versucht als source wieder "mtp://[usb:001,014]/" oder auch "/run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C014%5D/" zu benutzen, allerdings auch erfolglos ....
    Wie genau kann ich das jetzt beheben?

  • "sys.argv[1:]"
    Bewirkt das alle Argumente nach 1 gelten.
    Ein Argument wird generell getrennt durch Leerzeichen gewertet.
    Beispiel: ./bla.py a b c
    a ist das erste übergebene Parameter
    b das zweite
    c das dritte
    "sys.argv[1:]" würde dann sowohl a als auch b und c verwenden.
    Einfacher Test:

    PHP
    import sys
    print sys.argv[1:]
    [/php]
    [code]
    root@raspberrypi:/tmp# python t.py bla blub
    ['bla', 'blub']
    root@raspberrypi:/tmp#

    Übergibt man nix bleibt die Liste leer, es kommt nur keine Fehlermeldung. Das löst also kein Problem (fehlende Übergabe beim ausführen) sondern ignoriert es nur.

    Was dem Script in deinem Fall übergeben werden soll? Guck dir doch den Code noch mal an:
    [code=php]
    import os
    import sys
    import glob
    import shutil

    source = sys.argv[1]

    folders = [
    "/Phone/Pictures/Ballons/",
    "/Phone/Pictures/Familie/",
    "/Phone/Pictures/Florida/",
    "/Phone/Pictures/Ramona/",
    "/Phone/Pictures/Screenshots/",
    ]
    dest = "/home/pi/Desktop/Photos_and_videos/"

    for dir in folders:
    if not os.path.exists(dir):
    continue
    print "checking %s" % dir
    for file in glob.glob(source + dir + "*.jpg"):
    print "copy file %s to %s" % (file, dest)
    shutil.copy(file, dest)
    [/php]
    Welche Zeile hier bezieht sich auf "sys.argv" und wo wird das eingesetzt?

  • Auf das "sys.argv" bezieht sich die 21. Zeile.
    Wie ich das verstehe sagt diese Zeile, dass die gesamte "Source" jetzt nach ".jpg" durchsucht werden soll.
    Aber fehlt hier nicht noch der genauere Pfad?
    So weiß Python doch gar nicht, wo nach den Ordnern "/Phone/Pictures/Ballons/", "/Phone/Pictures/Familie/" etc. gesucht werden soll, oder gibt "sys.argv[1]" dem Programm darüber auch noch nähere Auskunft?

  • "source" ist eine Variable die wir mit sys.argv[1] füttern bzw setzen. "source" enthält dann also den ersten Parameter der beim ausführen ans Script übergeben wurde.

    In Beitrag#13 schlug ich eine Anpassung der udev Rule vor, die da vorsieht beim RUN dem Script einen Parameter zu übergeben: /dev/%k
    Ob das soweit korrekt ist kann ich zZt nicht beurteilen, ist auch erst mal egal denn das zeigt WAS dem Script beim ausführen übergeben wird

    Wenn du das Script also nun manuell ausführen willst _musst_ du einen Parameter übergeben, der dann in "source" hinterlegt wird.

    Im späteren Verlauf des Scripts wird "source" dazu verwendet den Pfad in dem gesucht werden soll zu bilden:

    Code
    source + dir + "*.jpg"


    Da das in einer for Schleife steht würde zum Beispiel "dir" das enthalten:

    Code
    /Phone/Pictures/Ballons/


    Und "source" enthält zum Beispiel:

    Code
    /media


    ...dann wird daraus?

    Code
    /media/Phone/Pictures/Ballons/*.jpg

    ...und ist dann die Suchmaske.

    Du hast erwähnt das sich mtp://[usb:001,025] ständig ändert. Wer wenn nicht udev kennt aber die neue Adresse? Deshalb schreiben wir das Script dynamisch und müssen jetzt nur noch hinkriegen das udev uns die richtigen Adressen/Pfade ans Script übergibt..

  • Ok, also die von dir vorgeschlagene udev Regel habe ich übernommen.
    Ist es wirklich ok das in "99-com.rules" zu übernehmen, oder sollte man im Ordner eine neue Datei anlegen?
    Trotz der Änderungen hat es bis jetzt noch nicht funktioniert, kann man für udev wirklich nur "ATTR" verwenden?
    Bei anderen Beispielen im Internet war es eigentlich ausschließlich "ATTRS", aber das sollte doch eigentlich für die Erkennung des Gerätes nicht wichtig sein, oder?
    Mir ist an den"print" Befehlen aufgefallen, dass du das Skript in der älteren Version von Python geschrieben hast.
    Ich weiß, dass bei "print" beim neuen Python Klammern fehlen, aber gäbe es sonst noch etwas was ich an der Syntax ändern müsste?
    Vielleicht liegt da ja auch der Fehler bei mir.

    Auch wenn es theoretisch nicht so wichtig ist, da es ja automatisch laufen sollte, aber wie sollte der Parameter bei der manuellen Ausführung aussehen?
    Wie ich schon schrieb habe ich es bei "source" sowohl mit dem "MTP" Pfad, als auch über run versucht, aber Python scheint damit seine Probleme zu haben.

    PS: Vielen Dank für deine großen Anstrengungen mir zu helfen :)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!