Software

Name Description Price Download
StraightPool Billard app. ? Android

About

My name is Mirko Marx, a software developer for desktop applications and embedded devices. I've specialized in cross platform development with C++ and Qt for serveral years. I'm interested in the most recent development methods, blog posts and language standards around C++.

Contact

Das Kontaktformular ist wegen der neu inkraftgetretenen Datenschutz-Grundverordnung bis zur Klärung der Rechtslage deaktiviert worden.

Hinfreiche Befehle

Suchen

Ordner finden:

$ find / -type d name "*.zip"

Text in Datei finden:

$ grep 'word' <file>

Man pages: find grep

Archive

Komprimieren und Symbolische Links erhalten:

$ tar -czvf example.tar.gz example/

Dekomprimieren und Symbolische Links erhalten:

$ tar -xhzvf example.tar.gz

Man pages: tar

Monitoring

Aktuelle CPU- und Speicher-Auslastung:

$ top -bc | grep <process_name>

Durchschnittliche CPU- und Speicher-Auslastung:

$ ps -C <process_name> -o %cpu,%mem,cmd

Hardware-Informationen

CPU-Informationen:

$ cat /proc/cpuinfo

Backups

$ rsync -auv --log-file=/var/log/rsync_backup --delete /source/path /target/path

-a umfasst die Optionen r (rekursiv), l (symbolische Links mitkopieren), p (Rechte der Dateien und Ordner übernehmen), t (Zeitstempel übernehmen), g (Gruppenrechte übernehmen) und D (Gerätedateien mitkopieren). Das –u steht für Update und sorgt dafür das nur neuere Dateien kopiert werden. Das -v steht für verbose und gibt Details auf der Konsole aus was gerade passiert.

Last change: Sat, 17 Nov 2018 13:42:00 +0000

Inbetriebnahme Rock64

Installation des Bestriebssystems

Als Betriebssystem soll ArchLinux auf der SD-Karte installiert werden.

$ sudo dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=32
$ sudo fdisk /dev/mmcblk0
  "o" -> Partionen löschen
  "p" -> Partionen anzeigen (sollte keine Partitionen zeigen)
  "n", "p" für primary, "1", "32768", ENTER
  "w"
$ sudo mkfs.ext4 /dev/mmcblk0p1
$ mkdir root
$ sudo mount /dev/mmcblk0p1 root
$ wget http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz
$ su
# bsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C root
# sync
# wget http://os.archlinuxarm.org/os/rockchip/boot/rock64/boot.scr -O root/boot/boot.scr
# umount root
$ wget http://os.archlinuxarm.org/os/rockchip/boot/rock64/idbloader.img
$ wget http://os.archlinuxarm.org/os/rockchip/boot/rock64/uboot.img
$ wget http://os.archlinuxarm.org/os/rockchip/boot/rock64/trust.img
$ dd if=idbloader.img of=/dev/mmcblk0 seek=64 conv=notrunc
$ dd if=uboot.img of=/dev/mmcblk0 seek=16384 conv=notrunc
$ dd if=trust.img of=/dev/mmcblk0 seek=24576 conv=notrunc

Jetzt kann die SD-Karte in den Rock64 eingesetzt werden und die Stromversorgung eingeschaltet werden. Das System sollte nun hochfahren.

Achtung: Da die HDMI-Unterstützung für den Rock64 unter ArchLinux nicht funktioniert, kann nur über SSH auf den Rock64 zugegriffen werden.

Konfiguration des Betriebssystems

Die Standard-Benutzer und Standardpasswörter sind:

  • alarm:alarm
  • root:root

Falls die Tastaturbelegung nicht stimmt:

$ loadkeys de

Entferne die Datei boot.scr die zuvor manuell heruntergeladen wurde und installiere das U-Boot-Package:

# rm /boot/boot.scr
# pacman -Sy uboot-rock64
"y" -> um den letzten Bootloader zu installieren
# exit

Sprache und Zeitzone ändern:

# echo LANG=de_DE.UTF-8 > /etc/locale.conf
# echo KEYMAP=de-latin1-nodeadkeys > /etc/vconsole.conf
# ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
# nano /etc/locale.gen
# locale-gen

Passwörter ändern:

$ passwd
# passwd

Hostnamen ändern:

# hostnamectl set-hostname rock64

Archlinux Krypto-Schlüssel aktualisieren:

# pacman-key --init
# pacman-key --populate archlinuxarm

SSH-Zugriff ohne Passwortabfrage einrichten

Angenommen es soll von einem PC auf den Rock64 per SSH zugegriffen werden. Dann muss auf dem PC und als auch auf dem Rock64 OpenSSH installiert werden.

# pacman -S openssh

Falls noch nicht vorhanden müssen SSH-Keys auf dem PC generiert werden:

# ssh-keygen -t rsa

Im Ordner ~/.ssh sollte sich jetzt ein Private-Key id_rsa und ein Public-Key id_rsa.pub befinden. Nun muss der Inhalt des Public-Keys vom PC in die ~/.ssh/authorized_keys-Datei des Rock64 hinzugefügt werden.

Soll auf dem PC Putty als SSH-Client verwendet werden, so muss noch eine *.ppk-Version des Private-Keys mit puttygen generiert werden, welche bei der Verwendung von Putty angegeben werden muss.

Last change: Sun, 15 Nov 2019 09:55:50 +0000

Web-Server einrichten

Web-Server installieren:

# pacman -S nginx
# systemctl start nginx.service
# systemctl enable nginx.service

Das Standard-Webseiten-Verzeichnis ist /srv/http.

Beachte, dass die Portweiterleitung für Port 80 zur Nutzung von HTTP im Router aktiviert ist.

Domain registrieren

Soll der Server von außen erreichbar sein, so ist es eher störend über die IP-Adresse zuzugreifen. Besser ist es über eine Domain zugreifen zu können. Domains lassen sich bei diversen Anbietern mieten.

Falls der Web-Server an einem Internet-Anschluss mit dynamischer IP-Adresse hängt, muss die aktuelle IP für die Domain aktuell gehalten werden. Dies wird durch die Nutzung eines DynDNS-Service erreicht, der im Router des Internet-Anschlusses konfiguriert und unterstützt werden muss. Wie das konkret umgesetzt wird soll hier nicht erklärt werden.

HTTPS mit Let's Encrypt-Zertifikat

Um ein Let's Encrypt-Zertifikat erstellen zu können muss das Tool certbot installiert werden.

# pacman -S certbot

Angenommen die Website liegt auf dem Webserver unter /src/http/yourdomain.com und die Website ist unter den zwei Domains yourdomain.com und www.yourdomain.com erreichbar. Die Zertifikatserstellung erfolgt dann durch:

# certbot certonly --webroot -w /srv/http/yourdomain.com
  -d yourdomain.com -d www.yourdomain.com

Wenn die Zertifikatserstellung erfolgreich war, so wurden die Zertifikate unter /etc/letsencrypt/live/yourdomain.com abgelegt. Nun muss nur noch die Webserver-Konfiguration (unter /etc/nginx/nginx.conf) ähnlich der folgenden angepasst werden.

worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include mime.types;
    default_type application/octet-stream;

    sendfile on;

    keepalive_timeout 65;

    server {
        listen 80 default_server;
        server_name yourdomain.com;
        return 301 https://$server_name$request_uri;

        location / {
            root /srv/http/yourdomain.com;
            index index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }

    server {
        listen 443 ssl default_server;
        server_name yourdomain.com;

        # SSL

        ssl on;
        ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
        ssl_session_cache builtin:1000 shared:SSL:10m;
        ssl_ciphers HIGH:!aNULL:!MD5:!RC4;

        # HSTS

        add_header Strict-Transport-Security "max-age=3156000; includeSubDomains" always;

        # global

        location / {
            root /srv/http/yourdomain.com;
            index index.html index.htm;
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/share/nginx/html;
        }
    }
}

Damit der Web-Server die Änderungen übernimmt, sollte er neugestartet werden.

# systemctl restart nginx.service

Beachte, dass die Portweiterleitung für Port 443 zur Nutzung von HTTPS im Router aktiviert ist.

Nun ist die Website über ein kostenloses Let's Encrypt Zertifikat komplett SSL verschlüsselt.

Let's Encrypt-Zertifikat automatisch erneuern

Ein Let's Encrypt-Zertifikat ist immer 90 Tage gültig und muss deshalb regelmäßig mit dem Befehl certbot renew --quiet erneuert und der Webserver neugestartet werden.

Das lässt sich per Systemd automatisieren.

