ALSA: changing audio device priority
ALSA enumerates available audio devices in the order their corresponding kernel modules are loaded, so e.g. connecting an audio capable HDMI device can break on-board sound. For a permanent and system wide change of audio device priority, this order can be manipulated by adding a simple configuration file with the suffix .conf
to the folder /etc/modprobe.d/
.
First it needs to get a list of the loaded sound modules:
$ cat /proc/asound/modules
0 MODULE_X
1 MODULE_Y
2 MODULE_Z
In the best case, all audio devices use different kernel modules, which will be listed, one per line, with the key options
and an index
value:
### File: /etc/modprobe.d/alsa.conf
options MODULE_1 index=0
options MODULE_2 index=1
options MODULE_3 index=2
If there are several audio devices based on the same chipset, additionally their associated card IDs need to be specified. The command
$ aplay -l | grep ^card
will return the necessary identifiers in the second column, right after card #:
. Add them to the respective lines in /etc/modprobe.d/alsa.conf
as new column three, between module name and index number.
To be prepared for the occasional use of a USB audio adapter, I suggest to additionally list the snd-usb-audio
module and assign it index=0
.
Here my current configuration:
### File: /etc/modprobe.d/alsa.conf
options snd-usb-audio index=0
options snd-hda-intel id=VT82xx index=1
options snd-hda-intel id=HDMI index=2
Although this is Linux, the easiest way to make the changes take effect is to reboot the system ;)
If you have several devices with the same ID, you can make ALSA directly address the hardware by adding the following entries to /etc/asound.conf
or ~/asoundrc
- the respective card number can again be determined with the command aplay -l
.
### File: /etc/asound.conf
### OR
### ~/.asoundrc
pcm.!default {
type hw
card 1
}
ctl.!default {
type hw
card 1
}
Note: This way no other applications can access the sound card concurrently.
As a last solution, it is possible to fully disable specific cards with a line like the following in /etc/modprobe.d/alsa.conf
:
### File: /etc/modprobe.d/alsa.conf
options snd-hda-intel enable=0,1
The array will disable (0
) the first and enable (1
) the second of two cards.
Auto-upgrade for Debian based systems
A reliable auto-updater for home use. It can be executed e.g. at boot from /etc/rc.local
to keep apt
based systems up-to-date. Some output will be logged to /var/log/safe-upgrade.log
, in case of upgraded or held packages as well as errors a report will be sent to root@localhost.
Update August, 2020: Command line option "--full" for Dist-Upgrade.
Update June, 2022: sleep
-loop for delayed connections (dial-up, WiFi).
#!/bin/sh
#
# safe-upgrade.sh
#
# automated "safe-upgrade" for apt-based distributions with logging
# to /var/log/safe-upgrade.log and a mail to root@localhost in case
# of upgraded packages or problems
# optional command line parameter "--full" will run a dist-upgrade
pingtest=debian.org
hostname=`hostname`
logfile=/var/log/safe-upgrade.log
mailto=root@localhost
if [ X"$@" = X"--full" ] ; then
task=dist-upgrade
else
task=upgrade
fi
sleep 15
echo ----- `date` ----- >> "$logfile"
ping -c 1 "$pingtest" > /dev/null 2>> "$logfile" ||\
{
echo "System upgrade cancelled: No internet connection." |\
tee -a "$logfile" |\
mailx -s "$hostname"\ update\ \*\*\*ERROR\*\*\* "$mailto"
exit 0
}
DEBIAN_FRONTEND=noninteractive
apt-get -q=2 update 2>&1 |\
tee -a "$logfile" |\
mailx -E -s "$hostname"\ update\ \*\*\*ERROR\*\*\* "$mailto"
apt-get "$task" -y -q 2>&1 |\
grep -ve "^(\{0,1\}Reading" \
-e "^Building" \
-e "^Calculating" |\
tee -a "$logfile" |\
grep -ve "^0 upgraded.*0 not upgraded\.$" |\
mailx -E -s "$hostname"\ upgrade\ log "$mailto" &&
echo ----- DONE ----- >> "$logfile"
exit 0
To tame the daily growing log file, add the following lines to /etc/logrotate.conf
or into an own file in /etc/logrotate.d/
. This will keep compressed archives of the last three months' log files.
### File: /etc/logrotate.conf
/var/log/safe-upgrade.log {
monthly
create
rotate 3
}
If you want the script to be executed by cron, it is necessary to set the $PATH
variable - in the script itself, or in the crontab
. This example runs every three hours at 45':
### File: root crontab, open to edit with "crontab -e"
# m h dom mon dow command
45 */3 * * * PATH='/usr/sbin:/usr/bin:/sbin:/bin' /path/to/safe-upgrade.sh
Piping dd
Write to several devices at once with dd
and tee
:
$ dd if=INFILE | tee > (dd of=/dev/sdX) | dd of=/dev/sdY
dd
over the network with netcat
and bzip
compression (not encrypted),
serverside...
$ nc -l 9000 | bzip2 -d | dd bs=1M of=OUTFILE
...and clientside:
$ dd bs=1M if=INFILE | bzip2 -c | nc SERVER 9000
Writing data to an ssh
server, using xz
transport compression:
$ dd if=INFILE bs= 1M | xz |\
ssh user@host "xz -d | dd of=OUTFILE bs=1M"
Reading data from an ssh
server, again with xz
transport compression:
$ ssh user@host "dd if=INFILE bs=1M | xz" |\
xz -d | dd of=OUTFILE bs=1M
Hotfixing a Debian package
How to patch and compile a Debian package from its source and avoid future re-installation of the unpatched version by creating a local version number. Example: claws-mail.
Note: Source repositories need to be enabled in the sources.list
.
Become root and install the needed software:
$ sudo su
$ apt-get install build-essential apt-src devscripts patch
Create a working directory, here /usr/src/claws-mail
and enter it:
$ mkdir /usr/src/claws-mail
$ cd /usr/src/claws-mail
apt-src
will download and install the Debian source package itsself as well as all needed development files and tools:
$ apt-src install claws-mail
Enter the source tree, apply the patch (or edit source manually) and use debchange
from the "devscripts" package to create a local version number with suffix "local". It is possible to append a short decripive text directly to the debchange
command, which will be added to the packages changelog:
$ cd claws-mail-VERSION
$ patch SOURCEFILE DIFF
$ debchange --local local PATCH_DESCRIPTION...
If no changelog text is given, an editor will open the changelog. (Edit, save and) close the file to continue. Now leave the source tree and compile the package:
$ cd ..
$ apt-src -p build claws-mail
This will take a while. When back at the command prompt, the newly built Debian package(s) can be found in the "top level" working directory, ready to install.
$ cd ..
$ dpkg -i ALLTHEDEBS
Finally clean the leftovers of the build process from the source tree:
$ apt-src clean claws-mail
Note: The next official update of the package will automatically overwrite this local version. In case the update does not contain the locally applied patch, update the apt
package index and run apt-src
again. It will try to bring the patch forward:
$ apt-get update
$ cd /usr/src/claws-mail
$ apt-src -b upgrade claws-mail
$ cd .. && dpkg -i ALLTHEDEBS
If you want to install all of the built packages (or there is only one package going to be built), it is sufficient to run
$ apt-src -i install claws-mail
This will update, patch and compile the sources and finally install the newly built package(s) in one go.