Codebits - Sammlung kleiner Helferlein

Rain_Maker

Administrator
Teammitglied
In den letzten Monaten/Jahren hat sich auf meinem System in einer Datei namens "Codebits" einiges angesammelt, was einem den Alltag erleichtern kann.

Hierbei handelt es sich eigentlich nur um eine immer wieder ergänzte Textdatei, in der kurz ein paar Zeilen Code im Sinne einiger Befehle, einem Eintrag in irgendeiner Konfigurationsdatei o.ä. und ein kurzer Kommentar dazu niedergeschrieben wurden.

Das Ganze dient(e) als kleine Gedächtnisstütze oder kleines "Nachschlagewerk zum durchgreppen", wenn man wusste "da hatte ich doch mal etwas dazu aufgeschrieben", also eine Art "digitale Zettelsammlung".

Viele dieser Helferlein wurden durch recht langes Rumprobieren oder auch oft längere Onlinerecherche gefunden, der Aufwand des Findens war -wie so oft- deutlich größer als der Aufwand dann am Ende ein paar Zeilen in ein Skript oder eine Konfigurationsdatei zu schreiben.

Vor allem wegen des oben genannten oft langen Suchens, bis man die passende Lösung gefunden hatte, besteht der wirkliche Wert dieser kleinen Zettelsammlung darin, daß man versucht sich möglichst viel Mühe bei den Kommentaren zu geben, damit man in diesem Fall offline (und meist mit grep :)) schnell findet, was man gesucht hat.

In diesem Thread soll diese Zettelsammlung Schritt für Schritt online gestellt werden, dabei sind natürlich auch alle Nutzer des Forums dazu eingeladen ihre "Codebits" zu veröffentlichen.

Es geht hier _nicht_ darum irgendwelche "deppensicheren" Tutorials in epischer Länge und Breite zu schreiben, sondern um kurze Tipps/Anregungen, die jemand, der etwas Ahnung von der Materie hoffentlich dann beim Benutzen einer Suchmaschine mit sinnvollen Suchbegriffen finden kann.

Wichtig sind also neben den "Codebits" selbst, daß man als Ersteller versucht möglichst mit sinnvollen Schlagworten, die dann logischerweise von Suchmaschinen mit gespidert werden, den Eintrag zu ergänzen und ihn gut auffindbar zu machen.

Es gilt also, "weniger ist mehr".

Greetz,

RM
 

Rain_Maker

Administrator
Teammitglied
Huawei GPRS UMTS HSDPA HSUPA Modem - Roaming abschalten AT-Kommando

Das Roaming-Feature bei Verbindungen über ein Mobilfunknetzwerk ist zwar vielleicht in manchen Situationen praktisch, kann aber ganz schön teuer werden.

Allgemein sprechen auch GSM/UMTS/HSDPA/HSUPA-Modems immer noch den guten, alten AT-Komnmandosatz

AT-Befehlssatz

der einfach nur um mobilfunkspezifische Kommandos (z.B. für GSM) erweitert wurde (Suchmaschine verrät mehr).

Bei Geräten von Huawei -und es scheint sich hier um ein Herstellerspezifisches Kommando zu handeln, Geräte anderer Hersteller werden mit diesem Befehl möglicherweise keine Reaktion zeigen!- kann man mittels des Kommandos "AT^SYSCFG"+Optionen Einstellungen auslesen und ändern (z.B. mit einem seriellen Terminal wie minicom).

Beispiel:

a) Hardware

Code:
Bus 002 Device 005: ID 12d1:1003 Huawei Technologies Co., Ltd. E220 HSDPA Modem / E230/E270 HSDPA/HSUPA Modem
b) Treiber:

option.ko

c) Devices:

/dev/ttyUSB0 # eigentliches Modemgerät für Aufbau von Verbindungen

/dev/ttyUSB1 # Kommandokanal zum Absetzen/Empfangen von AT-Kommandos

