Users4Users : Die besten NICHT-geheimen "Shell-Tricks" der Linux-User

Rain_Maker

Administrator
Teammitglied
ffmpeg: Basics (Audio)

Das Tool "ffmpeg" kann man mit Fug und Recht als "Schweizer Taschenmesser für Datenumwandlung im Bereich Multimedia" bezeichnen.

Es handelt sich um einen sehr schnellen und sehr mächtigen (und damit auch teilweise mächtig kryptischen) Enkodierer/Dekodierer für die Kommandozeile, der so ziemlich alles aus dem Bereich Multimediadateien in so ziemlich alles Andere umwandeln kann.

Die Installation von ffmpeg sollte über den Paketmanager erfolgen, aufgrund lizenzrechtlicher Gründe findet man in einigen Distributionen das entsprechende Paket nicht in den offiziellen Repositories der jeweiligen Distribution.

So bietet z.B. für openSUSE das Packmanprojekt entsprechende Pakete an, für Fedora schaut man sich am besten bei rpmfusion.org um, aber wie man eventuell benötigte Paketquellen einbindet und ffmpeg installiert, soll hier aber nicht Gegenstand des Beitrags sein, hierzu konsultiere man die Dokumentation seiner Distribution.

Die Grundsyntax von ffmpeg ist eigentlich recht simpel,

Code:
ffmpeg -i <Quelldatei> [Optionen] <Ausgabedatei>
wobei es eben eine riesige Fülle an diversen Parametern gibt, mit welchen sich Dateiformate, Containerformate, Codecs, Bitraten, etc. pp. sehr fein einstellen lassen.

Das eigentliche Hauptgebiet für ffmpeg ist die Umwandlung von Videodateien, aber das bedeutet nicht, daß man dieses Werkzeug nicht zur Konvertierung von reinen Audiodateien verwenden kann, im Gegenteil, gerade durch die große Anzahl von Ein- und Ausgabeformaten, stellt ffmpeg hier oft die schnellste Lösung dar, da viele Tools wie z.B. lame (MP3). oggenc (OGG-vorbis), flac (FLAC) oder opusenc (OGG-Opus) gewisse Einschränkungen in Bezug auf das Format der Eingabedatei besitzen.
So ist es z.B. nicht möglich eine .mp3 mittels oggenc direkt in eine OGG-Vorbis Datei umzuwandeln, da oggenc keine mp3 dekodieren kann und man so einen Zwischenschritt benötigt, der zuerst die .mp3 in eine WAVE-Datei umwandelt (*.wav) um diese dann mittels oggenc zum Zielformat konvertieren zu können.

Da die Anzahl der Parameter für die Konvertierung von Audiodateien meist geringer als beim Umwandeln von Videos ist, will ich hier mit ein paar entsprechenden Beispielen beginnen, auch um der/den geneigten Leser(in) Beispiele zu liefern, die noch einigermaßen übersichtlich sind.

Mit ffmpeg ist das Ganze in einem Schritt zu erledigen:

Code:
ffmpeg -i QUELLDATEI.mp3 -vn -c:a libvorbis ZIELDATEI.ogg
Bedeutung der Parameter:

- i (Eingabedatei)

-vn (keine Videospur codieren, hier unnötig, da mp3 kein Video enthalten kann, bei anderen Dateiformaten durchaus wichtig, eine ".ogg" kann sowohl Video als auch Audiodatei sein)

-c:a (Codec für Audio, äquivalent kann auch "-acodec" verwendet werden. Dabei muss man den genauen Namen der Codecs kennen, hier hilft z.B. der Befehl "ffmpeg -encoders")

Nun ist dieses Beispiel eher zu simpel, eine oft gewollte Funktion ist das Kodieren mit einer bestimmten Bitrate/Qualität.

Hier nun ein Beispiel, welches aus meiner Alltagspraxis stammt, da ich öfters Podcasts höre, welche nur in einem proprietären Format und mit IMHO viel zu hoher Bitrate angeboten werden, denn selbst für ein Gespräch mit mehreren Personen brauche ich keine 128KBit MP3-Datei, oft kann man sogar auf Stereo verzichten.

Code:
fmpeg -i QUELLDATEI.mp3 -vn -c:a libvorbis -b:a 64k -f ogg ZIELDATEI.oga
Was bedeuten die neuen Parameter?

