Schlagwort-Archive: Linux

Stack: Ubuntu, Webmin, nginx, PostgreSQL, Samba, Symfony

Quellen:

https://ubuntu.com/

https://www.nginx.com/

https://symfony.com/

https://www.postgresql.org/

Ubuntu

Mehr Informationen:

https://ubuntu.com/tutorials/install-ubuntu-desktop#1-overview

SSH installieren

sudo apt install openssh-server
sudo systemctl status ssh
sudo systemctl enable ssh
sudo systemctl start ssh
sudo reboot

Einwahl über SSH-Client, wie bspw. Putty

Mehr Informationen:

https://www.ionos.de/digitalguide/server/konfiguration/ubuntu-ssh/

IPv6 ausschalten

sudo nano /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash ipv6.disable=1"
GRUB_CMDLINE_LINUX="ipv6.disable=1"
sudo update-grub
sudo reboot

Mehr Informationen:

https://itsfoss.com/disable-ipv6-ubuntu-linux/

Shell pimpen

sudo apt-get install trash-cli # Papierkorb
sudo cp /etc/bash.bashrc /etc/bash.bashrc.bak
sudo nano /etc/bash.bashrc
alias +='pushd .'
alias ..='cd ..'
alias ...='cd ../..'
alias dir='ls -la  --color=auto'
alias d='ls -la  --color=auto'
alias gzcat='gunzip -c'
alias l='ls -alF'
alias la='ls -la'
alias ll='ls -la'
alias ls='/bin/ls $LS_OPTIONS'
alias ls-l='ls -l'
alias md='mkdir -p'
alias o='less'
alias rd='rmdir'
alias rehash='hash -r'
alias rm='rm -i'
alias unzip='tar xfvz'
alias which='type -p'
alias zip='tar cfvz'
alias sudo='sudo '
alias del='trash -rf'
sudo nano ~/.bashrc # ein kürzerer Prompt
GREEN="\[$(tput setaf 2)\]"
RESET="\[$(tput sgr0)\]"
PS1="${GREEN}$${RESET}"

Mehr Informationen:

https://1manfactory.com/pimp-my-shell-eine-vernuenftige-arbeitsumgebung-fuer-linux/

ein Zusatz-Admin zur Sicherheit

sudo adduser <NUTZER>
sudo adduser <NUTZER> sudo

Webmin

sudo apt update
curl -fsSL https://download.webmin.com/jcameron-key.asc | sudo gpg --dearmor -o /usr/share/keyrings/webmin.gpg
sudo nano /etc/apt/sources.list
deb [signed-by=/usr/share/keyrings/webmin.gpg] http://download.webmin.com/download/repository sarge contrib
sudo apt update
sudo apt install webmin
# Browser: http://<HOST>:10000

Mehr Informationen:

https://www.digitalocean.com/community/tutorials/how-to-install-webmin-on-ubuntu-22-04

nginx

sudo apt update
sudo apt install nginx
sudo systemctl status nginx
# Browser: http://<HOST>
sudo systemctl stop nginx # Stoppen
sudo systemctl start nginx # Starten
sudo systemctl restart nginx # Neustart
sudo systemctl reload nginx # sanfter Neustart nach Neu/Re-Konfiguration
sudo systemctl disable nginx # Autostart (Default) verhindern
sudo systemctl enable nginx # Autostart wieder ermöglichen

Rechte für /var/www/html

sudo chown -R www-data: /var/www/html/
sudo find /var/www/html -type f -exec chmod 664 {} + -o -type d -exec chmod 775 {} +
sudo usermod -a -G www-data $USER
exit # Neueinwahl nötig

PHP für nginx

sudo apt-get install php8.1-fpm
sudo systemctl status php8.1-fpm # läuft der PHP-Service?
sudo nano /etc/nginx/sites-available/default

Folgendes muss angepasst werden:

  • index.php zur Indexliste hinzufügen (Zeile 8)
  • Entkommentieren der Zeilen 17, 18, 21, 24, 28, 29 und 30
server {
  # Example PHP Nginx FPM config file
  listen 80 default_server;
  listen [::]:80 default_server;
  root /var/www/html;

  # Add index.php to setup Nginx, PHP & PHP-FPM config
  index index.php index.html index.htm index.nginx-debian.html;

  server_name _;

  location / {
    try_files $uri $uri/ =404;
  }

  # pass PHP scripts on Nginx to FastCGI (PHP-FPM) server
  location ~ \.php$ {
    include snippets/fastcgi-php.conf;

    # Nginx php-fpm sock config:
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    # Nginx php-cgi config :
    # Nginx PHP fastcgi_pass 127.0.0.1:9000;
  }

  # deny access to Apache .htaccess on Nginx with PHP, 
  # if Apache and Nginx document roots concur
  location ~ /\.ht {
    deny all;
  }
} # End of PHP FPM Nginx config example
sudo nginx -t # um die Änderungen an der Konfiguration zu testen
sudo systemctl restart nginx # Neustart des Servers