d) Auslesen (z.B. über minicom)

Code:
AT^SYSCFG
^SYSCFG:2,0,3FFFFFFF,1,2
e) Bedeutung (ohne Gewähr für die ganzen anderen Felder)

Code:
# AT^SYSCFG für Huawei

AT^SYSCFG=$mode,$acqOrder,$band,$roam,$srvDomain

 $mode
 2=Auto-Select
 13=GSM only
 14=WCDMA only
 16=no Change

 $acqOrder
 0=Automatic
 1=GSM prefered
 2=WCDMA prefered
 3=no Change

 $band
 3fffffff = All
 Rest siehe "AT^SYSCFG=?"

 $roam
 0=Not Supported
 1=Supported
 2=no Change

 $srvDomain
 0=Circuit-Switched only
 1=Packet-Switched only
 2=Circuit- & Packet-Switched
 3=Any
 4=no Change
f) Roaming aus und Rest unverändert lassen

Code:
AT^SYSCFG=16,3,3FFFFFFF,0,4
g) neue Ausgabe

Code:
AT^SYSCFG?                                                        
^SYSCFG:2,0,3FFFFFFF,[B]0[/B],2
h) Alle Optionen des Befehls ansehen

Code:
AT^SYSCFG=?
i) Einbau in ein entsprechendes (pre-up) Script

Code:
echo -e "AT^SYSCFG=16,3,3FFFFFFF,0,4\r" > <Kommandokanal> # z.B. /dev/ttyUSB1
 

Rain_Maker

Administrator
Teammitglied
wvdial - Einwahl als unprivilegierter Nutzer

Ein Praktisches Tool zur Einwahl über ein (GSM-)Modem ist wvdial.

Es kann als eigentlicher Dialer oder als Ersatz für "chat" beim Aufruf von pppd verwendet werden (wer mehr wissen will => STFW) und ist mittlerweile auch bei vielen Distributionen für diese Zwecke im Einsatz.

Wer weder NetworkManager oder die entsprechende ifup-Implementierung der Distribution nutzen will, kann auch direkt wvdial zur Einwahl auf der Kommandozeile verwenden.

Die Einrichtung von wvdial bzw. /etc/wvdial.conf will ich hier nicht besprechen, dazu findet sich genügend im Netz und RTFM (man wvdial, man wvdial.conf) hilft auch weiter.

Einziger Haken an der Geschichte, per default kann ein eingeschränkter Nutzer keine Einwahl vornehmen, was an zwei Punkten hängt.

1) pppd muss als root gestartet werden

Das lässt sich recht einfach lösen, wobei man natürlich argumentieren kann, daß SUID root ein potentielles Sicherheitsproblem ist, allerdings dürfte man dann auch z.B. umtsmon nicht verwenden, denn der macht das genau so, während bestimmte wrapper (smpppd/cinternet/kinternet) anhand von zuvor gegebenen Zugriffsrechten (Gruppenzugehörigkeit bzw. PolicyKit) einem User die Berechtigung geben sich einzuwählen und dann ebenfalls pppd als root starten, denn ohne diese Rechte geht es nicht.

Eine IMHO passable Lösung stellen folgende Berechtigungen dar (unter openSUSE, andere Distributionen mögen eine andere Gruppe für pppd setzen).

Code:
ls -l /usr/sbin/pppd
-rwsr-x--- 1 root [B]dialout[/B] 370896 19. Feb 06:22 /usr/sbin/pppd
Prinzipiell also "wie gehabt", wer in der Gruppe "dialout" ist, darf pppd mit SUID root starten.

Unter openSUSE löst man das z.B. mit einer "permissions"-Datei

Code:
cat [B]/etc/permissions.d/mobile_broadband[/B] 
/usr/sbin/pppd			root:dialout		4750