- b:a (Bitrate für Audio, 64 KBit reichen für Sprache dicke aus)

-f ogg (Explizite Angabe des Containerformates, sonst beschwert sich ggf. ffmpeg, wenn es anhand der Dateiendung (man beachte, "oga" statt "ogg") keine eindeutige Zuordnung machen kann)

Das Ganze jetzt noch als 56 KBit ogg-Datei mit nur einem Audiokanal ("Mono"):

Code:
fmpeg -i QUELLDATEI.mp3 -vn -c:a libvorbis -b:a 56k -ac 1 -f ogg ZIELDATEI.oga
Parameter:

-ac 1 (Audio Channels 1, also nur ein einziger Audiokanal, vulgo "Mono")

Wer z.B. einen tragbaren Mediaplayer besitzt, auf welchem sich Rockbox installieren lässt, kann sich auch seine Hörbücher/Podcasts im neuen Ogg-OPUS Format kodieren, welches sich besonders gut für niedrige Bitraten und Sprache eignet und mittlerweile als offizieller, freier Standard für Audio in HTML5 festgelegt wurde.

Code:
fmpeg -i QUELLDATEI.mp3 -vn -c:a libopus -b:a 48k -ac 1 ZIELDATEI.opus
Wer etwas mutiger ist, kann auch mal "-b:a 32k" versuchen und sich von der (meist) noch erstaunlich guten Qualität überraschen lassen.

Wie oben angemerkt, ist die Option "-vn" bei einer mp3-Datei als Quelle nicht zwingend notwendig, da .mp3 kein Video enthalten kann, aber es gibt durchaus einen recht häufig in diversen Foren angefragten Anwendungsfall, bei welchem diese Option mit die Wichtigste ist.

Die typische Frage in diversen Foren lautet in etwa so:

Wie extrahiert man die Audiospur aus einer Videodatei (und wandelt sie ggf. in $GEWÜNSCHTES_AUDIOFORMAT um)?

Mit ffmpeg ist das Ganze ein Kinderspiel.

Code:
ffmpeg -i <VIDEODATEI.DATEIENDUNG> -vn -c:a NAME_DES_ENCODERS -b:a GEWÜNSCHTE_BITRATE -f GEWÜNSCHTER_ZIELCONTAINER <AUDIODATEI.DATEIENDUNG>
Je nach Quelldatei macht es ab und zu keinen Sinn neu zu kodieren, hat man z.B. ein OGG-Theora-Video (*.ogg oder *.ogv) und will die Audiospur als OGG-Vorbis Audio (*.oga oder *.ogg) extrahieren, dann reicht ein einfaches "Herausschnibbeln" der Audiospur ohne erneut zu kodieren, denn der Standard für OGG-Videos sieht für die Audiospur (zwingend?) die Verwendung von OGG-Vorbis als Codec vor.

Hierzu gibt es einen speziellen Wert für die Wahl des Audiocodecs.

Code:
ffmpeg -i <VIDEO.ogg> -vn -c:a copy -f ogg AUDIO.ogg
Das "copy" ist eigentlich selbsterklärend, es werden sowohl Audiocodec als auch Audiobitrate genau so übernommen und nur die Audiospur extrahiert, was dann übrigens im Vergleich zum Umkodieren entsprechend schneller von Statten geht.

Um entscheiden zu können, wann/ob sich das Umkodieren lohnt, wäre nun ein Werkzeug praktisch, mit welchem man Informationen über eine Multimediadatei erhalten kann.

Hierzu liefert ffmpeg das Tool "ffprobe" mit, die Syntax ist dabei sehr simpel:

Code:
ffprobe <DATEI>
Und als abschließender Tipp; welche Dateiformate ffmpeg lesen kann, sagt einem übrigens (analog zum Befehl zur Ermittlung der unterstützten Formate für das Ziel) "ffmpeg -decoders".

Greetz,

RM
 

Rain_Maker

Administrator
Teammitglied
ffmpeg: Mehrere Dateien des selben (sic!) Formats aneinanderhängen ("concat" demuxer)

Mit ffmpeg kann man auch sehr einfach mehrere Dateien des selben Formats (gleiche Codecs!) zu einer Datei verbinden.