Mehr Informationen:

https://1manfactory.com/nginx-ubuntu-php-fpm/

PHPINFO

sudo echo "<?php phpinfo(); ?>" >> /var/www/html/info.php
# Browser http://<HOST>/info.php

nginx-Modul für Webmin

Webmin -> Webmin Configuration -> Webmin Modules
Install from “From HTTP or FTP URL”
Quelle: https://github.com/Sumarious/nginx-webmin/raw/master/nginx.wbm.gz

Mehr Informationen:

https://github.com/Sumarious/nginx-webmin

https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04

Composer

sudo apt update
sudo apt install php-cli unzip # benötigt
cd ~
curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
HASH=`curl -sS https://composer.github.io/installer.sig`
echo $HASH
php -r "if (hash_file('SHA384', '/tmp/composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
composer

Mehr Informationen:

https://www.digitalocean.com/community/tutorials/how-to-install-and-use-composer-on-ubuntu-22-04

PostgreSQL

sudo apt update
sudo apt install postgresql postgresql-contrib
sudo systemctl start postgresql.service
sudo systemctl status postgresql

Mehr Informationen:

https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-20-04

PostgreSQL in Webmin

Webmin -> Refresh Modules
Servers -> PostgreSQL Database Server

HeidiSQL für PostgreSQL

WICHTIG: IP6 muss deaktiviert sein (siehe oben)

sudo nano /etc/postgresql/14/main/postgresql.conf
listen_addresses = '*'
sudo nano /etc/postgresql/14/main/pg_hba.conf
# IPv4 local connections:
#host    all      all             127.0.0.1/32		scram-sha-256
host     all       all            0.0.0.0/0		scram-sha-256
sudo service postgresql restart

Da IP6 jetzt deaktiviert ist, muss noch eine Einstellung für nginx dringend angepasst werden:

sudo nano /etc/nginx/sites-available/default
#listen [::]:80 default_server; dieser Eintrag muss deaktiviert sein, wenn kein IP6
sudo systemctl restart nginx # nginx neu starten

neuer User für PostgreSQL

Webmin -> PostgreSQL -> PostgreSQL Users -> Create a new user

Samba

sudo apt-get install samba
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf_backup # Kopie schadet nie
systemctl status smbd # Status prüfen
sudo nano /etc/samba/smb.conf
[www]
  comment = Web Root Dir
  path = /var/www/html
  valid users = @www-data
  browseable = yes
  public = no
  writable = yes
  printable = no
  create mode = 0644
  directory mode = 0775
  force group = www-data
  force user = www-data
sudo usermod -aG www-data $USER
sudo smbpasswd -a $USER # für jeden Nutzer notwendig, der Samba nutzen soll
sudo service smbd restart
systemctl status smbd
sudo smbstatus --shares # zeigt aktive Verbindungen

In der Windows-Kommandozeile eine Verbindung herstellen:

net use X: \\<HOST>\www /user:<USER> <PASSWORD>

Symfony

Symfony-cli Binary installieren

sudo apt-get install php-xml # wird noch benötigt
cd ~
curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.deb.sh' | sudo -E bash
sudo apt install symfony-cli

ein neues Symfony-Projekt anlegen

sudo chown -R www-data:www-data /var/www/html/
sudo find /var/www/html/ -type d -exec chmod 775 {} \;
sudo find /var/www/html/ -type f -exec chmod 664 {} \;
sudo find /var/www/html/ -type d -exec chmod g+s {} \;
cd /var/www/html/
symfony new --webapp testprojekt
cd testprojekt/
composer require --dev symfony/profiler-pack
symfony server:start -d # Symfony Server starten

Aufruf über Symfony Server

Aufruf über nginx

Git und GitHub für Windows mit Sourcetree, Teil 3: Branches, Pull Requests und Fetch

Das Thema Branches ist sehr wichtig für die Arbeit mit GitHub. Im Grunde kommt man nicht an ihnen vorbei, spätestens wenn man nicht mehr allein an einem Projekt arbeitet.

Was sind Branches?

