Umount alle usb außer...

  • Hallo

    bei mir läuft xbian 14.2 und ich habe mir ein eigenen Menüeintrag in Confluence erstellt, mit dem ich alle USBs auf einmal auswerfen kann. Das mache ich einfach, in dem ich mit RunScript() ein python Script ausführe:

    Python
    #!/usr/bin/python
    
    
    import subprocess
    subprocess.call("sh /home/xbian/scripts/umountAll.sh", shell=True)

    Ich hatte auch

    Code
    subprocess.check_call(["umount", "/media/usb*"])


    versucht, um das shellscript loszuwerden, aber das geht nicht. Da kommt eine Fehlermeldung.

    Wie auch immer. Mein Shellscript:

    Bash
    #!/bin/bash
    sudo umount /media/usb*

    Das funktioniert. Nun bin ich aber an einem Punkt, wo ich nicht mehr alle Festplatten auswerfen möchte, sondern eine eben nicht. Das Problem ist, dass ich nicht gewährleisten kann, dass diese Festplatte wirklich immer usb0 ist. Wenn der RPI neustartet, würfelt sich das bestimmt. Und wenn nicht durchs neustarten, dann eben wegen etwas Anderem.

    Nun kann man ja auch sowas machen:

    Bash
    #!/bin/bash
    sudo umount /media/usb$1


    und dann mit

    Code
    sh umountAll.sh 0
    sh umountAll.sh 1
    ...


    aufrufen. Das setzt aber vorraus, dass ich die Festplatten kenne und wieviele es sind.
    Gibt es eine Möglichkeit, mit shellscript oder python, die Festplatte die nicht ausgeworfen werden soll zu erkennen und alle anderen auszuwerfen?

    Im Prinzip bräuchte ich ja nur eine Datei im Wurzelverzeichnis der Festplatte anlegen, nach der ich dann suche, und diese wird dann eben nicht entfernt. Das ist aber umständlich. Mit Java würde ich das hinbekommen, aber dann müsste ich Java installieren und dann im shellscript eine Javadatei aufrufen. Ein Script ruft ein Script das ein Script aufruft. Irgendwie hohl.

    Vielleicht hat ja noch jemand eine Idee?

  • Wieso 2 Scripte? Wieso lässt du von RunScript() nicht einfach nur ein Script ausführen in dem alles erledigt wird :s

    sh ist btw was anderes als bash. Du setzt zwar einen Shebang auf bash, lässt die Datei dann aber von sh verarbeiten :-/ sh ist älter als bash und kann nicht so viel. Die Dateiendung sagt nichts aus und dient nur der Übersicht. Bestes Beispiel: raspi-config oder rpi-update sind beides bash Scripte aber ohne Dateiendung.

    Wenn du erreichen willst das ein USB-Gerät immer den selben Device-Namen oder Mount-Point erhällt, dann konfiguriere usbmount oder udev entsprechend.

    Also zunächst mal sollte man klären in welcher Sprache du das machen willst - 2 Scripte zu verwenden indem das eine nur das andere aufruft ist Quatsch und zu viel kuddelmuddel.
    Wenn das geklärt ist kann man sich an Details setzen (grad keine Lust beide Möglichkeiten vorzukauen). Im Prinzip lässt du eine Liste mit den gemounteten erstellen und lässt anhand des Names nur das Laufwerk nicht umounten was du halt behalten willst - was aber voraussetzt dass das Device immer den selben "namen" hat.

    //EDIT:


    Ich bin generell kein Freund vom mischen, also wenn man in einer bestimmten Programmiersprache schreibt sollte man möglichst viel nativ in dieser Sprache machen, ohne auf externe/andere Programme auszuweichen. Deshalb würde ich Abstand davon nehmen mithilfe subprocess (also ausführen eines Konsolen Befehls) zu prüfen ob der jeweilige Prozess läuft. Das geht eleganter und schöner mithilfe vom python Modul psutil.

    Vorbereitung:

    Code
    apt-get update
    apt-get install build-essential python-dev python-pip
    pip install psutil

    [code=php]
    import psutil, subprocess

    behalten = "usb0"

    for disk in psutil.disk_partitions():
    if behalten in disk.device:
    continue
    subprocess.check_call(["umount", disk.device])

    [/php]


  • Wieso 2 Scripte? Wieso lässt du von RunScript() nicht einfach nur ein Script ausführen in dem alles erledigt wird :s


    Weil es nicht geht. Ich kann mit RunScript kein Shellscript aufrufen. Habe es versucht und sogar in dem Forum für kodi nachgefragt, aber keine Antwort erhalten. Das Problem haben im Netz viele und umgehen es genauso wie ich. Ich habe auch versucht, das shellscript wegzulassen:

    Code
    subprocess.check_call(["umount", "/media/usb*"])
    subprocess.call("sudo umount /media/usb*", shell=True)


    geht beides nicht. Da kommt eine Fehlermeldung: non zero exit status 2
    errno2 ist meines wissens nach "File or Directory not found" in Unix Systemen. Der gleiche Fehler kommt übrigens, wenn ich statt dem * eine Zahl eingebe. Die usb existieren aber, nämlich usb0 - 4.


    [...] was aber voraussetzt dass das Device immer den selben "namen" hat.


    :wallbash: Ich wusste nicht, dass man auch den Festplattennamen zum umounten nutzen kann. Damit ist es leicht. Die Anzahl meiner Festplatten wird sich vermutlich nicht so schnell ändern und daher kann ich einfach hintereinander

    Code
    umount /media/A
    umount /media/B
    umount /media/D
    ...


    ausführen und behalte C.

    Wenn du jetzt noch weißt, wieso man keine shell scripts in RunScript ausführen kann oder wieso ich nicht mit python umounten kann, bin ich wunschlos glücklich.


  • Weil es nicht geht. Ich kann mit RunScript kein Shellscript aufrufen. Habe es versucht und sogar in dem Forum für kodi nachgefragt, aber keine Antwort erhalten. Das Problem haben im Netz viele und umgehen es genauso wie ich. Ich habe auch versucht, das shellscript wegzulassen:

    Code
    subprocess.check_call(["umount", "/media/usb*"])
    subprocess.call("sudo umount /media/usb*", shell=True)


    geht beides nicht. Da kommt eine Fehlermeldung: non zero exit status 2
    errno2 ist meines wissens nach "File or Directory not found" in Unix Systemen. Der gleiche Fehler kommt übrigens, wenn ich statt dem * eine Zahl eingebe. Die usb existieren aber, nämlich usb0 - 4.

    Ja ne... Du kannst ja offensichtlich durch aus ein Shellscript ausführen, da du ja von RunScript() erst das Python Script und dadurch dann das Bash Script ausführen lässt. Das sind beides Shellscripts.

    Ein exitcode von "2" sagt aber eigentlich "Incorrect Usage" aus, aber naja... Probier erst mal folgendes aus :fies:

    Das du einen Fehler im "only python"-Script erhälst ist etwas völlig anderes und hat mit dem ersten - nämlich 2 verschachtelte Scripts - nichts zu tun und könnte man darauf zurückführen das es keine $PATH Umgebungsvariable gibt und somit kann er 'umount' auch nicht finden. Abhilfe könnte man also erreichen indem man den absoluten Pfad des Befehls verwendet...

    Man muss aber trotzdem die erforderliche Syntax für den jeweiligen Aufruf verwenden... Deine subprocess.call Zeile wieso in dieser Form nicht funktionieren.
    Notfalls einfach mal das Script manuell in der Shell ausführen und so prüfen ob es denn überhaupt funktioniert - unabhängig von KODI. Wenn es aber selbst da nicht geht, kann es freilich auch nicht über KODI gehen.

    Ein weiteres Problem könnte aber eben auch sein dass die Python Dateien nicht ausführbar ist und somit der Shebang nicht verwendet werden kann...


    :wallbash: Ich wusste nicht, dass man auch den Festplattennamen zum umounten nutzen kann. Damit ist es leicht. Die Anzahl meiner Festplatten wird sich vermutlich nicht so schnell ändern und daher kann ich einfach hintereinander

    Code
    umount /media/A
    umount /media/B
    umount /media/D
    ...


    ausführen und behalte C.

    Wenn du jetzt noch weißt, wieso man keine shell scripts in RunScript ausführen kann oder wieso ich nicht mit python umounten kann, bin ich wunschlos glücklich.

    Ich dachte du hättest vorhin geschrieben dass das nicht fest ist und was zuvor /media/C war könnte nach einem Reboot /media/A sein :s


    Das funktioniert. Nun bin ich aber an einem Punkt, wo ich nicht mehr alle Festplatten auswerfen möchte, sondern eine eben nicht. Das Problem ist, dass ich nicht gewährleisten kann, dass diese Festplatte wirklich immer usb0 ist. Wenn der RPI neustartet, würfelt sich das bestimmt. Und wenn nicht durchs neustarten, dann eben wegen etwas Anderem.

    Das solltest du erst mal klären, sonst kriegst du Probleme...


    Wie sieht denn dein RunScript() Eintrag exakt aus?

  • Ok es scheint einiges an Verwirrung zu geben. Nochmal von vorn.

    In meiner Home.xml des Confluence Skins gibt es einen Eintrag:

    Code
    <item id="8">
      <label>HDs auswerfen</label>
      <onclick>RunScript(/home/xbian/scripts/umountAll.py)</onclick>
      <icon>-</icon>
      <thumb>-</thumb>
    </item>

    umountAll.py:

    Python
    #!/usr/bin/python
    
    
    import subprocess
    subprocess.call("sh /home/xbian/scripts/umountAll.sh", shell=True)

    umountAll.sh:

    Bash
    #!/bin/bash
    sudo umount /media/usb*

    Das wars und das funktioniert.

    Es gibt 5 Festplatten. 4 sollen immer ausgeworfen werden, die 5. nicht. Nennen wir sie A, B, C, D und E wobei E nicht entfern werden soll. Nun steckt die E direkt am RPi, die Anderen an einem externen Hub. Das Hub wird stromlosgeschalten, wenn der Fernseher aus geht, deswegen auch umounten. Der RPi bleibt an.

    Ich gehe davon aus, dass xbian die einfach so mounted, wie sich die Festplatten melden. Das heißt, mal ist A usb0, mal ist B usb0. Ich könnte natürlich einfach E zuerst anstecken, dann wäre sie usb0. Ich bezweifel aber, dass das immer so bleibt. Neustart z.B.

    Ich konnte inzwischen das Problem auf eine Stelle reduzieren können. Habe umountAll.py so abgeändert:

    Code
    subprocess.check_call(["/bin/umount", "/media/usb1"]);


    und das geht in der Kommandozeile, wenn ich sudo pythong umountAll.py eingebe. Ohne sudo geht es nicht. Er wirft hier natürlich auch nur die 1 aus.

    Wenn ich das mit kodi ausführen lasse, kommt ein Infofenster Scriptfehler. Ich denke mal, weil das sudo fehlt.


  • Ich gehe davon aus, dass xbian die einfach so mounted, wie sich die Festplatten melden. Das heißt, mal ist A usb0, mal ist B usb0. Ich könnte natürlich einfach E zuerst anstecken, dann wäre sie usb0. Ich bezweifel aber, dass das immer so bleibt. Neustart z.B.

    Soweit ich weiß ist standardmäßig usbmount installiert und erstellt automatisch die Verzeichnisse /media/usb0 bis /media/usb7 , erst mal völlig egal ob man 8 USB Laufwerke angeschlossen hat...
    Das erste Laufwerk welches erkannt wird, wird auf /media/usb0 gemountet usw. Die Reihenfolge wann ein Gerät erkannt wird kann bei jedem Boot willkürlich sein.

    Um das zu umgehen bzw zu verbessern könnte man stattdessen UDEV verwenden, bei dem man anhand bestimmter Kriterien wie zB der Seriennummer des Sticks/Laufwerks immer einen festen Mountpoint festlegen könnte. Dann würde also ein USB-Laufwerk mit der Seriennummer XYZ123 immer nach /media/A gemountet werden, egal wann dieser erkannt wurde.
    Mehr dazu siehe hier: Laufwerk/Gerät immer der selben Gerätedateien zuweisen (udev)
    Falls du das benutzen möchtest solltest du vorher usbmount deinstallieren.


    Er wirft hier natürlich auch nur die 1 aus.

    Ja weil es eben 'check' ist ;)

    Wenn ich das mit kodi ausführen lasse, kommt ein Infofenster Scriptfehler. Ich denke mal, weil das sudo fehlt.

    Entweder weil er 'sudo' ansich nicht findet, eben weil ihm die Umgebungsvariable $PATH fehlt, in der nach Befehlen sucht. Oder weil er keine 'sudo' Rechte besitzt. Ich weiß jetzt leider nicht über welchen Benutzer Kodi unter XBian läuft, aber das könntest du feststellen indem du den auszuführenden Benutzer in eine Datei schreiben lässt, also das Script sollte dann so aussehen:

    Code
    echo $(id) > /tmp/test.txt

    (oder anstatt 'id' -> 'whoami')


    Probier es mal bitte mit folgendem:

    Home.xml

    Code
    <item id="8">
      <label>HDs auswerfen</label>
      <onclick>RunScript("/bin/bash /home/xbian/scripts/umountAll.sh")</onclick>
      <icon>-</icon>
      <thumb>-</thumb>
    </item>

    /home/xbian/scripts/umountAll.sh

    Code
    behalten=usb0
    
    
    for dev in $(ls /media/); do
            echo Checking /media/$dev
            if [ "$dev" != "$behalten" ] && [ ! -z "$(cat /proc/mounts | grep -w /media/$dev)" ]; then
                    echo umounting /media/$dev
                    sudo umount -f /media/$dev
            fi
    done

    Das einzige was du verändern/anpassen musst ist die behalten Variable und bezieht sich auf das Verzeichnis innerhalb /media/.


  • [...] aber das könntest du feststellen indem du den auszuführenden Benutzer in eine Datei schreiben lässt [...]


    Wird schwierig, weil ich nicht weiß, wie ich das als "kodi" user ausführe. Die Befehle:

    Code
    1. cat /etc/passwd |grep "/bin/bash" |cut -d: -f1
    2. cat /etc/passwd |grep "/home" |cut -d: -f1


    1. liefert 2 User: xbian, root
    2. liefert 3 User: iguanair, ntp, xbian


    Probier es mal bitte mit folgendem: [...]


    Ich hatte vor einiger Zeit schon einmal diese Form:

    Code
    <onclick>RunScript("/bin/bash /home/xbian/scripts/umountAll.sh")</onclick>


    und die funktionierte nicht. Deswegen die Sache mit dem Pythonscript.

    Ich kann es aber nicht testen, weil aus irgendeinem Grund dein Script nicht funktioniert:

    Code
    xbian@xbian ~ $ sh scripts/umountAll.sh
    : not founduntAll.sh: 3: scripts/umountAll.sh:
    scripts/umountAll.sh: 4: scripts/umountAll.sh: Syntax error: word unexpected (expecting "do")

    Eine ganz simples Beispielscript mit:

    Bash
    #!/bin/bash
            for i in $( ls ); do
                echo item: $i
            done


    funktioniert auch nicht, mit selbem Fehler.


  • Wird schwierig, weil ich nicht weiß, wie ich das als "kodi" user ausführe. Die Befehle:

    Ich hab dir das doch vorgekaut wie man das herausfindet
    Dein Python Script hat doch zuvor auch ein bash Script ausgeführt oder nicht? Also wieso kannste das jetzt hierfür nicht nutzen? :s


    Ich kann es aber nicht testen, weil aus irgendeinem Grund dein Script nicht funktioniert:

    Code
    xbian@xbian ~ $ sh scripts/umountAll.sh
    : not founduntAll.sh: 3: scripts/umountAll.sh:
    scripts/umountAll.sh: 4: scripts/umountAll.sh: Syntax error: word unexpected (expecting "do")

    Das funktioniert bei mir super:

    ..ich wiederhole mich aber gerne noch mal: sh ist btw was anderes als bash. Du setzt zwar einen Shebang auf bash, lässt die Datei dann aber von sh verarbeiten :-/ sh ist älter als bash und kann nicht so viel. Die Dateiendung sagt nichts aus und dient nur der Übersicht. Bestes Beispiel: raspi-config oder rpi-update sind beides bash Scripte aber ohne Dateiendung.
    Quelle: Beitrag#2

    <onclick>RunScript("/bin/bash /home/xbian/scripts/umountAll.sh")</onclick>

    sollte es auch mit bash ausführen, nicht mit sh. Das denk ich mir nicht grundlos aus. Aber wieso machst du es trotzdem mit sh? :-/ Deine Konsole ist auch bash. Also gewöhn dir das mit sh bitte ab :(

  • Zitat


    Dein Python Script hat doch zuvor auch ein bash Script ausgeführt oder nicht? Also wieso kannste das jetzt hierfür nicht nutzen?


    Keine Ahnung. :D

    Das steht in der txt:

    Code
    uid=1000(xbian) gid=1000(xbian) groups=1000(xbian),5(tty),24(cdrom),27(sudo),29(audio),44(video),100(users),999(input)

    In meinem RunScript steht:

    Code
    <onclick>RunScript("/bin/bash /home/xbian/scripts/umountAll.sh")</onclick>


    Wieso wird es dann mit sh ausgeführt?

    Ist es so richtig ausgeführt?

    Code
    xbian@xbian ~/scripts $ bash umountAll.sh
    umountAll.sh: line 2: $'\r': command not found
    umountAll.sh: line 3: syntax error near unexpected token `$'do\r''
    'mountAll.sh: line 3: `for dev in $(ls /media/); do

    Das ich ein Script nicht mit sh ausführen soll, habe ich auch so nicht verstanden. Ich dachte als du sagtest, ich soll es mit bash machen, dass ich dann einfach

    Bash
    #!/bin/bash


    im Kopf des Scripts einfügen soll. Mich hat nie so richtig interessiert, was das eigentlich macht. Aber ich habe es jetzt begriffen. Das #! sagt dem Kommandointepreter, wie das Script gelesen werden soll und der Interpreter ist dann demnach sh oder eben bash.


  • Keine Ahnung. :D

    Das steht in der txt:

    Code
    uid=1000(xbian) gid=1000(xbian) groups=1000(xbian),5(tty),24(cdrom),27(sudo),29(audio),44(video),100(users),999(input)

    uid = user id = xbian
    gid = group id = xbian
    Und das andere sind halt die Gruppen in den der Benutzer is..

    Du musst also den Benutzer xbian in visudo mit aufnehmen, damit er auch ohne Password-Abfrage sudo verwenden kann/darf.

    In meinem RunScript steht:

    Code
    <onclick>RunScript("/bin/bash /home/xbian/scripts/umountAll.sh")</onclick>


    Wieso wird es dann mit sh ausgeführt?

    Nein, es wird So nicht mit sh ausgeführt. ".sh" ist nur die Dateiendung. Die Datei wird direkt an den Interpreter /bin/bash übergeben. Du hattest es aber manuell an sh übergeben...

    Ist es so richtig ausgeführt?

    Code
    xbian@xbian ~/scripts $ bash umountAll.sh
    umountAll.sh: line 2: $'\r': command not found
    umountAll.sh: line 3: syntax error near unexpected token `$'do\r''
    'mountAll.sh: line 3: `for dev in $(ls /media/); do

    Das sind andere Fehler.
    Wie hast du die Datei erstellt? Ich schätze mal unter Windows eine Datei erstellt und dann auf den PI übertragen, oder? Windows verwendet andere Zeilenumbrüche die Linux aber nicht versteht. Also entweder du verwendest ein Linux-kompatibles Dateiformat indem du zB notepad++ , Proton , oder UltraEdit verwendest - oder du erstellt die Datei direkt über Linux also nano /home/xbian/umountAll.sh und copy&pastest den Code da rein.. (vorher das vermurkste File löschen)

    Das ich ein Script nicht mit sh ausführen soll, habe ich auch so nicht verstanden. Ich dachte als du sagtest, ich soll es mit bash machen, dass ich dann einfach

    Bash
    #!/bin/bash


    im Kopf des Scripts einfügen soll. Mich hat nie so richtig interessiert, was das eigentlich macht. Aber ich habe es jetzt begriffen. Das #! sagt dem Kommandointepreter, wie das Script gelesen werden soll und der Interpreter ist dann demnach sh oder eben bash.

    Der Shebang wird nur beachtet wenn man die Datei direkt ausführt, ohne es an einen 'Verarbeiter' direkt zu übergeben
    also zB

    Code
    ./umountAll.sh

    oder

    Code
    /home/xbian/umountAll.sh

    ...erst dann wird der Shebang (falls vorhanden) beachtet.

  • Also wenn ich xbian sudo Rechte gebe, funktioniert auch

    Code
    <onclick>RunScript("/bin/bash /home/xbian/scripts/umountAll.sh")</onclick>


    ?

    Zitat

    Ich schätze mal unter Windows eine Datei erstellt und dann auf den PI übertragen, oder?


    Ja, aber mit Eclipse erstellt und dort ist Unix eingestellt, weil ich für meine anderen RPi c++ Programme schreibe. Scheinbar funktioniert das aber nicht für sh. :S Habe es dann mit notepad++ gemacht und damit geht es.

    Dabei kommt mir aber ein Gedanke. Bei mir in dem media Ordner sieht es doch so aus:

    Code
    A
    B
    C
    usb0
    usb1
    usb2


    Dein Script müsste doch alles außer usb0 umounten. Das heißt, wenn A usb0 ist, dann umounted er trotzdem A. Demnach müsste ich dein Script etwas anpassen oder?

    Eine Frage noch, könnte es auch ausprobieren aber wenn ich schonmal dabei bin: Wenn ich ein Leerzeichen in dem Verzeichnisnamen habe, also z.B. "Fotos 2015", dann muss ich, um in dieses Verzeichnis zu wechseln, cd Fotos\ 2015 eingeben.

    Sieht das dann in deinem Script so aus:

    Code
    behalten=Fotos\ 2015


    ?

    Einmal editiert, zuletzt von 3dmaxb00n (12. April 2015 um 09:14)

Jetzt mitmachen!

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