Ich möchte es nun noch ein drittes Mal betonen, das Ganze klappt nur dann, wenn alle Quelldateien die selben Codecs verwenden, also z.B. mehrere mp3-Dateien zusammengefügt werden sollen.

Es ist durchaus auch möglich mehrere Dateien unterschiedlichen Formats zusammen zu fügen, dann wird es aber sehr viel komplexer (vielleicht in einem späteren Post, für Neugierige, siehe hier).

Seit ffmpeg 1.1 kann der sog. "concat" Demuxer verwendet werden, das Ganze ist dann recht simpel:

Code:
ffmpeg -i "concat:DATEI1.mp3|DATEI2.mpg|DATEI3.mpg" -vn -c:a copy ZIELDATEI.mp3
Oder das Ganze gleich noch mit Umkodieren in eine platzsparende OGG-Opus Datei (48 KBit/s) gefällig?

Code:
ffmpeg -i "concat:DATEI1.mp3|DATEI2.mpg|DATEI3.mpg" -vn -c:a libopus  -b:a 48k ZIELDATEI.mp3
Hier soll es nur um die Basics gehen, ein etwas komplexeres Beispiel sei nur kurz erwähnt und verlinkt.

Bei vielen Eingabedateien wird das Getippe dann doch etwas mühsam, hier kann man mit einer Dateiliste oder Schleifen arbeiten, wie auf folgender Seite beschrieben:

https://trac.ffmpeg.org/wiki/Concatenate

Greetz,

RM
 

Rain_Maker

Administrator
Teammitglied
Zeitgesteuerte Aufgaben mit systemd nur bei aktiver Netzwerkverbindung starten

Der folgende, kleine Beitrag soll ein wenig die Möglichkeiten von systemd beleuchten, die über die Standardaufgaben eines init-Systems gehen.

Aufgabenstellung:

- Eine bestimmte Aktion soll

a) direkt nach Herstellen einer Netzwerkverbindung

b) anschließend in regelmäßigen Abständen

und

c) nach Trennen der Verbindung nicht mehr weiter

ausgeführt werden.

Zusammen gefasst also eine kleine Mischung aus Pre-/Post-|Up/Down Scripten und Cronjob, allerdings eben mit systemd als Unterbau.

Als Beispiel habe ich mir dazu die Synchronisation der Systemzeit über einen Zeitserver ausgesucht, da

a) diese Aufgabe perfekt auf die obigen Anforderungen passt (NTP-Synchronisation ohne Netzwerk macht keinen Sinn und mit Netzwerkverbindung sollte es regelmäßige Updates geben)

b) ich mit der Implementierung von NTP in YaST nie so ganz zufrieden war (siehe auch diverse Beiträge in diversen Foren, die gerne mal über lange Bootzeiten etc. klagen).

Zunächst brauchen wir zwei Dateien für systemd, eine ".service" und eine ".timer", am besten mit gleichem Präfix.

/etc/systemd/system/sntp-timesync.service

Code:
[Unit]
Description=Update time from time server
After=network.target network.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c '/usr/sbin/sntp -t 10 -s ptbtime1.ptb.de || :'
Kurze Erklärung zum Inhalt (siehe auch "man systemd.service" und "man systemd.unit")

Description= (selbsterklärend)

After= (wird erst NACH den hier genannten Diensten/Targets ausgeführt)

Type=oneshot (für einen einzelnen Befehl/ein Script meist eine gute Wahl, auch hier siehe "man systemd.service")

ExecStart= (auszuführende Aktion)

Diese Datei führt die eigentliche Synchronisation durch, die Zeile in "ExecStart" enthält dabei einen kleinen Hack, das "|| :" am Ende sorgt dafür, daß der Aufruf auch bei nicht erfolgreicher Synchronisation mit dem Status "erfolgreich" beendet wird, das ist aber eher Kosmetik, wen eventuelle Meldungen, der Dienst sei fehlerhaft beendet worden, nicht stören, kann das weglassen, dann sieht das so aus:

Code:
[Unit]
Description=Update time from time server
After=network.target network.service

[Service]
Type=oneshot
ExecStart=/usr/sbin/sntp -t 10 -s ptbtime1.ptb.de
Da es dann nur um einen Befehl geht, kann der Trick mit dem Aufruf über eine eigene Subshell (/bin/sh -c 'BEFEHLE') wegfallen, des weiteren kann man in beiden Fällen statt mit "-s" auch mit "-j" als Parameter für sntp spielen, der Timeout mit "-t 10" liegt bei maximal 10 Sekunden, auch hier kann man ein wenig spielen (siehe "man sntp").