In Git sind Branches (dt. Zweige) Versionen des Projekts, die sich inhaltlich voneinander unterscheiden und dabei gleichzeitig parallel existieren können.

Branches sind eine wichtige Funktion in Git, da sie es Entwicklern ermöglichen, verschiedene Ideen oder Experimente gleichzeitig auszuprobieren, ohne die ursprüngliche Version des Projekts zu beeinträchtigen. Zum Beispiel kann man einen neuen Branch erstellen, um eine neue Funktion auszuprobieren, während der Haupt-Branch stabil bleibt. Wenn die neue Funktion erfolgreich getestet wurde, kann sie in den Haupt-Branch übernommen („gemerged“) werden.

Git ermöglicht auch, zwischen Branches zu wechseln und zu arbeiten, wodurch Entwickler effizienter arbeiten können, ohne dass sie separate Arbeitskopien erstellen müssen.

Das Wechseln zwischen Branches ist einfach und schnell, sodass Entwickler problemlos zwischen verschiedenen Versionen ihres Projekts navigieren können.

Wir legen einen neuen Branch an

  1. Öffnen Sie Ihr Repository in Sourcetree.
  2. Klicken Sie auf den Button „Branch“ in der oberen Menüleiste.
  3. Klicken Sie auf den Reiter „New Branch“ im neuen Fenster.
  4. Geben Sie einen Namen für Ihren neuen Branch ein und wählen Sie den Branch aus, von dem Sie den neuen Branch ableiten möchten. Standardmäßig wird der neue Branch von dem aktuell ausgewählten Branch (hier: main) abgeleitet.
  5. Klicken Sie auf den Button „Create Branch“.

Ich nenne den neuen Branch „new_feature“. Allerdings werden wir kein neues Feature einführen, sondern lediglich an der schon bekannten Datei „README.md“ etwas ändern.

Fortan wollen wir also im „new_feature“-Branch arbeiten. In unserem Repository wird aber weiterhin das Projekt in seiner ursprünglichen Version verbleiben und parallel existieren.

Mit einem Doppelklick auf der linken Seite auf den Namen der Branch springen wir zwischen „main“ und „new_feature“ hin und her.

Wir fügen jetzt in unserer bekannten Datei „README.md“ eine neue Zeile, genauer eine neue Überschrift hinzu. Außerdem ist mir gerade aufgefallen, dass ich „turotial“ statt „tutorial“ geschrieben habe. Das wird auch korrigiert.

Nach dem Speichern wechseln wir wieder zu Sourcetree und sehen nach wenigen Sekunden Wartezeit erwartungsgemäß unsere Datei wieder im Status „Unstaged“. Rechts oben erkennen wir die vorgenommenen Änderungen.

Wie bereits durchexerziert, schieben wir die Datei in den „Staged“ Bereich und führen anschließend ein Commit durch.

Nun sehen wir einen veränderte History-Bereich:

In dem neuen Branch wurden die Änderungen übernommen. Klicken wir nun wieder auf den ursprünglichen Branch, sehen wir noch den alten, ursprünglichen Stand der Datei.

Jetzt sorgen wir mit „Push“ dafür, dass die veränderte Datei bei GitHub landet. Im aufgehenden Fenster nehmen Sie bitte folgende Anpassungen vor:

Und wieder ist eine kleine Änderung im History-Bereich zu sehen.

Schauen wir jetzt in GitHub nach, was passiert ist. Sie wechseln jetzt in den Status, und damit in die Perspektive, des Administrators. Sie sind also jetzt eine andere Person als die, die die Änderungen vorgenommen hat.

GitHub weist uns darauf hin, dass ein neuer Branch angelegt worden ist und dass in diesen Branch neue Dateien (in unserem Falle nur eine) gepusht wurden.

Da wir uns aber noch im Hauptbranch „main“ befinden, sind die Änderungen noch nicht zu sehen – was ja Sinn der Aktion war. Denn noch wissen wir nicht, ob die Änderungen fehlerfrei sind und bei den anderen (spekulativen) Administratoren im Projekt Akzeptanz finden.

Wir zeigen jetzt den Branch „new_feature“ an. Dazu drücken wir den Dropdown-Button mit der Aufschrift „main“ und wechseln auf „new_feature“

Wir sehen jetzt den neuen Branch „new_feature“

Dieser Branch hat jetzt (auch wieder wie erwartet) unsere Änderungen und befindet sich „1 commit ahead of main“. Was bedeutet das?

