Uli Köhler

Beispielcode: Koa.JS mit Router & Body-Parser

Dieser Beispielcode stellt die einfachstmögliche Koa.JS-Applikation dar, die ich als Template für verschiedene Webserver-Projekte verwende.

#!/usr/bin/env node
const router = require('koa-router')();
const koaBody = require('koa-body');
const Koa = require('koa');
const app = new Koa();

app.use(koaBody());

router.get('/', async ctx => {
    ctx.body = "Hallo Welt!";
});

app.use(router.routes());

if (!module.parent) app.listen(3000);

Installiere die Abhängigkeiten mit

npm i --save koa koa-router koa-body

und führe den Code so aus, nachdem du den obenstehenden Code als index.js abgespeichert hast:

node index.js

Während node index.js noch läuft, öffne http://localhost:3000 . Du solltest dort Hallo Welt! sehen. Jetzt bist du bereit, das Beispiel zu deiner eigenen Webapplikation auszubauen.

Posted by Uli Köhler in Javascript, NodeJS

Was ist ‚lamp controlgear‘ in der Beleuchtungstechnik?

lamp controlgear ist die englische Bezeichnung für Betriebsgeräte (controlgear) für Beleuchtungen (lamp).

Typische Beispiele sind elektronische Betriebsgeräte für LED-Module (electronic controlgear for LED modules).

Der Begriff controlgear wird z.B. auch in IEC-Standards benutzt, beispielsweise IEC 61347-2-13 (deutsche Version) und kann somit als offizielle Bezeichnung für diese Produktgruppe dienen.

Typischerweise ist in diese Standards ein controlgear/Betriebsgerät als Einheit definiert, die eine nachgeschaltete Beleuchtung mit der für die Beleuchtung spezifizierte Spannung bzw. mit dem spezifiziertem Strom versorgt.

Posted by Uli Köhler in Elektronik

Widerstands-Leistung online berechnen

Benutze diesen Online-Rechner, um die Leistung in Watt zu berechnen, die von einem Widerstand dissipiert wird, wenn du den Widerstand in Ω und den Strom in A kennst!

Continue reading →

Posted by Uli Köhler in Elektronik, Online-Rechner

Was ist ‚…‘ in HTML?

… ist der HTML-Entity-Code für Punkt-Punkt-Punkt:

Wenn du … auf einer Webseite außerhalb von HTML-Quellcode siehst, heißt das normalerweise, dass der Autor oder das Content-Management-System die Entität inkorrekt eingefügt hat. Eigentlich sollte dort stehen.

Ich empfehle, das Unicode-Zeichen HORIZONTAL ELLIPSIS (siehe den obenstehenden Codeblock) anstatt der HTML-Entität … zu verwenden.

Du musst dazu jedoch den Tag

<meta charset="utf-8" />

in deinem HTML-<head> haben, damit der Browser weiß, mit welchem Zeichensatz die Seite kodiert ist.

Posted by Uli Köhler in Unkategorisiert

Beispiel für ein minimales WordPress-Plugin

Dieses Beispiel zeigt das minimale WordPress-Plugin – es macht absolut nichts, aber du kannst es aktivieren und es als Basis für eigene Plugins nutzen.

Zuerst erzeuge einen Ordner für dein Plugin in wp-content/plugins/, zum Beispiel wp-content/plugins/mein-plugin

Speichere den Folgenden Code als functions.php im Plugin-Ordner, z.B. wp-content/plugins/my-plugin/functions.php

<?php 
/*
Plugin Name: My plugin
*/

Nun kannst du dein Plugin im WordPress-Adminbereich aktivieren.

Posted by Uli Köhler in PHP, Wordpress

Was bedeutet Delivery Status Notification ‚550 5.1.1 User unknown (in reply to RCPT TO command)‘?

Problem:

Du versuchst, eine E-Mail zu senden, aber kurz nach dem Absenden der E-Mail erhältst du eine Delivery Status notification-Mail wie diese:

This is the mail system at host techoverflow.net.

I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.

For further assistance, please send mail to postmaster.

If you do so, please include this problem report. You can
delete your own text from the attached returned message.

                   The mail system

<[email protected]>: host mail.recpient.com[213.216.0.1] said: 550 5.1.1 User
    unknown (in reply to RCPT TO command)

Lösung:

Wenn die Delivery status notification-E-Mail eine Zeile wie diese enthält:

<[email protected]>: host mail.firma.com[213.216.0.1] said: 550 5.1.1 User unknown (in reply to RCPT TO command)

bedeutet das, dass die Empfänger-E-Mail-Adresse (am Anfang der Zeile – in diesem Beispiel [email protected]) nicht existiert.