Natürlich kann man auch einen anderen Zeitserver als "ptbtime1.ptb.de" verwenden, eine Liste von Kandidaten findet man unter openSUSE in der Datei "/usr/share/YaST2/data/ntp_servers.yml", sofern "yast2-ntp-client" installiert ist, ansonsten hilft die Suchmaschine des geringsten Misstrauens sicher weiter.

Die dazu gehörige .timer-Datei sieht in etwa so aus:

/etc/systemd/system/sntp-timesync.timer

Code:
[Unit]
Description=Scheduled NTP sync
DefaultDependencies=no
Before=shutdown.target

[Timer]
OnActiveSec=5s
OnUnitActiveSec=15min

[Install]
WantedBy=timers.target
Da die beiden Dateien (.service/.timer) den selben Präfix "sntp-timesync" tragen, reicht das aus, hat man eine ".timer"-Datei, deren Dateiname nicht zur .service-Datei "passt", dann kann man sie um folgende Zeile erweitern:

Code:
[Unit]
Description=Scheduled NTP sync
DefaultDependencies=no
Before=shutdown.target

[Timer]
OnActiveSec=5s
OnUnitActiveSec=15min
Unit=sntp-timesync.service

[Install]
WantedBy=timers.target
Man gibt also den Namen der damit verknüpften .service-Datei explizit an.

Kurze Erläuterung zu den gesetzten Werten in der .timer-Datei

Description= (selbsterklärend)

EDIT:

Da nutzt man den Kram testweise eine Woche und alles geht glatt, aber kaum postet man das in ein Forum, gibt es kurz darauf zum ersten Mal Ärger damit. *grml*

Ohne die beiden nächsten Parameter bleibt in wenigen Fällen (ifup, Startmode ifplugd/auto, Kiste hängt aber nicht am Netz und ein Interface "baumelt" ohne aktive Verbindung in der Luft) das System beim Herunterfahren stecken, deshalb die beiden Parameter:

DefaultDependencies=no (das ist mehr zur Sicherheit, damit nicht $ANDERER_DIENST auf das Beenden des Timers warten muss)

Before=shutdown.target (Dienst _UNBEDINGT_ vor dem Shutdown stoppen, dann geht alles glatt)

EDIT Ende

OnActiveSec=5s (Nach Aktivieren des Timers durch systemd wird 5 Sekunden gewartet und dann der damit verknüpfte Dienst (sntp-timesync.service) gestartet)

OnUnitActiveSec=15min (Nach Aktivieren des Timers durch systemd wird alle 15 Minuten der damit verknüpfte Dienst (sntp-timesync.service) gestartet)

Der Teil mit

Code:
[Install]
WantedBy=timers.target
ist hier eigentlich unnötig, da der Dienst nur bei Bedarf aktiviert werden soll (nach Aufbau einer Netzwerkverbindung).

Wer allerdings den obigen Dienst immer laufen lassen kann ("Standleitung" anyone?) und sich die weiteren Schritte ersparen will, der kann mit diesem Eintrag den Dienst mittels "systemctl enable sntp-timesync.timer && systemctl start sntp-timesync.timer" dauerhaft aktivieren und starten (ohne "Install"-Sektion ginge das nicht).

Unter openSUSE legen wir nun ein Script unter /etc/sysconfig/network/scripts ab, welches nach Aufbau und Abbau einer Netzwerkverbindung die Dienste startet oder stoppt.

/etc/sysconfig/network/scripts/sntp-timer

Code:
#!/bin/bash
#

case "$0" in
        *scripts/sntp-timer)
                case $1 in
                start)
                        /usr/bin/systemctl start sntp-timesync.timer
                ;;
                stop)
                        /usr/bin/systemctl stop sntp-timesync.timer
                ;;
                status)
                        /usr/bin/systemctl status sntp-timesync.timer
                ;;
                restart)
                        /usr/bin/systemctl restart sntp-timesync.timer
                ;;
                try-restart)
                        /usr/bin/systemctl try-restart sntp-timesync.timer
                ;;
                *) 
                        echo "don't know what to do" >&2 ;;
                esac
        ;;
        #
        # ifup /etc/sysconfig/network/if-{up,down}.d/ script part;
        # start or stop sntp-timesync.timer
        #
        (*if-up.d*)
                /usr/bin/systemctl start sntp-timesync.timer
        ;;
        (*if-down.d*)
                /usr/bin/systemctl stop sntp-timesync.timer
        ;;
        *) echo "don't know what to do" >&2 ;;