Der aktuelle Branch hat einen Commit mehr als der Branch „main“. Die Änderungen im neuen Feature-Branch wurden noch nicht in den „main“-Branch übertragen (=gemerged). Auch das ist ein schlüssiges, gewolltes Verhalten von git bzw. GitHub.

Compare & pull request

Sehen Sie den Button mit der Aufschrift “Compare & pull request”?

„Compare“ und „Pull Request“ sind Funktionen in Git und GitHub, die es Entwicklern ermöglichen, Änderungen an einem Repository vorzuschlagen und sie in den Hauptzweig (z.B. „main“ oder „master“) zu integrieren.

„Compare” ermöglicht es, den Unterschied zwischen zwei Branches aufzuzeigen, indem Änderungen, die gemacht wurden, gegenübergestellt werden. Dadurch können Entwickler sehen, welche Dateien und Zeilen geändert wurden und welche Auswirkungen die Änderungen haben werden.

Ein „Pull Request“ ist eine Anfrage an den Repository-Administrator (in diesem Falle ausschließlich an uns selbst), um Änderungen in den Hauptzweig des Repositorys zu übernehmen. Der Administrator kann dann die Änderungen überprüfen, Kommentare dazu abgeben und sie gegebenenfalls genehmigen und zusammenführen oder auch ablehnen.

Nach Klick auf den Button „Compare & pull request“ gibt es folgendes Fenster in GitHub.

Wir sehen praktischerweise schon den Kommentar, den wir beim Commit der Änderungen angegeben haben. Es gibt aber auch die Möglichkeit, einen längeren, erkenntnisreichen Kommentar zu hinterlassen.

Wenn wir etwas nach unten scrollen, sehen wir die erfolgten Änderungen im Detail, wie wir es schon in Sourcetree kennenlernen durften.

Mit „Create pull request“ werden wir nun die Anfrage an den Administrator (auch wenn wir das selbst sind) stellen, unseren neuen Code in dem Branch „new_feature“ zu kontrollieren und bei Akzeptanz, in den Haupt-Branch „main“ zu übernehmen.

Schauen wir, was passiert, wer wir den Knopf drücken. Es öffnet sich ein neues Fenster im Browser.

Die Änderungen akzeptieren

Wir sehen oben die Überschrift des Commits, eine Beschreibung hatten wir nicht angegeben. Interessanterweise kann GitHub schon feststellen, dass es voraussichtlich keine Konflikte beim Zusammenführen der README.md-Datei auf dem Hauptbranch geben wird.

Bevor wir den Request jetzt final akzeptieren, scrollen wir noch kurz nach unten.

Hier könnten wir, wenn wir wollten, den Request ablehnen (und vorher noch einen Kommentar dazu hinterlassen.)

Aber wir haben uns ja dazu entschieden, den Request zu akzeptieren, also drücken wir beherzt auf „Merge pull request“.

Nach einer kleinen Zwischenfrage, auf die wir einen kleinen Kommentar (z.B. einen Dank an den fleißigen Programmierer) hinterlassen können, drücken wir jetzt aber wirklich final auf „Confirm merge“.

So sieht dann das Ergebnis aus:

Der Pull request wurde erfolgreich eingebunden und wurde jetzt geschlossen. Der Administrator hat nun noch die Gelegenheit den „new_feature“-Branch zu löschen oder nicht.

Es hängt von den individuellen Projektanforderungen und -richtlinien ab, ob er dies tut. Einige Teams bevorzugen das Löschen des Feature-Branches, um eine saubere und übersichtliche Branch-Historie zu erhalten, während andere Teams den Feature-Branch behalten möchten, um mögliche zukünftige Probleme leichter zu identifizieren und zu debuggen.

Es gibt jedoch auch Kompromisslösungen, wie zum Beispiel das Umbenennen des Feature-Branches in einen entsprechenden Namen, um anzuzeigen, dass er bereits gemerged wurde. In jedem Fall ist es wichtig, klare Richtlinien für das Branching-Verhalten im Team zu definieren und sicherzustellen, dass alle Teammitglieder diese Richtlinien verstehen und befolgen.

So sieht jetzt der Hauptbranch aus. Die Änderungen wurden komplett übernommen.

Die Änderungen im lokalen Repository – Pull oder Fetch

Damit jetzt alle am Projekt Beteiligten wieder auf den gleichen Stand der Entwicklung kommen – z.B. am Beginn eines neuen Arbeitstages, müssen sie die aktuellen Änderungen aus dem entfernten (remote) Repository auf GitHub übernehmen. Das schließt übrigens auch den Einreicher des „Pull requests“ selbst mit ein, denn er weiß ja noch nicht, dass seine Änderungen akzeptiert worden sind.