Zuerst wird der tatsächliche Dienst zum Erneunern angelegt:

# nano /etc/systemd/system/certbot.service
[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --agree-tos
ExecStartPost=/bin/systemctl reload nginx.service

Danach wird ein Timer angelegt, der täglich den Prozess ausführt. Certbot prüft selbstständig, ob eine Verlängerung notwendig ist.

# nano /etc/systemd/system/certbot.timer
[Unit]
Description=Daily renewal of Let's Encrypt's certificates

[Timer]
OnCalendar=daily
RandomizedDelaySec=1day
Persistent=true

[Install]
WantedBy=timers.target

Zuletzt muss der Timer gestartet und aktviert werden (so dass dieser auch bei einen System-Reboot ausgeführt wird).

# systemctl start certbot.timer
# systemctl enable certbot.timer

Der Status der Ausführung lässt sich wie folgt prüfen:

# journalctl -u certbot

Proxy auf weitere Webdienste einrichten

Häufig sollen neben der normalen Website weitere Dienste angeboten werden, die unter einem separaten Webserver unter einer anderen Port-Nummer laufen.

Beispielsweise läuft ein Service auf Port 12345. Nun soll dieser einfach über http[s]://[www.]yourdomain.com/Service erreichbar sein. Dazu müsste die Server-Konfiguration (/etc/nginx/nginx.conf) wie folgt angepasst werden:

server {
	listen 80 default_server;
	...
	location /Service {
		proxy_pass http://localhost:12345;
	}
	...
}
server {
	listen 443 default_server;
	...
	location /Service {
		proxy_pass http://localhost:12345;
	}
	...
}

System Backup

System-Backup offline machen

Hierbei wird das zu sichernde System heruntergefahren und der Datenträger an ein anderes System eingehangen. Anschließend wird ein Image-Abbild davon erstellt:

$ dd if=/dev/<device-id> of=/path/to/image.img bs=4M status=progress

System-Backup online machen

Hierbei wird das zu sichernde System nicht heruntergefahren sondern nur alle Dienste und Prozesse angehalten die auf den Datenträger schreiben könnten. Anschließend erstellt das laufende System von seinem eigenen Datenträger ein Image-Abbild und schreibt es auf einen anderen Datenträger. Nach dem Abschluss werden die zuvor beendeten Dienste und Prozess wieder gestartet.

Beispiel Backup-Skript:

#!/bin/bash

TIMESTAMP=`date +%Y%m%d-%H%M%S`
DESDIR=/mnt/hdd/BACKUPS/images
BACKUP_ANZAHL="5"
BACKUP_NAME="RaspberryPiBackup"
DIENSTE_START_STOP="service mysql"

# Stoppe Dienste vor Backup
#${DIENSTE_START_STOP} stop

# Backup mit Hilfe von dd erstellen und im angegebenen Pfad speichern
dd if=/dev/mmcblk0 of=${DESDIR}/${BACKUP_NAME}-${TIMESTAMP}.img bs=1MB

# Starte Dienste nach Backup
#${START_SERVICES} start

# Alte Sicherungen die nach X neuen Sicherungen entfernen
#pushd ${DESDIR}; ls -tr ${DESDIR}/${BACKUP_NAME}* | head -n -${BACKUP_ANZAHL} | xargs rm; popd
sync

Mit folgendem Cron-Job kann das Backup-Skript wiederkehrend automatisiert ausgeführt werden:

# export VISUAL=nano; crontab -e

Um das Backup-Skript bspw. jeden Sonnabend um 2:00 Uhr auszuführen ist folgender Eintrag für den Cron-Job erforderlich:

0  2  *  *  *  /path/to/backup_image.sh

Shrink an image file

Load loopback kernel module:

# modprobe loop

Find a unused loopback device:

# losetup -f

Create a new loopback device for the image:

# losetup /dev/loop0 image.img

Trigger kernel to load the new loopback device:

# partprobe /dev/loop0

Open GParted and shrink filesystem and partition:

# gparted /dev/loop0

Release the loopback device:

# losetup -d /dev/loop0

Display the partion table:

# fdisk -l image.img

You will see something like this:

Disk image.img: 29.7 GiB, 31914983424 bytes, 62333952 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xe948a605

Device     Boot  Start      End  Sectors  Size Id Type
image.img1        2048   206847   204800  100M  c W95 FAT32 (LBA)
image.img2      206848 31023103 30816256 14.7G 83 Linux

Finally the image file has to be truncated (use the number of sectors and blocksize from your fdisk output):

# truncate --size=$[(31023103+1)*512] image.img

Last change: Sun, 28 Oct 2018 10:33:19 +0000

System Restore

Write an image file to a storage media

$ dd if=/path/to/image.img of=/dev/<device-id> bs=4M status=progress

Resize the filesystem and partition on the storage media

Use GParted to make this:

# gparted /dev/<device-id>

Last change: Sun, 28 Oct 2018 10:34:47 +0000

Datenträger einbinden

Falls der Datenträger eine NTFS-Formatierung hat, muss der NTFS-Treiber installiert werden:

# pacman -S ntfs-3g

Verzeichnis für das Mounten des Datenträgers erstellen:

# mkdir /mnt/hdd

Datenträger mounten:

# mount -t auto /dev/sdx1 /mnt/hdd

Permanentes Mounten eines Datenträgers durch Hinzufügen des folgenden Eintrages in /etc/fstab:

UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" /mnt/hdd1 auto defaults,nofail 0 0

Achtung: Die Option "nofail" ist wichtig, da das Booten nicht klappt, falls der Datenträger nicht angeschlossen ist!:

Die UUID des Datenträgers lässt sich durch folgenden Befehl herausfinden:

# fdisk -l
# blkid /dev/<Geräte-Bezeichnung>

Festplatte nach einer gewissen Zeit automatisch in den Standby schicken

# pacman -S hdparm

Den Status der Festplatte kann man wie folgt abrufen:

# hdparm -C /dev/sdx

Um eine Festplatte in den Standby zu schicken muss folgendes aufgerufen werden:

# hdparm -y /dev/sdx

Will ein Prozess auf die Festplatte zugreifen wird sie automatisch wieder anlaufen.

Soll eine Festplatte nach einer gewissen Zeit automatisch in den Standby geschickt werden, so muss folgendes aufgerufen werden:

# hdparm -S 60 /dev/sdx

Hierbei steht 60 für eine Zeit von 60 * 5 Sekunden.

Um diese Einstellung permanent zu setzen muss in /etc/hdparm.conf folgender Eintrag hinzugefügt werden:

/dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx {
spindown_time = 60
}

Last change: Wed, 28 Nov 2018 11:05:21 +0000

NAS

Samba einrichten:

# pacman -S samba
# cp /etc/samba/smb.conf.default /etc/samba/smb.conf

Allgemeine Konfiguration (/etc/samba/smb.conf):

workgroup = HOMEGROUP
#  log file = /var/log/samba/log.%m
security = user

Beispiel für die Konfiguration eines neuen NAS-Netzlaufwerks (/etc/samba/smb.conf):

[HDD]
comment = HDD
path = /mnt/hdd
valid users = @users
force group = users
create mask = 0660
directory mask = 0771
read only = no

Benutzer einrichten:

# useradd nas -m -G users
# passwd nas
# smbpasswd -a nas
# chown nas:nas -R /mnt/hdd

Samba-Dienst starten:

# systemctl start smb.service
# systemctl enable smb.service
# systemctl start nmb.service
# systemctl enable nmb.service

Last change: Wed, 28 Nov 2018 10:47:47 +0000

Git Commits

  1. Commit-Message bearbeiten (Not pushed + most recent commit)

    $ git commit --amend
  2. Commit-Message bearbeiten (Already pushed + most recent commit)

    $ git commit --amend
    $ git push origin master --force

    ACHTUNG: Dies wird andere Benutzer daran hindern sich mit dem Repo zu synchronisieren, wenn sie bereits eine Kopie gezogen haben!

  3. Commit-Message bearbeiten (Not pushed + old commit)

    $ git rebase -i HEAD~X
    $ git commit --amend
    $ git rebase --continue
      
  4. Commit-Message bearbeiten (Already pushed + old commit)

    $ git rebase -i HEAD~X
    $ git commit --amend
    $ git rebase --continue
    $ git push origin master --force
      

Git Branches

master-Branch durch anderen Branch ersetzen

$ git checkout <branch>
$ git merge -s ours master
$ git checkout master
$ git merge <branch>

-s ours ist die Abk. für --strategy=ours

Lokale Branch löschen

$ git branch -d <branch>

Remote Branch löschen

$ git push origin :<branch>

Git

  1. Working copy => enthält die realen Dateien
  2. Index => erfasst alle von Git verwalteten Dateien
  3. HEAD => zeigt auf den letzten Commit

Installation

# pacman -S git

Entferntes Repository erzeugen

Ein entferntes Repository erstellen (gewöhnlicherweise auf einem Linux-Server).

$ mkdir <path/to/repo>
$ cd <path/to/repo>
$ git --bare init

Repository klonen

Das enternte Repository lässt sich nun von einem Client-Rechner (mit installiertem Git) wie folgt klonen.

$ git clone ssh://username@host/path/to/remoteRepo

Nun könnte noch nach einem Schlüssel gefragt werden. Bei Tortoise-Git unter Windows muss dann die "raspi.ppk"-Datei angegeben werden. Unter Linux muss die "raspi.ppk"-Datei wie folgt umgewandelt werden:

$ mkdir -p ~/.ssh
$ puttygen ~/raspi.ppk -o ~/.ssh/id_rsa -O private-openssh

Workflow

Dateien hinzufügen/entfernen

$ git add 
$ git rm

Der Status kann jederzeit durch folgenden Befehl überprüft werden:

$ git status

Hinzugefügte Dateien in lokales Repository übernehmen

$ git commit

Danach öffnet sich ein Editor, in dem die Commit-Nachricht eingegeben werden muss. Beachte: Der zu verwendende Editor kann wie folgt geändert werden:

$ git config --global core.editor notepad.exe

Änderungen vom lokalen Repository an entferntes Repository senden

$ git push origin

Die Standard-Branch heißt "master".

Änderungen vom entfernten Repository im lokalen Repository übernehmen

$ git pull

Dadurch werden die letzten Updates aus dem entfernten Repository geholt.

Branching

Die Standard-Branch heißt "master". Für einen Entwicklungsschritt solltest du aber eine eigene Branch erstellen und in diese Branch wechseln:

$ git branch 
$ git checkout

Sobald der Entwicklungsschritt abgeschlossen ist, sollte man in den "master"-Branch wechseln und die Änderungen aus den "Entwicklungs"-Branch dort hinein-mergen:

$ git checkout master
$ git merge

Dadurch können Konflikte auftreten, die du durch manuelles Edititeren beheben musst. Nach erfolgreichen mergen sollte die Branch auch wieder gelöscht werden:

$ git branch -d

Beachte: Eine Branch ist im entfernten Repository nicht verfügbar, bis du sie im entfernten Repository hochlädst:

$ git push origin

Tagging

Es wird empfohlen für jeden abgeschlossenen Meilensteilen (z.B. ein Release) ein neues Tag anzulegen:

$ git tag

Backup

Für ein Backups auf dem enternten Repository auf dem Server kann folgendes Skript (backupGit.sh) genutzt werden:

#!/bin/bash
TIMESTAMP=`date +%Y%m%d-%H%M%S`
SRCDIR=/path/to/GitRepo.git
DESDIR=/path/to/backup
tar -cpzf $DESDIR/GitRepo.git_$TIMESTAMP.tar.gz $SRCDIR
sync

Anschließend wird mit

# export VISUAL=nano; crontab -e

ein Cron-Job eingerichtet, um das Backup-Skript zu wiederkehrenden Zeitpunkten automatisch auszuführen.

Um das Backup-Skript bspw. jeden Sonnabend um 2:00 Uhr auszuführen ist folgender Eintrag für den Cron-Job erforderlich:

0  2  *  *  *  backupGit.sh

Last change: Wed, 22 Aug 2018 16:25:49 +0000

Yocto-Image erstellen

Nachfolgend wird das Erstellen eines Yocto-Images für den Raspberry Pi (als Target) beispielhaft gezeigt.

$ cd
$ mkdir -p yocto/source
$ cd yocto/source
$ git clone -b warrior git://git.yoctoproject.org/poky.git poky
$ git clone -b warrior git://git.openembedded.org/meta-openembedded
$ git clone -b warrior https://github.com/meta-qt5/meta-qt5
$ git clone -b warrior git://git.yoctoproject.org/meta-security
$ git clone -b warrior git://git.yoctoproject.org/meta-raspberrypi
$ git clone -b warrior git://github.com/jumpnow/meta-rpi

Mit dem source-Befehl werden nun Befehle aus der Datei oe-init-build-env direkt auf dieser Konsole ausgeführt.

$ source poky/oe-init-build-env ../build

Die Yocto-Build-Tools sollten nun bekannt und das Arbeitsverzeichnis der build-Ordner sein.

Build-Konfiguration aus meta-rpi übernehmen:

$ cp ../source/meta-rpi/conf/local.conf.sample conf/local.conf
$ cp ../source/meta-rpi/conf/bblayers.conf.sample conf/bblayers.conf

Image bauen:

$ bitbake qt5-image

Wenn das Bauen wegen eines Moduls fehlschlägt, dann kann folgendes helfen:

$ bitbake -c cleansstate <module_name>

Image auf SD-Karte schreiben

Nachfolgend wird davon ausgegangen, dass die SD-Karte als /dev/sdb eingehangen ist.

SD-Karte mit 2 Partitionen formatieren:

$ sudo ./mk2parts.sh sdb

Umgebungsvariablen für die nachfolgenden Skripte setzen:

$ export OETMP=~/rpi/build/tmp
$ export MACHINE=raspberrypi3

Es kann sein, dass die Partitionen der SD-Karte automatisch gemountet werden. Damit die nachfolgenden Skripte erfolgreich arbeiten müssen diese ausgehangen werden.

$ umount /dev/sdb1
$ umount /dev/sdb2

Boot-Partition schreiben:

$ ./copy_boot.sh sdb

System-Partition schreiben:

$ ./copy_rootfs.sh sdb qt5 rpi3

Cross-Kompilierung für das Target-Gerät

Nachdem nach ein Yocto-Image für das Target-Gerät gebaut hat, möchte man i.d.R. unter einem Host für das Target Software cross-kompilieren, deployen und debuggen können. Dazu muss das Sysroot mit den Target-Header und die entsprechenden Cross-Compiler auf dem Host verfügbar sein. Diese lassen sich auch über das Yocto-Buildsystem für den Host wie folgen bauen.

$ source poky-rocko/oe-init-build-env ~/rpi/build
$ bitbake qt5-image -c populate_sdk

Generiert wurde nun ein Shell-Skript unter ${TMPDIR}/deploy/sdk. Die Installation erfolgt durch deren Ausführung:

$ sudo poky-glibc-x86_64-meta-toolchain-qt5-cortexa7hf-neon-vfpv4-toolchain-2.1.1.sh

Last change: Mon, 19 Aug 2019 14:44:24 +0000

Package-Downgrade

Alle Packages die über Pacman installiert werden, werden in /var/cache/pacman/pkg heruntergeladen. Dort findet man also alle Packages die bisher installiert wurden (sofern der Cache nicht gelöscht wird).

Falls ein installiertes Package Probleme bereitet, kann man einfach auf eine ältere Version des Package aus dem Cache wie folgt downgraden:

$ cd /var/cache/pacman/pkg
# pacman -U package-version.pkg.tar.xz

Im Falle dass man den Kernel downgraden möchte sollte man neben dem Package linux auch linux-headers und Kernelmodule wie z.B. virtualbox-host-modules-arch downgraden.

Last change: Wed, 17 Jan 2018 10:49:57 +0000

KDE Plasma

Alle Schriftzeichen und Emoticons in Google Chrome anzeigen

# pacman -S noto-fonts noto-fonts-extra noto-fonts-cjk noto-fonts-emoji

KDE Plasma einrichten

Global Shortcuts:
				WIN+D -> Show Desktop
				WIN+E -> Open Explorer
				WIN+L -> Lock Screen
				WIN+X -> Open Settings
				CTRL+ALT+Left -> Go to left Desktop
				CTRL+ALT+Right -> Go to right Desktop

Last change: Fri, 15 Mar 2024 18:59:07 +0000

ArchLinux Installation

Keyboard Layout setzen:

# loadkeys de-latin1-nodeadkeys

Keyring updaten:

# pacman -Sy archlinux-keyring

Arch Linux interaktiv installieren:

# archinstall

Last change: Fri, 15 Mar 2024 18:59:07 +0000

Elements

Text

This is bold and this is strong. This is italic and this is emphasized. This is superscript text and this is subscript text. This is underlined and this is code: for (;;) { ... }. Finally, this is a link.


Heading Level 2

Heading Level 3

Heading Level 4

Heading Level 5
Heading Level 6

Blockquote

Fringilla nisl. Donec accumsan interdum nisi, quis tincidunt felis sagittis eget tempus euismod. Vestibulum ante ipsum primis in faucibus vestibulum. Blandit adipiscing eu felis iaculis volutpat ac adipiscing accumsan faucibus. Vestibulum ante ipsum primis in faucibus lorem ipsum dolor sit amet nullam adipiscing eu felis.

Preformatted

i = 0;

while (!deck.isInOrder()) {
    print 'Iteration ' + i;
    deck.shuffle();
    i++;
}

print 'It took ' + i + ' iterations to sort the deck.';

Lists

Unordered

  • Dolor pulvinar etiam.
  • Sagittis adipiscing.
  • Felis enim feugiat.

Alternate

  • Dolor pulvinar etiam.
  • Sagittis adipiscing.
  • Felis enim feugiat.

Ordered

  1. Dolor pulvinar etiam.
  2. Etiam vel felis viverra.
  3. Felis enim feugiat.
  4. Dolor pulvinar etiam.
  5. Etiam vel felis lorem.
  6. Felis enim et feugiat.

Icons

Actions

Table

Default

Name Description Price
Item One Ante turpis integer aliquet porttitor. 29.99
Item Two Vis ac commodo adipiscing arcu aliquet. 19.99
Item Three Morbi faucibus arcu accumsan lorem. 29.99
Item Four Vitae integer tempus condimentum. 19.99
Item Five Ante turpis integer aliquet porttitor. 29.99
100.00

Alternate

Name Description Price
Item One Ante turpis integer aliquet porttitor. 29.99
Item Two Vis ac commodo adipiscing arcu aliquet. 19.99
Item Three Morbi faucibus arcu accumsan lorem. 29.99
Item Four Vitae integer tempus condimentum. 19.99
Item Five Ante turpis integer aliquet porttitor. 29.99
100.00

Buttons

  • Disabled
  • Disabled

Form

Legal Note

Show postal address

This Website is based on a template from HTML5 UP.

Impressum

Haftung für Inhalte

Die Inhalte dieser Website wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität der Inhalte kann ich jedoch keine Gewähr übernehmen. Als Diensteanbieter bin ich gemäß § 7 Abs. 1 TMG für eigene Inhalte auf dieser Website nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG bin ich als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werde ich diese Inhalte umgehend entfernen.

Haftung für Links

Meine Website enthält Links zu externen Webseiten Dritter, auf deren Inhalte ich keinen Einfluss habe. Deshalb kann ich für fremde Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Webseiten ist stets der jeweilige Anbieter oder Betreiber verantwortlich. Die verlinkten Websites wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.

Urheberrecht

Die durch den Seitenbetreiber erstellten Inhalte und Werke auf dieser Website unterliegen dem deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Website sind nur für den privaten, nicht kommerziellen Gebrauch gestattet. Soweit die Inhalte auf dieser Website nicht vom Betreiber erstellt wurden, werden die Urheberrechte Dritter beachtet. Insbesondere werden Inhalte Dritter als solche gekennzeichnet. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam werden, bitte ich um einen entsprechenden Hinweis. Bei Bekanntwerden von Rechtsverletzungen werde ich derartige Inhalte umgehend entfernen.

Datenschutz

Die Nutzung dieser Website ist in der Regel ohne Angabe personenbezogener Daten möglich. Soweit auf dieser Website personenbezogene Daten (beispielsweise Name, Anschrift oder Email-Adressen) erhoben werden, erfolgt dies, soweit möglich, stets auf freiwilliger Basis. Diese Daten werden ohne Ihre ausdrückliche Zustimmung nicht an Dritte weitergegeben.

Ich weise darauf hin, dass die Datenübertragung im Internet (z.B. bei der Kommunikation per Email) Sicherheitslücken aufweisen kann. Ein lückenloser Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich. Der Nutzung von im Rahmen der Impressumspflicht veröffentlichten Kontaktdaten durch Dritte zur Übersendung von nicht ausdrücklich angeforderter Werbung und Informationsmaterialien wird hiermit ausdrücklich widersprochen. Der Betreiber dieser Website behält sich ausdrücklich rechtliche Schritte im Falle der unverlangten Zusendung von Werbeinformationen, etwa durch Spam-Mails, vor.