esac
Wie das für $ANDERE_DISTRO geeignet ist, entnehme man der Dokumentation der entsprechenden Distro, das im weiteren Verlauf beschriebene Einbinden bei der Verwendung von NetworkManager dürfte hingegen distrounabhängig sein.

- Einbindung in die klassische Methode mit ifup (openSUSE)

Code:
su -

(Passwort eingeben)

ln -sf ..scripts/sntp-timer /etc/sysconfig/network/if-up.d/

ln -sf ../scripts/sntp-timer /etc/sysconfig/network/if-down.d/
und das war es dann auch schon.

- Einbinden in NetworkManager

Hier verwenden wir den "dispatcher"-Mechanismus von NetworkManager

/etc/NetworkManager/dispatcher.d/sntp-timesync

Code:
#! /bin/sh
#

case "$2" in
        up)
                /etc/sysconfig/network/scripts/sntp-timer start
                exit 0
                ;;
        down)
                /etc/sysconfig/network/scripts/sntp-timer stop
                exit 0
                ;;
        *)
                exit 0
                ;;
esac
Logischerweise ist der Pfad "/etc/sysconfig/network/scripts" bei anderen Distros ggf. anzupassen.

Wer prüfen will, ob das Ganze klappt, der kann in einem Terminal

Code:
watch -n1 "systemctl status sntp-timesync.service sntp-timesync.timer"
eingeben und dann die Ausgabe beobachten, während man munter Netzwerkverbindungen aufbaut/trennt.

Greetz,

RM
 

Rain_Maker

Administrator
Teammitglied
Zwei kurze Tipps zu Flash und/oder HTML5

Disclaimer: Flash ist eine digitale Seuche und man sollte sie so oft wie möglich vermeiden, bis sie dann endlich vollständig ausgerottet ist.

Tipp 1: Auf einem bekannten Videoportal HTML5 statt Flash erzwingen

Wer einen HTML5-fähigen Browser hat (oder testen will, ob ein Browser es beherrscht), der kann bei Videos auf Youtube mit einem einfachen Zusatz zur URL erzwingen, daß HTML5 zuerst versucht wird.

Angenommen, man hat einen Link der Art

Code:
https://www.youtube.com/watch?v=IRGENDEINE_ZEICHENFOLGE
so kann man durch Anfügen von "&html5=True", also durch die URL

Code:
https://www.youtube.com/watch?v=IRGENDEINE_ZEICHENFOLGE&html5=True
die Verwendung von HTML5 erzwingen.

Auch wenn das nicht immer klappt, einen Versuch ist es auf jeden Fall wert.

Tipp 2: Flash und Pulseaudio

Wer Pulseaudio verwendet (ein "pidof pulseaudio" sagt mehr) erlebt manchmal eine Überraschung beim Verhalten des Lautstärkereglers.

Auf einem von mir betreuten System reagierte Flashplayer nicht wie erwartet auf Änderungen des "normalen" Lautstärkereglers und manchmal kam gar kein Ton aus den Boxen.

Des Rätsels Lösung:
Flash verwendete als Ausgabemodul Alsa und nicht Pulseaudio, soll heißen, sofern ein anderer Prozess gerade auf Pulseaudio zugegriffen hatte, blockierte Pulseaudio die Ausgabe direkt über Alsa (das ist kein Bug, sondern Sinn und Zweck von Pulseaudio die "Herrschaft" zu übernehmen), hatte jedoch lange genug zuvor kein anderer Prozess Zugriff auf Pulseaudio (und der Pulseaudiodaemon "schlief" deshalb), so hatte aber dann logischerweise auch der Lautstärkeregler, welcher eigentlich die Ausgabe von Pulseaudio steuern sollte, keine Auswirkung auf die Lautstärke des Flashplayers, da dieser ja "direkt" über Alsa Sound ausgab.