Um das zu erreichen, gibt es die Befehle „pull“ und „fetch“, die beide dafür da sind, Änderungen aus dem entfernten Repository zu übernehmen, sich aber in einem wichtigen Punkt unterscheiden.

Der Befehl „fetch” ruft alle Änderungen ab, die in einem Remote-Repository vorgenommen wurden, ohne diese in das lokale Repository zu integrieren. Dadurch können Sie sehen, welche Änderungen in dem Remote-Repository vorliegen, bevor Sie entscheiden, ob Sie sie zusammenführen möchten oder nicht.

Im Gegensatz zum Befehl „pull“ führt „fetch“ keine automatische Zusammenführung durch. Stattdessen müssen Sie entscheiden, ob Sie die Änderungen in Ihr lokales Repository integrieren möchten. Wir werden das jetzt mal machen.

Nach Klick auf „Fetch“ in der oberen Menüleiste erhalten wir drei Optionen zur Auswahl:

„Fetch from all remotes“ in Git bedeutet, dass alle Remote-Repositories, die mit dem lokalen Repository verbunden sind, nach Aktualisierungen durchsucht werden.

“Prune tracking branches no longer present on remote(s)?” entfernt die lokalen Tracking-Branches irreversible, die nicht mehr auf dem Remote-Repository vorhanden sind.

„Fetch all tags“ lädt alle Tags aus dem Repository herunter. Ein Tag ist ein Name, der einem bestimmten Commit zugewiesen wird, um ihn zu markieren. Es kann nützlich sein, alle Tags herunterzuladen, um sicherzustellen, dass Sie alle Informationen zu bestimmten Commits haben, einschließlich Informationen zu veröffentlichten Versionen oder Meilensteinen.

Ich belasse es fürs Erste bei den Default-Einstellungen.

Als Ergebnis erhalten wir … nichts, oder zumindest keine Änderungen. Woran liegt das? Das ist in unserem Falle leicht zu erklären, da wir ja die Einzigen sind, die Änderungen vorgeschlagen haben. Dementsprechend werden uns keine Differenzen aus anderen Pull/Merge requests angezeigt.

Wir können daher beruhigt „Pull“ in der Menüzeile drücken, um den Abgleich mit dem remote Repository abzuschließen

Nun haben wir vier Optionen zur Auswahl.

Mit „Commit merged changes immediately“ wird Git automatisch einen neuen Commit erstellen, der die zusammengeführten Änderungen beim Zusammenführen von Branches enthält. Wenn Sie das nicht möchten, bspw. aus Kontrollgründen, müssen Sie das später von Hand machen.

„Include messages from commits merged in merge commit“. Wenn diese Option ausgewählt ist, werden die Commit-Messages der zusammengeführten Commits in den Merge-Commit übernommen. Ich würde aus Gründen der Übersichtlichkeit darauf verzichten.

„Create a new commit even if fast-forward is possible?“ lassen wir fürs Erste deaktiviert, ansonsten könnten wir die neuen Commits aus dem Merge nicht mehr rückgängig machen.

„Rebase instead of merge“ – dieser Punkt dient dazu, die komplette Commit-Historie in einem linearen Verlauf zusammenzuführen. Das kann übersichtlicher sein, kann aber dazu führen, dass Informationen verloren gehen. Bei neuen Projekten sollte man sich einmalig festlegen, welcher der beiden Methoden genutzt wird. Es sollte tunlichst darauf geachtet werden, beide Methoden nicht zu vermischen. Ich lasse dieses Feld deaktiviert, da ich immer der Merge-Methode den Vorzug vor Rebase gebe.

Ich setze jetzt lediglich den Haken bei „Commit merged changes immediatly“, da ich davon ausgehe, dass beim Merge in GitHub alles richtig war.

Wie Sie sehen, hat sich nichts großartig getan, außer dass die kleine „2“ verschwunden ist, denn jetzt haben wir eigentlich unsere zuvor selbst erstellten Änderungen „gepullt“ haben. Das Ergebnis wäre ein anderes, wenn wir auch Änderungen anderer Personen übernommen hätten. Das werden wir im nächsten Kapitel sehen.

Zusammenfassung: Wir wissen nun, wie wir Änderungen über einen neuen Branch zu GitHub einspielen, wie wir diese Änderungen in den Hauptbranch einfügen und wie wir externe Änderungen im Code in unser Repository übernehmen können.

Bash Script Vorlage mit Parameter-Verarbeitung

