cheatsheet.zwischenspeicher.info

Some tech documentation and snippets, finally organized.
Posts tagged as linux

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.