Wenn man schon Pulseaudio nutzt, dann macht es auch Sinn möglichst alle Anwendungen durch Pulseaudio zu "quetschen", im Fall des Flashplayers erzielt man diesen Effekt über eine Umgebungsvariable.

Man fügt die Zeile

Code:
export FLASH_FORCE_PULSEAUDIO=1
in die passende Datei ein, in Frage kommen entweder /etc/profile (bzw. falls vorhanden und z.B. unter openSUSE die bessere Wahl /etc/profile.local)als globale Einstellung für alle User oder $HOME/.profile als Einstellung für den einzelnen User (diese Datei muss ggf. angelegt werden).

Greetz,

RM
 

Rain_Maker

Administrator
Teammitglied
"udev-Magie" statt Blacklisten: "ENV_MODALIAS" für die Zuordnung eines Treibers zu einem bestimmten Gerät

Man kennt wahrscheinlich die entsprechenden Ratschläge aus diversen Forenbeiträgen.

"Wenn Du $GERÄT mit $ANDEREM_TREIBER verwenden willst, dann blackliste $STANDARDTREIBER und gut ist."

Prinzipiell oft eine einfache und gute Lösung, aber es kann auch zu Problemen führen.

Nehmen wir an, man hat mehrere Devices, die unterschiedliche IDs haben, aber den selben Standardtreiber benutzen, wobei eines der Devices aber nicht ordentlich mit diesem funktioniert, die anderen dagegen schon. Dann führt das Blacklisten des Standardtreibers dazu, daß dieser für keines der Geräte mehr automatisch geladen wird und beim händischen Laden kloppen sich dann zwei Treiber um das selbe Device.

Hier mal ein (praxisrelevantes) Beispiel:

Bis Kernel 3.14 wurden WLAN-Karten mit der PCI-ID 10EC:8199 (Realtek) vom Treiber "r8187se" aus dem "Staging"-Zweig unterstützt. Dieser "Staging"-Treiber funktionierte so weit eigentlich ganz gut, aber gerade im Bereich WLAN wird seit Jahren versucht alles auf einen einheitlichen "Unterbau" (WLAN-Stack) zu bekommen. Im Linuxkernel befinden sich daher "ordentliche" Treiber für WLAN, welche auf mac80211 basieren und sämtliche neuen Treiber werden auf dieser Basis geschrieben.

Bei vielen anderen "Staging"-Treibern wurde daran gearbeitet, entweder eine mac80211-basierte Variante davon zu schreiben oder den Code in einen bereits vorhandenen mac80211-basierten Treiber zu integrieren, so auch bei obigem Treiber, dessen gerätespezifischer Code in "rtl818x_pci" integriert wurde und ab Kernel 3.15 wurde der alte "Staging"-Treiber aus dem Kernel entfernt.

So weit, so plausibel, aber dummerweise hat das Ergebnis noch mit so mancher Kinderkrankheit (schlechte Signalstärke, Verbindungsabbrüche etc.) zu kämpfen. Das wird zwar aller Voraussicht nach mit jedem neuen Kernel besser werden, aber wer auf einer Distribution unterwegs ist, die bei der selben Kernelversion bleibt (openSUSE, Debian, *Buntu), der hat zunächst einmal verloren (openSUSE 13.2 hat z.B. einen 3.16er Kernel).

Bis also die Kinderkrankheiten überstanden sind, wäre es nicht schlecht, den "alten" Treiber auch auf Kerneln > 3.14 verwenden zu können, darum kümmert sich z.B. dieses Projekt hier:

https://github.com/freestyl3r/rtl8187se

Und hier nun das Beispiel aus der Praxis:

Ein Bekannter von mir hat genau diese Karte in seinem Laptop verbaut, bis zu seinem letzten OS-Upgrade lief sie mit r8187se auch ganz ordentlich, danach mit einem Kernel > 3.14 gingen die Probleme los.

Da er aber auch noch eine PCMCIA WLAN-Karte besitzt, hat er zunächst diese verwendet, alles war OK und wie es der Zufall so wollte, lief diese Karte mit dem Treiber "rtl818x_pci". Nachdem ich ihm (per Chat) geholfen hatte den "alten" Treiber für seine Kernelversion zu bauen und zu installieren, wurde rtl818x_pci geblacklisted, die eingebaute Karte lief wieder wie gewohnt und mit der Steckkarte ging dann logischerweise nichts mehr.