Wer Skripte für die Bash auf Linux selbst erstellt, wird früher oder später den Wunsch verspüren, Parameter und Argumente verarbeiten zu können, um die Skripte flexibler zu gestalten.

Ich nutze dazu diese Vorlage:

#!/bin/bash
# /usr/local/bin/.../...
# Handy one-liner that explains what the program does.

function usage()
{
   cat << HEREDOC
   
   Handy one-liner that explains what the program does.
   
   Usage: $progname [--parameter1 NUM] [--parameter2 STR] [--parameter3 TIME_STR] [--verbose] [--dry-run]
          argument1 [argument2] [argument3] [ ... ]
   
   Example: $progname -d=5 /tmp/folder1/ /tmp/folder2/
            explain the example in detail

   optional parameter:
     -p, --parameter1 NUM        explain this parameter
     -q, --parameter2 STR        explain this parameter
     -r, --parameter3 TIME_STR   explain this parameter
     -h, --help                  show this help message and exit
     -v, --verbose               increase verbosity
     --dry-run                   dry run, dont change any files, folders or values

HEREDOC
}  

# parse the arguments before getopts, otherwise they will be lost
for i in "$@"; do
	if [[ $i = "-"* ]]; then
		:
	else                
		arguments+=("$i") # append the arguments to array
	fi
done

# initialize default parameter
progname=$(basename $0)
verbose=0
dryrun=0
parameter1=10
parameter2="Hello World!"
parameter3="2023-01-22 17:40:33"

# use getopt and store the output into $OPTS
# note the use of -o for the short options, --long for the long name options
# and a ":" for any option that takes a parameter
OPTS=$(getopt -o "p:q:r:hv" --long "parameter1:,parameter2:,parameter3:,help,verbose,dry-run" -n "$progname" -- "$@")
if [ $? != 0 ] ; then echo "Error in command line arguments. See '$progname -h/--help'." >&2 ; exit 1 ; fi
eval set -- "$OPTS"

while true; do
  # echo "\$1:\"$1\" \$2:\"$2\""
  case "$1" in
    -h | --help ) usage; exit; ;;
    -p | --parameter1 ) parameter1="$2"; shift 2 ;;
    -q | --parameter2 ) parameter2="$2"; shift 2 ;;
    -r | --parameter3 ) parameter3="$2"; shift 2 ;;
    --dry-run ) dryrun=1; shift ;;
    -v | --verbose ) verbose=$((verbose + 1)); shift ;;
    -- ) shift; break ;;
    * ) break ;;
  esac
done

if (( $verbose > 0 )); then

   # print out all the parameters we read in
   cat <<EOM
   p/parameter1=$parameter1
   q/parameter2=$parameter2
   r/parameter3=$parameter3
   verbose=$verbose
   dryrun=$dryrun
   arguments=${arguments[@]}
EOM
fi

# Now starts the magic

Wie nutzt man mehrere GitHub-Accounts auf einem Rechner?

Wenn Sie mehrere GitHub-Accounts haben und auf demselben Rechner arbeiten möchten, können Sie Ihre Git-Konfiguration anpassen, um sicherzustellen, dass die richtigen Anmeldeinformationen für die jeweiligen Repositories verwendet werden.

1. Legen Sie für jeden GitHub-Account, den Sie verwenden möchten, ein neues SSH-Schlüsselpaar an.

Zunächst prüfen wir, ob schon ein SSH-Schlüssel auf ihrem Rechner existiert:

ls -al ~/.ssh

Sollte kein Schlüssel angelegt sein, müssen wir eben einen erzeugen:

ssh-keygen -t rsa -b 4096 -C "Ihr Kommentar"

Es ist nicht unbedingt nötig, das Schlüsselpaar mit einem Passwort zu sichern – vorausgesetzt, Sie sind sich sicher, dass keine unbefugte Person Zugriff auf Ihr Home-Verzeichnis hat. Ich gehe folgendermaßen vor:

mkdir ~/.ssh
cd ~/.ssh
ssh-keygen -t rsa -b 4096 -C "Schlüssel 1 auf masch1"
ls -la

Das Schlüsselpaar nenne ich beispielhaft „id_rsa_01“

Im Verzeichnis befinden sich dann zwei zusammengehörende Dateien: „id_rsa_01“ und „id_rsa_01.pub“. Erstere beinhaltet den privaten und Letztere den öffentlichen Schlüssel.

Generierung eines RSA-Schlüsselpaares
ssh-keygen -t rsa -b 4096 -C "Schlüssel 1 auf masch1"
Generierung eines RSA-Schlüsselpaares