In den meisten Fällen gibt es entweder

  • einen Schreibfehler in der Mailadresse, z.B. [email protected] oder
  • die Person in der Firma existiert nicht mehr oder
  • die Domain ist falsch – z.B. firma.com statt firma.de oder enthält einen Tippfehler wie z.B. frima.de

Falls du die E-Mail an mehrere Empfänger geschickt hast (z.B. mit CC), dann ist sie bei den anderen Empfängern angekommen, außer:

  • die Delivery status notification-E-Mail enthält weitere Zeilen mit 550 5.1.1 User unknown , die weitere Empfänger auflisten, bei denen die Mails nicht angekommen sind, oder
  • es kommen weitere Delivery Status Notification-Mails an, die weitere Empfänger enthalten, bei denen die Mail nicht angekommen ist.

Manchmal dauert es einige Minuten, bis weitere Delivery status notification-Mails ankommen. Ab und zu landen diese E-Mail auch im Spam-Ordner.

Hinweis: Enthält die entsprechende Zeile in der Delivery Status Notification nicht 550 5.1.1 User unknown, dann liegt ein anderer Fehler vor.

Tip: Falls die Mailadresse des Empfängers nicht mehr existiert und du keine andere geeignete Mailadresse kennst, versuche eine der Folgenden Mailadressen:

oder sieh auf der Firmenhomepage im Impressum nach.

Posted by Uli Köhler in E-Mail

Was tun bei ‚fatal error: stringstream: Datei oder Verzeichnis nicht gefunden‘ in C++?

Problem:

Dein C++-Code enthält eine Zeile wie

#include <stringstream>

da du std::stringstream benutzen möchtest, aber dein Compiler zeigt dir diese Fehlermeldung an:

main.cpp:2:10: fatal error: stringstream: Datei oder Verzeichnis nicht gefunden
 #include 
          ^~~~~~~~~~~~~~
compilation terminated.

Solution:

Der Header heißt sstream, nicht stringstream! Benutze diese #include-Direktive:

#include <sstream>
Posted by Uli Köhler in C++

Lösung für git: fatal: Kein Ziel für „push“ konfiguriert.

Problem:

Du hast ein git-Repository in einem Ordner mithilfe von

git init

initialisiert.

Nun hast du ein oder mehrere Commits gespeichert und möchtest diese nun auf den Server hochladen (z.B. Github):

git push

aber du siehst diese Fehlermeldung:

fatal: Kein Ziel für "push" konfiguriert.
Entweder spezifizieren Sie die URL von der Befehlszeile oder konfigurieren ein Remote-Repository unter Benutzung von

    git remote add <Name> <URL>

und führen "push" dann unter Benutzung dieses Namens aus

    git push <Name>

Lösung:

Da du dein Repository mit git init initialisiert hast, weiß git nicht, auf welchen Server es die Daten hochladen soll, wenn du git push ausführst..

Daher müssen wir erst einen Server hinzufügen. Ein Server heißt bei git remote.

git remote add origin https://github.com/benutzer/repository.git

Denk daran, https://github.com/benutzer/repository.git durch die entsprechende URL zu ersetzen, die du beim Anbieter deines Repositories findest (z.B. auf Github).

Die Folgenden URLs sind beispielsweise korrekt:

  • https://github.com/ulikoehler/UliEngineering.git
  • [email protected]:ulikoehler/UliEngineering.git

Das obige Kommando fügt einen Server in die Serverliste des Repositories hinzu (remote add), der mit origin  bezeichnet wird (dies ist der Standardname für remotes in git) und die URL https://github.com/benutzer/repository.git hat.

Auf GitHub (und in GitLab) kannst du die korrekte URL herausfinden, indem du auf den grünen Clone or Download-Button klickst.

Nun kannst du deine existierenden Commits auf den Server pushen. Das erste mal reicht git push allerdings nicht aus, denn git weiß nicht, auf welchem Server der Upload landen soll.

Daher musst du das erste mal nach dem Ausführen von git remote add ... das Folgende Kommando ausführen, um den master-Branch auf den origin-Server hochzuladen:

git push --set-upstream origin master

Wenn dieses Kommando eine Fehlermeldung erzeugt, dann hast du vermutlich die falsche URL für den Server verwendet. In diesem Fall lösche den Server mit

git remote rm origin

und versuche es erneut mit der richtigen URL. Sollte die URL stimmen, hast du vermutlich nicht die richtigen Zugangsdaten für den Server eingegeben (z.B. bei SSH).

Ab jetzt kannst du ganz einfach

git push

