Hade en gång i tiden Windows. En av de jobbiga delarna med det var ju de löjliga enhetsbokstäverna. Kopplade jag in en USB-enhet kunde den dyka upp som E:\ eller F:\ eller vad som helst, olika varje gång. Det gick visserligen att permanent associera en viss enhet med en viss bokstav, men det kändes ju inte helt hundra ändå, så att säga.
Sedan kom EeePC med det absurda operativsystemet Xandros, där man också hade enhetsbokstäver, fast ännu sämre implementerat än i Windows. Absurt, som sagt.
Så med Ubuntu och de flesta and GNU/Linux-distributioner var ju allt frid och fröjd. Min USB-hårddisk Backup dök exempelvis upp som /media/Backup. Precis som det ska vara, inga fjanterier.
Nu, i och med Ubuntu 14.04 (jag använder bara LTS-versioner numera), har det flippat ut fullständigt. Just hårddiskar och sådant fungerar visserligen som tidigare, så där är allt fortfarande bra, men så kommer jag till min Nexus 4. I Ubuntu 12.04 dök den upp under ~/.gvfs/mtp. Lite otympligt, men det gick att hitta den och man behöver inte modifiera sina skript varje gång man monterar sin Nexus.
Nu, däremot, dyker den istället upp under /run/user/1000/gvfs/. Visst, vad är problemet? Bara ett annat ställe? Jo, så långt allt väl väl, men vad dyker den upp som? Ja, det vet man bara när det är för sent… Vi testar:
Okej, jag har redan pluggat in min Nexus. Det blev /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C006%5D denna gången.
Nu testar jag igen: Jag avmonterar, drar ur kabeln och sätter i den igen i samma USB-port. Nu blev namnet istället /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C007%5D
Visst går det med hjälp av lsusb, grep, awk och lite annat att lista ut vad namnet kommer att vara, men det känns ju väldigt onödigt.
Kan man komma runt detta på något sätt?
När det gäller andra enheter kan man ofta ge dem en ”label”, exempelvis min Backup ovan. Går det att göra så även med en Android-enhet? Om ja, skulle det hjälpa, så att jag i fortsättningen kan hitta min Nexus med exakt samma sökväg varje gång, exempelvis /run/user/1000/gvfs/mtp/Nexus4?
Ett sätt som jag kom på just nu, en fullösning, är ju i och för sig att skapa ett skript som startas vid montering (hur man nu triggar igång det på bästa sätt) som tar reda på monteringspunkten och lägger in sökvägen i en miljövariabel, men det känns inte kul…
Android-enhet via USB
- Johnny Rosenberg
- Inlägg: 1256
- Blev medlem: 23 jun 2007, 16:18
- OS: Ubuntu
- Utgåva: 22.10 Kinetic Kudu
- Kontakt:
- Johnny Rosenberg
- Inlägg: 1256
- Blev medlem: 23 jun 2007, 16:18
- OS: Ubuntu
- Utgåva: 22.10 Kinetic Kudu
- Kontakt:
Re: Android-enhet via USB, Udev, Bash-skript
Jag gjorde faktiskt en fullösning som fungerade rätt så bra, men kändes rätt så ful, som sagt:
Jag gjorde ett skript som startas när man loggar in. Skriptet kollar av USB-portarna efter min telefon och räknar ut sökvägen till densamma. Med hjälp av den skapar skriptet en länk till sökvägen, så alla skript som ska jobba mot telefonen behöver bara veta vad länken heter och var den ligger, och det är ju på samma ställe varje gång.
Skriptet gör en koll var tionde sekund, så när jag drar ur kabeln igen tar skriptet bort länken. Det tar även bort länken (om den finns) när man pluggar in telefonen, eftersom det kan finnas risk att en länk finns där med samma namn om jag exempelvis stängt av datorn utan att dra ur kabeln till telefonen först.
Dessutom kommer en liten ruta upp som talar om för mig att telefonen kopplats in när så skett och en annan som talar om att den kopplats ur, om så är fallet. Rutorna försvinner av sig själva efter 5 sekunder (jag använda Yad för detta).
Som sagt så funkade detta alldeles utmärkt. Nackdelen är ju att man har ett skript som ligger i bakgrunden och jobbar så länge datorn är på, eller i alla fall så länge man är inloggad (skriptet startas upp som ett ”Uppstartsprogram”).
Så jag började kika lite på det där med Udev och tänkte att det nog var en bättre idé. Jag plitade ihop en regel som skulle starta ett skript åt mig som fixar länken ifråga åt mig, men nu har ett problem uppstått:
Udev-regeln ser ut så här (jag har bytt telefon sedan jag skrev första gången, därav att det plötsligt står Nexus 6 och inte 4):
Regeln är placerad i filen /etc/udev/rules.d/10-local.rules.
/usr/local/bin/CreateLinkToPhone.sh ser ut så här:
Då kommer vi genast till mitt problem: När skriptet körs igång från Udev-regeln körs det inte av mig som användare, så alla mina vanliga miljövariabler saknas, såsom XDG_RUNTIME_DIR, USER och de andra. Visst kan man hårdkoda, men det känns ju som en sista lösning man tar till när allt annat är bevisat att vara 100 % omöjligt…
Telefonen kommer man ju åt via mappen ${XDG_RUNTIME_DIR}/gvfs/mtp:host=%5Busb%3A${BUSNUM}%2C${DEVNUM}%5D, där XDG_RUNTIME_DIR=”/run/user/1000”. BUSNUM brukar i regel vara 001 och DEVNUM är olika varje gång man pluggar in telefonen, exempelvis 021.
Eftersom XDG_RUNTIME_DIR inte är tillgänglig, måste jag alltså hårdkoda ”/run/user/1000”, vilket ju också gör att det inte fungerar om jag loggar in som någon annan, om jag inte gör en regel för varje användare.
Dessutom vill jag placera länken i ”/media”, men numera finns det ju en undermapp till den där sakerna brukar hamn, nämligen ”/media/${USER}”, alltså måste jag veta användarnamnet också.
Hur gör man vanligen för att åstadkomma detta? Jag har några idéer själv, men de flesta av dem är lite halvgalna.
En idé jag har är att man kör igång ett skript vid varje inloggning som sparar alla miljövariabler (eller i alla fall de man behöver) i en fil på något ställe där alla kan skriva och läsa, exempelvis ”/tmp” eller möjligen ”/var”. Därifrån kan skriptet sedan läsa vad det behöver veta. Men det känns som fusk…
Någon som har en bättre idé? Kan jag på något sätt ”importera” användarens miljövariabler till skriptet när det körs från Udev-regeln?
Jag gjorde ett skript som startas när man loggar in. Skriptet kollar av USB-portarna efter min telefon och räknar ut sökvägen till densamma. Med hjälp av den skapar skriptet en länk till sökvägen, så alla skript som ska jobba mot telefonen behöver bara veta vad länken heter och var den ligger, och det är ju på samma ställe varje gång.
Skriptet gör en koll var tionde sekund, så när jag drar ur kabeln igen tar skriptet bort länken. Det tar även bort länken (om den finns) när man pluggar in telefonen, eftersom det kan finnas risk att en länk finns där med samma namn om jag exempelvis stängt av datorn utan att dra ur kabeln till telefonen först.
Dessutom kommer en liten ruta upp som talar om för mig att telefonen kopplats in när så skett och en annan som talar om att den kopplats ur, om så är fallet. Rutorna försvinner av sig själva efter 5 sekunder (jag använda Yad för detta).
Som sagt så funkade detta alldeles utmärkt. Nackdelen är ju att man har ett skript som ligger i bakgrunden och jobbar så länge datorn är på, eller i alla fall så länge man är inloggad (skriptet startas upp som ett ”Uppstartsprogram”).
Så jag började kika lite på det där med Udev och tänkte att det nog var en bättre idé. Jag plitade ihop en regel som skulle starta ett skript åt mig som fixar länken ifråga åt mig, men nu har ett problem uppstått:
Udev-regeln ser ut så här (jag har bytt telefon sedan jag skrev första gången, därav att det plötsligt står Nexus 6 och inte 4):
Kod: Markera allt
ATTR{product}=="Nexus 6", ATTR{serial}=="BLABLABLABLA", SYMLINK+="Nexus_6", RUN+="/usr/local/bin/CreateLinkToPhone.sh"
/usr/local/bin/CreateLinkToPhone.sh ser ut så här:
Kod: Markera allt
#!/bin/bash
# Create a link to the connected phone in the ”/media/${USER}” directory.
# Variables ————————————————————————————————————————————————————————————————————
Media="/media/${USER}/"
LinkName="${Media}/${ID_MODEL}"
Target="${XDG_RUNTIME_DIR}/gvfs/mtp:host=%5Busb%3A${BUSNUM}%2C${DEVNUM}%5D"
# Main —————————————————————————————————————————————————————————————————————————
[[ -L ${LinkName} ]] && rm "${LinkName}"
if [[ ${ACTION} == "add" ]]; then
ln -s "${Target}" "${LinkName}"
fi
Telefonen kommer man ju åt via mappen ${XDG_RUNTIME_DIR}/gvfs/mtp:host=%5Busb%3A${BUSNUM}%2C${DEVNUM}%5D, där XDG_RUNTIME_DIR=”/run/user/1000”. BUSNUM brukar i regel vara 001 och DEVNUM är olika varje gång man pluggar in telefonen, exempelvis 021.
Eftersom XDG_RUNTIME_DIR inte är tillgänglig, måste jag alltså hårdkoda ”/run/user/1000”, vilket ju också gör att det inte fungerar om jag loggar in som någon annan, om jag inte gör en regel för varje användare.
Dessutom vill jag placera länken i ”/media”, men numera finns det ju en undermapp till den där sakerna brukar hamn, nämligen ”/media/${USER}”, alltså måste jag veta användarnamnet också.
Hur gör man vanligen för att åstadkomma detta? Jag har några idéer själv, men de flesta av dem är lite halvgalna.
En idé jag har är att man kör igång ett skript vid varje inloggning som sparar alla miljövariabler (eller i alla fall de man behöver) i en fil på något ställe där alla kan skriva och läsa, exempelvis ”/tmp” eller möjligen ”/var”. Därifrån kan skriptet sedan läsa vad det behöver veta. Men det känns som fusk…
Någon som har en bättre idé? Kan jag på något sätt ”importera” användarens miljövariabler till skriptet när det körs från Udev-regeln?
- Johnny Rosenberg
- Inlägg: 1256
- Blev medlem: 23 jun 2007, 16:18
- OS: Ubuntu
- Utgåva: 22.10 Kinetic Kudu
- Kontakt:
Re: Android-enhet via USB
Jag tror banne mig det löste sig…
En mängd problem dök upp på vägen, men till sist så…
Vad gäller udev-reglerna fick jag problem med att skriptet antingen inte drogs igång vid inkoppling eller urkoppling eller att det drogs igång två gånger vid urkoppling. Till sist valde jag att använda mig av två olika regler, en för in- och en för urkoppling. Inte så snyggt, men det fungerade bäst så.
Mina nuvarande regler ser ut så här:
Vad gäller skriptet var ju problemet att de vanliga miljövariablerna inte fanns tillgängliga eftersom skriptet inte körs av användaren utan av root. Detta löste jag lite fult genom att helt enkelt låta skriptet leta efter vilken användare som för tillfället har en mapp i /run/user. Naturligtvis inser jag att det kan finnas tillfällen när båda användarna (i mitt fall – vi är två stycken som använder datorn, men sällan samtidigt eftersom grafiken brukar krascha när man byter användare) är inne samtidigt, men det problemet åtgärdar jag den dagen då jag får problem med det.
Skriptet ser nu ut så här:
Jag tyckte det kunde vara trevligt med en loggfil också, som framgår av skriptet ovan, så jag behöll de raderna, även om de ursprungligen kom till i felsökningssyfte.
Loggfilen såg ut så här, när jag kopplat ur och i telefonen några gånger:
En sak jag inte testat ännu är att koppla in och ur telefonen när jag är inloggad på frugans konto. Det borde fungera, men man vet aldrig helt säkert förrän man testat…
Men än så länge har jag inte hittat någon som inte fungerar. Jag pluggar in min telefon och vips skapas en länk till telefonen enligt länknamnet ovan. Alla skript jag nu gör som ska leka med telefonen kan därmed använda sig av min länk och slipper räkna ut vad mappen heter där telefonen för tillfället befinner sig (en mapp som alltså heter olika varje gång man pluggar in den, i motsats till länken som skriptet skapar).
Jaha, så var det roliga slut. Vad ska jag sysselsätta mig med under resten av semestern, då?
En mängd problem dök upp på vägen, men till sist så…
Vad gäller udev-reglerna fick jag problem med att skriptet antingen inte drogs igång vid inkoppling eller urkoppling eller att det drogs igång två gånger vid urkoppling. Till sist valde jag att använda mig av två olika regler, en för in- och en för urkoppling. Inte så snyggt, men det fungerade bäst så.
Mina nuvarande regler ser ut så här:
Kod: Markera allt
ACTION=="add", ATTR{serial}="ZX1G428DSG", RUN+="/usr/local/bin/CreateLinkToPhone.sh"
ACTION=="remove", ENV{ID_SERIAL_SHORT}=="ZX1G428DSG", RUN+="/usr/local/bin/CreateLinkToPhone.sh"
Skriptet ser nu ut så här:
Kod: Markera allt
#!/bin/bash
# Create a link to the connected phone in the Media directory.
# Variables ————————————————————————————————————————————————————————————————————
# Calculate User and XDG_Runtime_Dir by searching for the phone.
Path="/run/user/"
XDG_Runtime_Dir=$(find "$Path" -maxdepth 1 -type d -regex "${Path}[0-9]+")
UserID=$(basename "${XDG_Runtime_Dir}")
User=$(getent passwd "${UserID}" | cut -d ':' -f1)
# Now just assign the right strings to all the other variables.
Media="/media/${User}"
LinkName="${Media}/${ID_MODEL}"
Target="${XDG_Runtime_Dir}/gvfs/mtp:host=%5Busb%3A${BUSNUM}%2C${DEVNUM}%5D"
LogFile="/var/log/CreateLinkToPhone"
# Main —————————————————————————————————————————————————————————————————————————
[[ -L ${LinkName} ]] && rm -f "${LinkName}"
if [[ ${ACTION} == "add" ]]; then
ln -s "${Target}" "${LinkName}"
fi
# For the log file:
printf "%s\n Händelse: %s\n Länknamn: %s\n" \
"$(date +'%F %T')" \
"${ACTION^}" \
"${LinkName}" >> "${LogFile}"
printf " Målmapp: %s\nAnvändare: %s (%s – %s)\n\n" \
"${Target}" \
$(getent passwd "${User}" | cut -d ':' -f 5 | cut -d ',' -f 1) \
"${UserID}" \
"${User}" >> "${LogFile}"
Loggfilen såg ut så här, när jag kopplat ur och i telefonen några gånger:
Kod: Markera allt
2015-08-04 20:46:26
Händelse: Remove
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C037%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 20:46:31
Händelse: Add
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C038%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 20:51:50
Händelse: Remove
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C038%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 20:51:53
Händelse: Add
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C039%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 21:19:18
Händelse: Remove
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C039%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 21:19:21
Händelse: Add
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C040%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 21:19:56
Händelse: Remove
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C040%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 21:20:01
Händelse: Add
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C041%5D
Användare: Johnny (1000 – guraknugen)
Men än så länge har jag inte hittat någon som inte fungerar. Jag pluggar in min telefon och vips skapas en länk till telefonen enligt länknamnet ovan. Alla skript jag nu gör som ska leka med telefonen kan därmed använda sig av min länk och slipper räkna ut vad mappen heter där telefonen för tillfället befinner sig (en mapp som alltså heter olika varje gång man pluggar in den, i motsats till länken som skriptet skapar).
Jaha, så var det roliga slut. Vad ska jag sysselsätta mig med under resten av semestern, då?