Man sollte sich den Inhalt beider Dateien einmal anschauen, um den Aufbau zu kennen.

cat id_rsa_01
cat id_rsa_01.pub
Der private RSA-Schlüssel
Der private RSA-Schlüssel
Der öffentliche RSA-Schlüssel
Der öffentliche RSA-Schlüssel

WICHTIG: Sie dürfen den privaten Schlüssel „id_rsa_01“ niemals an Dritte geben, schon gar nicht ohne eine Passwortsicherung. Ich werde nach dem Schreiben dieses Artikels das Schlüsselpaar löschen und ein neues anlegen, damit niemand es aus der Grafik kopieren kann.

2. Fügen Sie jeden öffentlichen SSH-Schlüssel Ihrem GitHub-Konto hinzu.

Um einen öffentlichen SSH-Schlüssel zu Ihrem GitHub-Konto hinzuzufügen, können Sie die folgenden Schritte ausführen:

Kopieren Sie den Inhalt der öffentlichen Schlüsseldatei (hier: ~/.ssh/id_rsa_01.pub) komplett in die Zwischenablage.

cat ~/.ssh/id_rsa_01.pub

Gehen Sie zu Ihrem GitHub-Konto und klicken Sie auf das Dropdown-Menü in der oberen rechten Ecke. Wählen Sie „Settings“ aus.

Klicken Sie im linken Menü auf „SSH and GPG Keys“.

Klicken Sie dann auf „new SSH key“

Geben Sie einen Titel für den Schlüssel ein (z.B. „RSA 1 Key für Maschine 1“). Behalten Sie die Auswahl „Authentication key“ bei. Fügen Sie den Inhalt des öffentlichen Schlüssels in das Feld „Key“ ein. Klicken Sie auf „Add SSH key“.

Danach sollten Sie folgenden Bildschirm erhalten:

Mehr Informationen zum Thema SSH und GitHub

Da wir mindestens zwei Schlüsselpaare für diese Aufgabe benötigen, legen Sie bitte gemäß Schritt 1 und 2 ein neues, zweites Paar an und nennen es „id_rsa_02“.

Anschließen öffnen Sie ihren zweiten GitHub-Account und fügen diesem den zweiten, privaten Schlüssel hinzu.

3. Konfigurieren Sie Git so, dass es den richtigen Schlüssel für jedes Repository verwendet.

Nun legen wir die Datei „~/.ssh/config“ an (wenn sie noch nicht existieren sollte) und bearbeiten sie.

nano ~/.ssh/config

Hier ein Beispiel

# Private github account: 1manfactory
Host github-private
   HostName github.com
   IdentityFile ~/.ssh/id_rsa_01
   IdentitiesOnly yes

# Company github account: Umbrella Corporation
Host github-umbrella
   HostName github.com
   IdentityFile ~/.ssh/id_rsa_02
   IdentitiesOnly yes

Falls Sie ihre Schlüsselpaare mit einem Passwort gesichert haben, sollten Sie beide Schlüssel dem SSH-Agenten hinzufügen. Somit werden Sie in dieser Session nur einmal nach dem Passwort gefragt, wenn Sie mit GitHub kommunizieren.

eval $(ssh-agent) # Sonderbefehl zum Start des SSH-Agenten
ssh-add ~/.ssh/id_rsa_01
ssh-add ~/.ssh/id_rsa_02
SSH-Agent: Schlüssel hinzufügen
SSH-Agent: Schlüssel hinzufügen

Damit es nicht zu einer Fehlermeldung kommt, müssen wir jetzt auch den öffentlichen Schlüssel von GitHub herunterladen. Der Befehl „ssh-keyscan“ sammelt öffentliche Schlüssel und speichert sie in der Datei „~/.ssh/known_hosts“, so dass Sie bei zukünftigen SSH-Verbindungen nicht mehr danach gefragt werden.

ssh-keyscan github.com >> ~/.ssh/known_hosts

Jetzt testen wir beide Verbindungen.

ssh -T git@github-private
ssh -T git@github-umbrella

4. Der Beweis: Wir klonen ein Repository und pushen eine Änderung

Wenn alles geklappt hat, sollte es inzwischen kein Problem mehr sein, ein Repository zu klonen.

eval $(ssh-agent) # den SSH-Agenten starten
cd ~
git clone git@github-private:1manfactory/demoprojekt.git # ein simples Demo
cd demoprojekt
dir
cat README.md
Ein Repository aus GitHub klonen per SSH-Schlüssel
Ein Repository aus GitHub klonen per SSH-Schlüssel