su -c "SuSEconfig --module permissions"
Starting SuSEconfig, the SuSE Configuration Tool...
Running module permissions only
Reading /etc/sysconfig and updating the system...
Executing /sbin/conf.d/SuSEconfig.permissions...
Checking permissions and ownerships - using the permissions files
	/etc/permissions
	/etc/permissions.secure
	/etc/permissions.d/mobile_broadband
	/etc/permissions.local
setting /usr/sbin/pppd to root:dialout 4750. (wrong permissions 0755)
Finished.
2) Selbst wenn man als Nutzer in der Gruppe "dialout" ist, weigert sich wvdial immer noch

Code:
 wvdial
--> WvDial: Internet dialer version 1.61
--> Cannot open /dev/ttyUSB0: Device or resource busy
--> Cannot open /dev/ttyUSB0: Device or resource busy
--> Cannot open /dev/ttyUSB0: Device or resource busy
Die Fehlermeldung ist ziemlich irreführend, denn die Zugriffsrechte sind eigentlich OK.

Code:
ls -l /dev/ttyUSB*
crw-rw---- 1 root dialout 188, 0 19. Jun 11:59 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1 19. Jun 17:15 /dev/ttyUSB1
und "busy" ist das Gerät auch nicht, sonst würde es als root nicht funktionieren.

Des Rätsels Lösung findet man z.B. mittels strace oder (einiger) Sucherei im Netz, wvdial legt eine Datei "LCK..<Devicename>" in /var/lock/ an:

Code:
ls -l /var/lock/*tty*
-rw-r--r-- 1 root root 11 19. Jun 11:59 /var/lock/LCK..ttyUSB0
aber der "normale" Nutzer hat auf dieses Verzeichnis keine Schreibrechte.

Code:
ls -l /var/
................
drwxrwxr-t  8 root lock 4096 19. Jun 17:51 lock
................
Bei openSUSE 11.4 sehen die Rechte so aus, ältere Versionen haben die Gruppe "uucp", bei anderen Distributionen => selbst nachsehen.

Nach hinzufügen des entsprechenden Nutzers zu den Gruppen "dialout" und "lock" (bzw. "uucp") funktioniert dann auch die Einwahl als unprivilegierter Nutzer.

Ich möchte allerdings betonen, daß man sich genau überlegen sollte, in wie weit man einem Nutzer bestimmte Rechte geben möchte und vor allem wie man diese neuen Rechte auch möglichst auf das Allernötigste einschränken kann.
 

Rain_Maker

Administrator
Teammitglied
Yet Another "what's my external ip" Script

Kurz und knackig.

Code:
#!/bin/bash
# echo $(date) |tr '\n' ' '
# echo External IP: $(curl -s http://checkip.dyndns.org/ | sed 's/\([a-z,A-Z,\ ,\<,\>,\/,\:,\-]\)//g')
# echo $(date) |tr '\n' ' '
# echo External IP: $(curl -s http://checkip.dyndns.org/ | sed 's/[a-zA-Z<>/ :]//g')
# echo $(date) |tr '\n' ' '
# echo External IP: $(wget -q -O - http://checkip.dyndns.org/ | sed  's/\([a-z,A-Z,\ ,\<,\>,\/,\:,\-]\)//g')
case $1 in 
	-ip|-i|--ip)
	echo $(wget -q -O - http://checkip.dyndns.org/ | sed 's/[a-zA-Z<>/ :]//g')
	;;
	-h|-help|--help)
	echo "${0##*/} -i|-ip|--ip - show external IP only"
	echo 
	echo "${0##*/} -h|-help|--help - show this help message"
	echo 
	echo "If called without any extra arguments, ${0##*/} will show"
	echo "external IP and actual date+time"
	;;
	*)
	echo $(date) |tr '\n' ' '
	echo External IP: $(wget -q -O - http://checkip.dyndns.org/ | sed 's/[a-zA-Z<>/ :]//g')
	;;
esac

exit 0
(In den Kommentaren finden sich Alternativen der Abfrage.)
 

Rain_Maker

Administrator
Teammitglied
udev - Modul beim Ein-/Ausstecken eines externen Gerätes laden/entladen

Das Laden eines bestimmten (geeigneten) Kernelmoduls beim Einstecken eines externen Gerätes (z.B. USB-Stöpsel) sollte eigentlich -udev sei dank- automatisch geschehen, aber ggf. kann man hier auch nachhelfen.

Die wirkliche Übung ist das Entladen des Moduls beim Entfernen des entsprechenden Gerätes, was normalerweise nicht automatisch geschieht und auch eigentlich ein sinnvolles Standardverhalten ist, da es ja z.B. sein könnte, daß es noch weitere Geräte im System gibt, die das selbe Kernelmodul verwenden und man nicht allen anderen Geräten beim Ausstecken "den Boden unter den Füßen" wegziehen will.

Aber da wir hier ja wissen, was wir tun ....... (und wer es nicht weiß, der sollte im Zweifelsfall eben die Finger von solchen kleinen Tricks lassen!).

Code:
# Laden von <Modul> beim Einstecken eines Gerätes, Erkennung an DeviceID und VendorID
ACTION=="add", ATTRS{idVendor}=="Numerische_VendorID", ATTRS{idProduct}=="Numerische_ProductID", RUN+="bin/sh -c '/sbin/modprobe Modulname -Optionen'"

# Entladen beim Ausstöpseln
ACTION=="remove", ATTRS{idVendor}=="Numerische_VendorID", ATTRS{idProduct}=="Numerische_ProductID", RUN+="bin/sh -c '/sbin/modprobe Modulname -r'"

# Oder etwas  eleganter mit der udev-Umgebungsvariablen "REMOVE_CMD":
ENV{REMOVE_CMD}="/bin/sh -c '/sbin/modprobe Modulname -r'"
Der RUN+="/bin/sh -c '/Pfad/Kommando'"-Konstrukt statt direkt das Kommando mit RUN+="/Pfad/Kommando" einzugeben ermöglicht es auch mehrere Befehle nacheinander auszuführen.

Wichtige Grundregel für RUN+= oder PROGRAM+= beim Schreiben von udev-Regel:

IMMER absolute, vollständige Pfade verwenden!
 

Rain_Maker

Administrator
Teammitglied
ffmpeg: Teile eines Streams extrahieren/umwandeln

Gegeben: Video mit Audio (AVC/AAC aLs ".mp4")

Gesucht: Nur die Audiospur und davon nur ein Teil, den bitte von Stereo auf Mono mit geringerer Bitrate und in ein freies Format umgewandelt (OGG-Vorbis als .oga)

Code:
ffmpeg -i EINGABEDATEI.mp4 -vn -c:a libvorbis -b:a 48k -ac 1 -f ogg -ss hh:mm:ss -t hh:mm:ss AUSGABEDATEI.oga
-vn: Kein Video

-c:a: libvorbis (welches Audiocodec wird verwendet, siehe "ffmpeg -encoders")

-b:a: Audiobitrate (hier 48k, was für Mono ausreichend ist)

-ac 1: Anzahl der Audiokanäle (1 = "mono")

-f ogg: Das Ganze in einen OGG-Container packen (da ich .oga als Suffix will, ist das hier nötig, wer .ogg als Suffix verwendet, kann das AFAIK hier zumindest weglassen)

-ss: Startzeit der Transkodierung (alles davor wird ignoriert)

-t: Wieviel soll anschliessend kodiert werden? Also _NICHT_ "bis wohin im Stream"

Beispiel:

Wenn ich also von von einer Eingabedatei die ersten 10 Minuten 3 Sekunden wegschneiden und danach bis zum Zeitpunkt "50 Minuten 7 Sekunden" im Originalstream umwandeln will, dann sieht das so aus:

Code:
-ss 00:10:03 -t 00:40:04
(etwas Kopfrechnen schadet ja nicht, oder?)

Greetz,

RM
 
Oben