verwenden, um neue Commits auf den Server hochzuladen

Posted by Uli Köhler in git

Wie behebt man „Couldn’t run /usr/bin/dumpcap in child process: Permission denied“ auf Linux

Wenn du eine Fehlermeldung wie diese in Wireshark siehst:

liegt das daran, dass der aktuelle Systemnutzer keine Berechtigung hat, Pakete von der Netzwerkkarte abzufangen.

Das kann sogar dann passieren, wenn du während der Installation ausgewählt hast, dass normale Nutzer Pakete abfangen dürfen – denn diese Einstellung wird erst aktiv, wenn du dich aus- und wieder eingeloggt hast (oder den Computer neugestartet hast).

Um das Problem temporär zu beheben, ohne dich aus- und wieder einzuloggen, führe Wireshark als Root aus: sudo wireshark

Um das Problem permanent zu beheben, führe dieses Kommando aus:

sudo usermod -a -G wireshark $USER

und dann logge dich komplett aus und wieder ein (oder starte deinen Computer neu).

Posted by Uli Köhler in Linux

Was tun bei CMake: ‚make: *** Es wurden keine Ziele angegeben und keine „make“-Steuerdatei gefunden. Schluss.‘

Problem:

Du versuchst, eine Software zu builden, die das CMake-Buildsystem verwendet.

Dazu führst du make aus, was in der Folgenden Fehlermeldung resultiert:

make: *** Es wurden keine Ziele angegeben und keine „make“-Steuerdatei gefunden.  Schluss.

Lösung:

Bevor du make ausführst, musst du den Build mit CMake konfigurieren.

Die einfachste Möglichkeit ist:

cmake .

Normalerweise musst du das nur einmal für jedes Projekt tun ; CMake wird automatisch Änderungen an CMakeLists.txt detektieren, wenn du make ausführst.

Danach kannst du make nochmal ausführen. Wenn der Build erfolgreich ist, siehst du eine Meldung ähnlich zu dieser:

[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[100%] Linking CXX executable main
[100%] Built target main
Posted by Uli Köhler in Buildsysteme

Was ist die Formel für 2/3/4 parallele Widerstände?

Formel für 2 parallele Widerstände R1 und R2:

R_{insgesamt} = \frac{1}{\frac{1}{R_1} + \frac{1}{R_2}}

Python-Ccode:

rinsgesamt = 1. / (1./r1 + 1./r2)

Formel für 3 parallele Widerstände R1 undR2:

R_{insgesamt} = \frac{1}{\frac{1}{R_1} + \frac{1}{R_2} + \frac{1}{R_3}}

Python-Code:

rinsgesamt = 1. / (1./r1 + 1./r2 + 1./r3)

Formel für 4 parallele Widerstände R1 und R2:

R_{insgesamt} = \frac{1}{\frac{1}{R_1} + \frac{1}{R_2} + \frac{1}{R_3} + \frac{1}{R_4}}

Python-Code:

rinsgesamt = 1. / (1./r1 + 1./r2 + 1./r3 + 1./r4)

 

Posted by Uli Köhler in Elektronik, Python

Wie kommt man auf dem Acer Aspire A515-52(G) ins BIOS / UEFI-Menü?

Um auf dem Acer Aspire 5 A515-52(G) ins BIOS / UEFI-Menü zu kommen, drücke wiederholt F2 während und kurz nachdem das Acer-Logo am Bildschirm angezeigt wird.

Posted by Uli Köhler in Hardware

Dateigröße in NodeJS bestimmen

Um in NodeJS die Größe einer Datei zu bestimmen (z.B. die Größe von test.txt) benutze fs.stat() oder fs.statSync(). Beispiel:

const fs = require("fs"); //Dateisystem-Modul laden
const stats = fs.statSync("myfile.txt");
const fileSizeInBytes = stats.size;
// Optional: Dateigröße in Megabytes konvertieren
const fileSizeInMegabytes = fileSizeInBytes / 1000000.0;

Oder benutze die Folgende Funktion:

function getFilesizeInBytes(filename) {
    const stats = fs.statSync(filename);
    const fileSizeInBytes = stats.size;
    return fileSizeInBytes;
}

Beispiel:

getFilesizeInBytes("test.txt");
Posted by Uli Köhler in NodeJS

Welche Windows 10-Version läuft bei mir? Finde es in 15 Sekunden heraus!

Um herauszufinden, welche Windows 10-Version und welcher Build auf deinem Computer läuft, drücke zuerst die Windows-Taste + R.
Dies öffnet dieses Eingabefenster:

Gib in diesem Dialog winver ein:

Jetzt drücke Enter (auch bekannt als Return). Dies öffnet das Windows 10-Versionsfenster:

In diesem Fenster kannst du sofort die Versionsnummer und Buildnummer sehen, hier markiert in rot:

In meinem Beispiel ist das Version 1809 und Build 17763.475

Posted by Uli Köhler in Windows

iotop ‚Netlink error: Vorgang nicht zulässig (1)‘ beheben

Problem:

Du versuchst, iotop zu starten, aber siehst nur diese Fehlermeldung:

Netlink error: Vorgang nicht zulässig (1)

The Linux kernel interfaces that iotop relies on now require root priviliges
or the NET_ADMIN capability. This change occured because a security issue
(CVE-2011-2494) was found that allows leakage of sensitive data across user
boundaries. If you require the ability to run iotop as a non-root user, please
configure sudo to allow you to run iotop as root.

Please do not file bugs on iotop about this.

Lösung:

Starte iotop als root:

sudo iotop

Der Grund dafür ist, dass iotop auf Kernel-Interfaces Zugriff benötigt, die nur root oder Prozessen/Nutzern mit der CAP_NET_ADMIN-capability zugänglich sind. Theoretisch könnte man dem iotop-binary diese capability mit sudo setcap cap_net_admin+ep /usr/sbin/iotop geben, unter Ubuntu 18.04 hat dies für mich allerdings nicht funktioniert.

Posted by Uli Köhler in Linux

String in die Zwischenablage kopieren mit Javascript (ohne Bibliotheken)

Um in Javascript einen String in die Zwischenablage zu kopieren ohne eine externe Bibliothek wie clipboard.js zu verwenden, verwende diese Funktion:

function copyStringToClipboard (str) {
   // Temporäres Element erzeugen
   var el = document.createElement('textarea');
   // Den zu kopierenden String dem Element zuweisen
   el.value = str;
   // Element nicht editierbar setzen und aus dem Fenster schieben
   el.setAttribute('readonly', '');
   el.style = {position: 'absolute', left: '-9999px'};
   document.body.appendChild(el);
   // Text innerhalb des Elements auswählen
   el.select();
   // Ausgewählten Text in die Zwischenablage kopieren
   document.execCommand('copy');
   // Temporäres Element löschen
   document.body.removeChild(el);
}

Warnung: Sollte der Benutzer beim Aufruf der Funktion Text auf der Seite ausgewählt haben, wird diese Auswahl gelöscht. Dieser Hackernoon-Artikel stellt hierfür eine Lösung vor (englisch), wir konzentrieren uns hier jedoch auf die einfachstmögliche Lösung.

Du kannst die Funktion zum Beispiel so benutzen:

copyStringToClipboard("abc123");

Browser-Kompatibilität

Unsere Lösung benutzt nur Standard-Javascript (ES6 ist nicht notwendig), das DOM-API (das bereits mehrere Jahrzehnte alt ist) und document.exec('copy'); , welches laut dem Mozilla Developer’s network kompatibel mit allen großen Browsern, einschließlich Internet Explorer ab IE9, ist.

Wie funktioniert das genau?

Wir erzeugen eine neue, temporäre <textarea> und setzen deren Wert auf den zu kopierenden String (zum Beispiel "abc123" in unserem o.g. Beispiel).

Um den Nutzer und insbesondere Screenreader nicht zu verwirren, setzen wir die <textarea> auf readonly (d.h. nicht editierbar) und schieben sie -9999px nach links aus dem Viewport hinaus. In allen praktischen Szenarien liegt die <textarea> dann weit außerhalb des sichtbaren Bildschirms.

Erst nachdem wir die <textarea> aus dem sichtbaren Viewport herausgeschoben haben, fügen wir sie zum DOM hinzu, sodass sie nichteinmal für den Bruchteil einer Sekunde angezeigt werden könnte.

Nun können wir den Text innerhalb der <textarea> mit el.select() auswählen und dann mit document.execCommand('copy'); in die systemweite Zwischenablage kopieren.

Schlussendlich können wir die <textarea> wieder aus dem DOM entfernen.

Danke an  Angelos Charalis auf Hackernoon für die Idee, die Textarea aus dem Viewport zu verschieben.

 

Posted by Uli Köhler in Javascript

ElasticSearch: Cluster-Zustand (cluster health) mit curl anzeigen

Um den aktuellen Zustand (cluster health) eines ElasticSearch-Clusters anzuzeigen, benutze

curl -X GET "http://localhost:9200/_cluster/health?pretty=true"

Falls der ElasticSearch-Cluster nicht auf localhost läuft, ersetzt localhost mit dem Hostnamen oder der IP-Adresse eines der ElasticSearch-Konten.

Beispielausgabe:
{
  "cluster_name" : "docker-cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "active_primary_shards" : 0,
  "active_shards" : 0,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

Die wichtigsten Informationen sind:

  • "cluster_name" : "docker-cluster" Der Name, den du deinem Cluster zugewiesen hast. Alle ElasticSearch-Knoten im Cluster müssen denselben Cluster-Namen haben, sonst verbinden sie sich nicht zu einem Cluster.
  • "number_of_nodes" : 1 Die Anzahl der Cluster-Knoten, die aktuell im Cluster aktiv sind. Manchmal benötigen einige Knoten etwas länger, um hochzufahren, wenn sie gerade erst gestartet worden sind. Daher: Sollten nicht genug Knoten aufgelistet werden, warte eine Minute und versuche es nochmal.
  • "status" : "green" Der Cluster-Zustand (engl. cluster health) deines Clusters

Der Cluster-Zustand kann drei Werte annehmen:

  • green: Mit deinem Cluster ist alles OK (wie in unserem Beispiel)
  • yellow: Dein Cluster ist grundsätzlich OK, aber einige Shards konnten nicht repliziert werden. Dies ist oft der Fall, wenn du einen Cluster mit nur einem Knoten betreibst (dann gibt es keinen zweiten Knoten, auf den die Shards repliziert werden können – fällt der eine Knoten aus, können die Daten nicht wiederhergestellt werden)
  • red: Etwas stimmt nicht mit dem Cluster. Du musst im Log nachsehen

Du möchtest möglichst einfach einen ElasticSearch-Cluster mit Docker aufsetzen? TechOverflow bietet für diesen Zweck einen einfachen Konfigurations-Generator an: ElasticSearch docker-compose.yml and systemd service generator (engl).

Siehe auch die offizielle Reference zu Cluster Health (engl.)

Posted by Uli Köhler in Datenbanken, ElasticSearch

Docker: Alle Container und Images/Abbilder löschen

Problem:

Du benutzt Docker, aber die Arbeit damit hinterlässt viele Container und Container-Abbilder (Images) auf deiner Festplatte. Du möchtest alle Container stoppen und alle Abbilder löschen, um Speicherplatz auf deiner Festplatte einzusparen.

Continue reading →

Posted by Uli Köhler in Container, Docker

Dateien löschen mit der C++17-filesystem-Bibliothek

Um eine Datei (zum Beispiel test.txt) in C++ zu löschen benutze remove aus der C++17-filesystem-Bibliothek:

remove("test.txt");

Vollständiges Beispiel:

#include <experimental/filesystem>
using namespace std::experimental::filesystem;

int main() {
    remove("test.txt");
}

Mit GCC musst du die Datei wie Folgt kompilieren:

g++ -o delete-cpp17 delete-cpp17.cpp -lstdc++fs

Die stdc++fs-Bibliothek muss gelinkt werden, um die Funktionen aus der C++17-Filesystem-Bibliothek einzubinden.

remove löscht Verzeichnisse nicht rekursiv, also können nur leere Verzeichnisse gelöscht werden! Benutze für das Löschen eines Verzeichnisses inklusive aller Unterverzeichnisse und darin enthaltenen Dateienremove_all oder lies unseren Post dazu: Dateien und Ordner rekursiv löschen mit der C++17-filesystem-Bibliothek

Posted by Uli Köhler in C++

Dateien und Ordner rekursiv löschen mit der C++17-filesystem-Bibliothek

Um mit der C++17-filesystem-Bibliothek ein Verzeichnis rekursiv zu löschen (zum Beispiel mein-verzeichnis), benutze remove_all:

remove_all("mein-verzeichnis");

Diese Zeile löscht mein-verzeichnis und alle darin enthaltenen Unterverzeichnisse und Dateien (= rekursiv).

Vollständiges Beispiel:

#include <experimental/filesystem>
using namespace std::experimental::filesystem;

int main() {
    remove_all("mein-verzeichnis");
}

Mit GCC musst du die Datei wie Folgt kompilieren:

g++ -o delete-cpp17 delete-cpp17.cpp -lstdc++fs

Die stdc++fs-Bibliothek muss gelinkt werden, um die Funktionen aus der C++17-Filesystem-Bibliothek einzubinden.

Falls du stattdessen nur ein leeres Verzeichnis oder eine einzelne Datei löschen möchtest (ohne Unterverzeichnisse), benutze remove anstatt remove_all oder lies unseren Post dazu: Dateien löschen mit der C++17-filesystem-Bibliothek

Posted by Uli Köhler in C++