Bei Bedarf kann/sollte man noch die E-Mail-Adresse und den Namen für dieses lokale Repository anpassen:

git config user.email "name@domain.org"
git config user.name "Martin Mustermann"

Eine Datei können wir jetzt wie gewohnt ins Repository übernehmen (=commit) und zu GitHub übertragen (=push).

nano README.md # ein bisschen was ändern
git add .
git commit -m "zweites commit von lokal"
git push # und hochladen nach GitHub

Pimp my shell – Eine vernünftige Arbeitsumgebung für Linux

Immer, wenn ich ein neues Linux aufsetze, führe ich bestimmte Kommandos durch bzw. konfiguriere ich mein System so, dass ich vernünftig damit arbeiten kann. Jeder hat seine Eigenheiten und Bedürfnisse – hier skizziere ich mal die meinen.

Zunächst installieren wir uns sudo, um als normaler Nutzer auch wie ein Supernutzer (=root) agieren zu können, ohne uns als root anmelden zu müssen. Natürlich müssen wir diese eine Installation selbst noch als root vornehmen. Danach müssen wir uns nie wieder als root anmelden – außer ins Notfällen.

apt-get install sudo

Nun fügen wir den während der Installation angelegten Nutzer der Gruppe „sudo“ hinzu: adduser sudo. In meinem Falle also den Nutzer „juergen“

adduser juergen sudo

Mit dem Befehl groups <username> kann man prüfen, ob das Hinzufügen tatsächlich geklappt hat.

groups juergen

Das war es schon. Jetzt bitte mit exit wieder aus der Shell ausloggen und als normaler Nutzer wieder einloggen. Jetzt kann man mit einem vorangestellten sudo Befehle wie root ausführen.

Testen wir unsere neuen Fähigkeiten, indem wir gleich einmal einen vernünftigen Editor installieren.

sudo apt-get install nano

Mit diesem Editor nehmen wir unsere erste Anpassung vor. Wir sorgen dafür, dass ab jetzt jeder neue Nutzer mit der bin/bash Shell verbunden wird.

sudo cp /etc/adduser.conf /etc/adduser.conf.bak # Kopie schadet nie
sudo nano /etc/adduser.conf

Im Editor suchen wir jetzt folgende Zeile (oder fügen sie, falls nicht vorhanden, hinzu):

DSHELL=/bin/bash

Nun installieren wir uns einen Papierkorb für Linux.

sudo apt-get install trash-cli
trash DATEI # DATEI in Papierkorb veschieben
trash-list # Dateien im Papierkorb auflisten
restore-trash # interaktiv Dateien wieder herstellen
alias del='trash -rf' # del verschiebt ab jetzt in den Papierkorb

Als Nächstes sorgen wir dafür, dass unser System gleich mit den wichtigsten Alias-Befehlen versorgt wird. Mit einem alias kann man mehrere Linux-Kommandos, oder ein Linux-Kommando mit mehreren Optionen durch einen neuen Befehl ersetzen. Es wird benutzt, um Zeit zu sparen und weniger zu tippen.

Das bekannteste alias dürfte wohl die Abkürzung dir für den Befehl „ls -l“ sein.

Wir bearbeiten wieder eine Konfigurationsdatei.

sudo cp /etc/bash.bashrc /etc/bash.bashrc.bak #  Kopie schadet nie
sudo nano /etc/bash.bashrc

Und fügen ans Ende folgende Zeilen hinzu:

alias +='pushd .'
alias ..='cd ..'
alias ...='cd ../..'
alias dir='ls -la --color=auto --group-directories-first -v'
alias d='ls -la --color=auto --group-directories-first -v'
alias gzcat='gunzip -c'
alias l='ls -alF'
alias la='ls -la'
alias ll='ls -la'
alias ls='/bin/ls $LS_OPTIONS'
alias ls-l='ls -l'
alias md='mkdir -p'
alias o='less'
alias rd='rmdir'
alias rehash='hash -r'
alias rm='rm -i'
alias unzip='tar xfvz'
alias which='type -p'
alias zip='tar cfvz'
alias sudo='sudo '
alias del='trash -rf'
source /etc/bash.bashrc # Änderungen werden sofort wirksam

Und schon sieht unsere Shell sehr viel bunter, schöner, übersichtlicher aus.

Ich selbst bevorzuge auch einen minimalen Prompt.

sudo nano ~/.bashrc
export PS1='\[\e[32m\]$\[\e[0m\] '
source ~/.bashrc # Änderungen werden sofort wirksam