Das wäre jetzt zwar als Lösung gut genug gewesen, aber dann packt einen doch der Ehrgeiz, ob das nicht auch etwas sauberer geht und ich würde hier nicht schreiben, wenn dem nicht so wäre.

Schauen wir uns kurz an, was "modinfo" zu den beiden Treibern zu sagen hat:

Code:
modinfo r8187se | grep 8199
alias:          pci:v000010ECd00008199sv*sd*bc*sc*i*

modinfo rtl818x_pci | grep 8199
alias:          pci:v000010ECd00008199sv*sd*bc*sc*i*
Damit ist auch klar, wieso sich beide Treiber zuständig fühlen, der rtl818x_pci unterstützt aber noch weitere Geräte:

Code:
modinfo rtl818x_pci | grep alias
alias:          pci:v00001432d00007106sv*sd*bc*sc*i*
alias:          pci:v00001186d00003301sv*sd*bc*sc*i*
alias:          pci:v00001186d00003300sv*sd*bc*sc*i*
alias:          pci:v00001799d00006020sv*sd*bc*sc*i*
alias:          pci:v00001799d00006001sv*sd*bc*sc*i*
alias:          pci:v000010ECd00008180sv*sd*bc*sc*i*
alias:          pci:v00001799d0000701Fsv*sd*bc*sc*i*
alias:          pci:v00001799d0000700Fsv*sd*bc*sc*i*
alias:          pci:v000010ECd00008185sv*sd*bc*sc*i*
alias:          pci:v000010ECd00008199sv*sd*bc*sc*i*
Wer also zusätzlich irgendein anderes Gerät aus der Liste für rtl818x_pci besitzt, der sägt sich mit dem Blacklisten von rtl818x_pci die Unterstützung für dieses Gerät praktisch ab.

Es wäre also wünschenswert, wenn man es so hinbiegen könnte, daß für Geräte mit der ID 10EC:8199 der Treiber r8187se bevorzugt geladen wird ohne rtl818x_pci auf die Blacklist setzen zu müssen.

Dies lässt sich mit einer einfachen udev-regel erreichen, genauer mit der (Umgebungs)Variablen "ENV{MODALIAS}":

/etc/udev/rules.d/99-r8187se.rules

Code:
ENV{MODALIAS}=="pci:v000010ECd00008199sv*sd*bc*sc*i*", ENV{MODALIAS}="r8187se"
Man beachte dabei die unterschiedliche Anzahl der Gleichzeichen, das doppelte in

ENV{MODALIAS}=="pci:v000010ECd00008199sv*sd*bc*sc*i*"

bedeutet "wenn Bedingung erfüllt", also die Variable diesen Wert wirklich hat; das einfache in

ENV{MODALIAS}="r8187se"

bedeutet "dann weise der Variablen den folgenden Wert zu".

Also wieder der typische Aufbau einer udev-Regel, nach dem Motto "WENN $Bedingung(en), DANN $Aktion".

Danach konnte der Backlisteintrag gelöscht werden und beide Karten funktionierten wie gewünscht, die eingebaute mit dem Treiber "r8187se", die andere mit "rtl818x_pci".

Greetz,

RM
 

helmut

New Member
Dateien erstellen, kopieren und verschieben/umbenennen und löschen

1. touch - Datei erstellen

Code:
touch example.txt
Durch diesen Befehl wurde die Datei example.txt in dem aktuellen Verzeichnis, indem man sich befindet, erstellt.
Sollte sie schon existieren, wird die Bearbeitungs- und Zugriffszeit auf die aktuell Zeit geändert. Mit

Code:
touch example.txt Zeitangabe
kann man den virtuellen Zugriff-/Bearbeitungszeitpunkt beliebig wählen. Mit -a wird nur die Zugriffszeit (access) geändert, mit -m die Bearbeitungszeit (modification). Die Erstellzeit bleibt unverändert.

Für Zeitangabe gibts ein flexibles Format, man kann nur den Tag bestimmen, oder nur die Uhrzeit, oder beides. Das internationale Format wäre

Code:
touch example.txt  -d "2022-01-12 12:33:00"
wobei bei der Uhrzeit auch Sekunden (und Minuten) weggelassen, oder Sekundenbruchteile mit angegeben werden können.

Mit man oder info erfährt man mehr ...
 
Oben