- Johnny Rosenberg
- Inlägg: 1256
- Blev medlem: 23 jun 2007, 16:18
- OS: Ubuntu
- Utgåva: 22.10 Kinetic Kudu
- Kontakt:
Re: Android-enhet via USB
Jag tror banne mig det löste sig…
En mängd problem dök upp på vägen, men till sist så…
Vad gäller udev-reglerna fick jag problem med att skriptet antingen inte drogs igång vid inkoppling eller urkoppling eller att det drogs igång två gånger vid urkoppling. Till sist valde jag att använda mig av två olika regler, en för in- och en för urkoppling. Inte så snyggt, men det fungerade bäst så.
Mina nuvarande regler ser ut så här:
Vad gäller skriptet var ju problemet att de vanliga miljövariablerna inte fanns tillgängliga eftersom skriptet inte körs av användaren utan av root. Detta löste jag lite fult genom att helt enkelt låta skriptet leta efter vilken användare som för tillfället har en mapp i /run/user. Naturligtvis inser jag att det kan finnas tillfällen när båda användarna (i mitt fall – vi är två stycken som använder datorn, men sällan samtidigt eftersom grafiken brukar krascha när man byter användare) är inne samtidigt, men det problemet åtgärdar jag den dagen då jag får problem med det.
Skriptet ser nu ut så här:
Jag tyckte det kunde vara trevligt med en loggfil också, som framgår av skriptet ovan, så jag behöll de raderna, även om de ursprungligen kom till i felsökningssyfte.
Loggfilen såg ut så här, när jag kopplat ur och i telefonen några gånger:
En sak jag inte testat ännu är att koppla in och ur telefonen när jag är inloggad på frugans konto. Det borde fungera, men man vet aldrig helt säkert förrän man testat…
Men än så länge har jag inte hittat någon som inte fungerar. Jag pluggar in min telefon och vips skapas en länk till telefonen enligt länknamnet ovan. Alla skript jag nu gör som ska leka med telefonen kan därmed använda sig av min länk och slipper räkna ut vad mappen heter där telefonen för tillfället befinner sig (en mapp som alltså heter olika varje gång man pluggar in den, i motsats till länken som skriptet skapar).
Jaha, så var det roliga slut. Vad ska jag sysselsätta mig med under resten av semestern, då?
En mängd problem dök upp på vägen, men till sist så…
Vad gäller udev-reglerna fick jag problem med att skriptet antingen inte drogs igång vid inkoppling eller urkoppling eller att det drogs igång två gånger vid urkoppling. Till sist valde jag att använda mig av två olika regler, en för in- och en för urkoppling. Inte så snyggt, men det fungerade bäst så.
Mina nuvarande regler ser ut så här:
Kod: Markera allt
ACTION=="add", ATTR{serial}="ZX1G428DSG", RUN+="/usr/local/bin/CreateLinkToPhone.sh"
ACTION=="remove", ENV{ID_SERIAL_SHORT}=="ZX1G428DSG", RUN+="/usr/local/bin/CreateLinkToPhone.sh"
Skriptet ser nu ut så här:
Kod: Markera allt
#!/bin/bash
# Create a link to the connected phone in the Media directory.
# Variables ————————————————————————————————————————————————————————————————————
# Calculate User and XDG_Runtime_Dir by searching for the phone.
Path="/run/user/"
XDG_Runtime_Dir=$(find "$Path" -maxdepth 1 -type d -regex "${Path}[0-9]+")
UserID=$(basename "${XDG_Runtime_Dir}")
User=$(getent passwd "${UserID}" | cut -d ':' -f1)
# Now just assign the right strings to all the other variables.
Media="/media/${User}"
LinkName="${Media}/${ID_MODEL}"
Target="${XDG_Runtime_Dir}/gvfs/mtp:host=%5Busb%3A${BUSNUM}%2C${DEVNUM}%5D"
LogFile="/var/log/CreateLinkToPhone"
# Main —————————————————————————————————————————————————————————————————————————
[[ -L ${LinkName} ]] && rm -f "${LinkName}"
if [[ ${ACTION} == "add" ]]; then
ln -s "${Target}" "${LinkName}"
fi
# For the log file:
printf "%s\n Händelse: %s\n Länknamn: %s\n" \
"$(date +'%F %T')" \
"${ACTION^}" \
"${LinkName}" >> "${LogFile}"
printf " Målmapp: %s\nAnvändare: %s (%s – %s)\n\n" \
"${Target}" \
$(getent passwd "${User}" | cut -d ':' -f 5 | cut -d ',' -f 1) \
"${UserID}" \
"${User}" >> "${LogFile}"
Loggfilen såg ut så här, när jag kopplat ur och i telefonen några gånger:
Kod: Markera allt
2015-08-04 20:46:26
Händelse: Remove
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C037%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 20:46:31
Händelse: Add
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C038%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 20:51:50
Händelse: Remove
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C038%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 20:51:53
Händelse: Add
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C039%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 21:19:18
Händelse: Remove
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C039%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 21:19:21
Händelse: Add
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C040%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 21:19:56
Händelse: Remove
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C040%5D
Användare: Johnny (1000 – guraknugen)
2015-08-04 21:20:01
Händelse: Add
Länknamn: /media/guraknugen/Nexus_6
Målmapp: /run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C041%5D
Användare: Johnny (1000 – guraknugen)
Men än så länge har jag inte hittat någon som inte fungerar. Jag pluggar in min telefon och vips skapas en länk till telefonen enligt länknamnet ovan. Alla skript jag nu gör som ska leka med telefonen kan därmed använda sig av min länk och slipper räkna ut vad mappen heter där telefonen för tillfället befinner sig (en mapp som alltså heter olika varje gång man pluggar in den, i motsats till länken som skriptet skapar).
Jaha, så var det roliga slut. Vad ska jag sysselsätta mig med under resten av semestern, då?
