Posts Tagged ‘Bash’

Donnerstag, 14. Oktober 2021

OpenInTerminal meldet „Waiting…“

Vor einiger Zeit habe ich hier im Artikel Öffne Terminal mit dem aktuellen macOS Finder-Pfad über die macOS Finder-Erweiterung OpenInTerminal geschrieben.

Folgendes Problem tritt dabei periodisch auf: Klickt man auf das Finder-Icon, heisst es im aufklappenden Dialog lapidar „Waiting…“

Die Lösung, eine Antwort auf meinen Bug-Report: Option-Klick auf Finder und Relaunch anwählen.

Tags: , , , , , , ,
Labels: Apple, IT

Keine Kommentare | neuen Kommentar verfassen

Freitag, 6. November 2020

Trump oder Biden? Gezählte Stimmen im Live-Stream (für Geeks)

Genial: alex/nyt-2020-election-scraper

Web GUI (inkl. Notifications)

alex.github.io/nyt-2020-election-scraper/battleground-state-changes.html

Kommandozeile

Jemand auf der Arbeit hat sich ein Kommandozeilentool gebaut, welches ihm die Veränderungen in Arizona auflistet. Ich gehe davon aus, dass er diese Text-Datei alle paar Minuten abruft, parst, und dann das neueste Resultat ausgibt: battleground-state-changes.txt

Ich habe es auch versucht, und glaub‘ ich hingekriegt:

$ watch -n 60 ./potus-2020-vote-stream.sh

watch ruft das untenstehende Script alle 60 Sekunden auf.

potus-2020-vote-stream.sh enthält folgenden Code:

#!/bin/bash

URL="https://raw.githubusercontent.com/alex/nyt-2020-election-scraper/master/battleground-state-changes.txt"
STATE="Arizona"

CMD="curl --silent \"$URL\" | grep -A 2 \"$STATE\" | tail -n 1"
#echo $CMD
eval $CMD

exit 0

Tags: , , , , , , , , ,
Labels: USA

Keine Kommentare | neuen Kommentar verfassen

Samstag, 6. Juni 2015

Ctrl-l bei Cyon SSH-Zugängen wieder zum Laufen bringen (sowie: Kritik an Cyon)

Vor Jahren war der Shared Hosting-Anbieter Cyon ein Lichtlein am Horizont — klasse Design, einfach zu bedienende Admin-Oberfläche ohne irgendwelchen Schnick-Schnack.

In den letzten Monaten hat der Anbieter bei mir leider viel Goodwill eingebüsst; es scheint, als passe Cyon bald im Monatsrhythmus seine Infrastruktur an, und der Leidtragende ist der Kunde:

  • Web Application Firewall. Unter dem Motto „Wir machen Web-Hosting noch sicherer!“ wurde primär einfach mal mein auf PHP und MySQL basierendes Site Management Tool zerschossen, welches seit bald 15 Jahren bei unzähligen Hostern produktiv läuft (und von mir auch regelmässig angepasst wird). PHP-Code darf nun nicht mehr per HTTP POST übermittelt werden, denn das sei grundsätzlich einmal ein Sicherheitsrisiko. Und überhaupt. Was zur Folge hat, dass meine Daten sowie diejenigen meiner betroffenen Kunden auf einen anderen Web-Server gezügelt werden mussten, welcher von einer nicht so paranoiden WAF abgeschirmt wird.
  • Lüpfen ohne Vorwarnung oder Testsystem. Ungefähr jedes halbes Jahr lüpft der Anbieter über Nacht die PHP-Standardversion. Finde ich im Grunde Klasse und äusserst fürsorglich. Wenn dann die Sysadmins dort wenigstens ein wenig Hirn walten lassen würden und meine für Cyon adaptierte php.ini ebenfalls von Version zu Version portieren würden. Aber nein, bei jedem PHP-Upgrade kriegt man eine liebevoll von Cyon vorbereite php.ini vorgesetzt, welche natürlich alle selber vorgenommenen Spezialeinstellungen nicht enthält. Ohne irgendwelche Vorwarnung, teilweise um 10 Uhr morgens. Dann heisst es auf der Arbeit, alles liegen und stehen lassen, irgendwie per SSH Verbindung zum Web-Server aufnehmen und die zerschossene php.ini mit einer Sicherheitskopie überschreiben. Dasselbe passierte übrigens mit oben genannter Problematik: Von einem Tag auf den anderen waren alle meine Web-Sites plötzlich wieder hinter einer amoklaufenden WAF aufgeschaltet und funktionierten wieder einmal nicht mehr. Nach Interventionen und langer Wartezeit bequemte sich ein System Engineer dort, den althergebrachten Zustand wieder herzustellen.
  • Kommunikation? Vergesst es. In der heutigen Zeit wäre es mittels E-Mail, Blog und RSS-Feeds ja echt keine Sache, die professionellen und semi-professionellen Kunden über geplante Änderungen zu informieren. Mit genügend Vorlaufzeit, damit das Datum im Kalender markiert werden kann und allenfalls bereits Anpassungen am Code vorgenommen werden können. Aber bei Cyon lebt man nach dem Grundsatz „Was der Kunde nicht weiss, macht ihn nicht heiss.“ Was halt leider dazu führt, dass der Kunde immer wieder aus heiterem Himmel eine grundlegende Anpassung vorgesetzt erhält.

Was mich zu meinem eigentlichen Problem führt: Es scheint, als hätte Cyon kürzlich den Web-Server von LiteSpeed auf Apache gewechselt (ich kämpfe derzeit mit Zeichensatzproblemen, weil AddDefaultCharset utf-8 in .htaccess nicht mehr beachtet werden). Nun gut und recht. Zusammen mit diesem Wechsel kommt auch die SSH-Shell komisch daher.

Insbesondere nervte mich tödlich, dass ich neuerdings das aktuelle Terminal-Fenster nicht mehr mittels Ctrl-l löschen konnte (analog zum Befehl clear, halt simpler und schneller). Wenn ich die Tastenkombination betätigte, erschien einfach eine neue Zeile mit der Befehlseingabe.

Nach einigen längeren Nachforschungen und Pröbeleien (wohl so eine Eigenheit von bash mit .bash_profile und .bashrc) löste folgender Eintrag in .bashrc mein Problem.

...
# User specific aliases and functions
bind -x $'"\C-l":clear;'

Quelle: To bind clear to ^l in Bash

Tags: , , , , , , , , , , , , ,
Labels: IT

5 Kommentare | neuen Kommentar verfassen

Donnerstag, 30. April 2015

Unter Windows sequentiell nummerierte Verzeichnisse erstellen

Das geht ganz einfach, wenn man Git für Windows installiert hat und so auf die bash-Shell zurückgreifen kann:

$ for i in {50..75}; do mkdir $i; done

Tags: , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Montag, 2. März 2015

SAP-Datenexporte mit Unix-Tools filtern

Kürzlich stand ich vor der Aufgabe, einen 1.8 Millionen Zeilen umfassenden SAP-Export (SE16N, sowie Hintergründe) nach genau 16-stelligen Zahlenfolgen zu filtern. Anstelle Excel (kann sowieso nicht mit 1.8 Millionen Zeilen umgehen) oder das komplizierte ACL zu verwenden, entschied ich mich stattdessen, die Plaintext-Datei mit Unix-Tools zu filtern.

Inspiration dazu war der kürzlich auf Hacker News erschienene Artikel Command-line tools can be 235x faster than your Hadoop cluster.

Unter Windows klappt das problemlos, wenn man Github für Windows installiert hat – die Installation bringt nämlich eine Linux-Shell mitsamt den grundlegendsten Unix-Tools mit, so auch cat, grep und wc.

Um den SAP-Export mit „|“ als Feldabgrenzung auf den gesuchten Pattern zu filtern, habe ich folgenden Befehl verwendet:

$ cat export.txt | grep -E "\|[4-5]{1}[0-9]{15}" > export-filtered.txt

Dieser Befehl speichert alle Zeilen aus der Datei export.txt, welche 16-stellige Zahlen enthalten, die mit 4 oder 5 beginnen und am Anfang eines Feldes stehen (deshalb \|), in die Datei export-filtered.txt.

So entfiel der Import über eine graphische Oberfläche (mit der obligatorischen Titelleiste „Keine Rückmeldung“) und die Sache war innert 5 Minuten gegessen.

Tags: , , , , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 26. Januar 2014

Shell-Script-Befehl auf STDOUT ausgeben und danach ausführen

Viele meiner Scripts sind mit hoher Verbosität programmiert, damit ich während der Entwicklung weiss, wo allfällig die Ausführung abbricht. Hierzu gehört auch, dass ich komplexe Befehle vor der Ausführung ausgebe. Damit kann ich den Befehl kopieren und beim Debugging manuell auf der Kommandozeile ausführen, um vielleicht weitere Hinweise auf das Problem zu erhalten.

Doch wie macht man das, wenn man bspw. bei rsync Pfadangaben mit Leerschlägen drin hat, die vom Tool dann auch effektiv erkannt und verarbeitet werden sollen? Hier die Lösung:

...
$SOURCE="/Users/mario/Pictures/iPhoto Library/"
$DEST="/Volume/Sicherungs Ordner mit vielen Leerzeichen/"
...
COMMAND="rsync $OPTS \"$SOURCE\" \"$DEST\""
...
echo "Executing '$COMMAND' ..."
...
eval $COMMAND
...

Die ganze Chose steht und fällt mit eval. Wird nur $COMMAND ausgeführt, stolpert rsync über die ordentlich mit Anführungszeichen versehenen Pfade mit Leerzeichen.

Tags: , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 26. Januar 2014

Shell-Scripte mit vielen Optionen

Komplexe Shell-Scripte, welche ein Unix-Tool mit unzähligen Optionen aufrufen, muss man ab und zu debuggen. Damit dies möglichst einfach funktioniert, habe ich mir angewöhnt, die Optionen so zu notieren, damit ich jede einzelne Option mit einem Tastendruck auskommentieren kann:

...
OPTS=""
OPTS="$OPTS --verbose"
OPTS="$OPTS --archive"
OPTS="$OPTS --no-owner"
OPTS="$OPTS --no-group"
#OPTS="$OPTS --delete" # WILL DESTROY EVERYTHING! DO NOT UNCOMMENT
OPTS="$OPTS --progress"
...
rsync $OPTS "$SOURCE" "$DESTINATION"
...

Tags: , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 17. November 2013

Finder-Eigenschaften von Dateien auf der Kommandozeile auslesen

Mit nachfolgendem bash-Script durchsuche ich einen Ordner mit über 700 Photos und gebe all diejenigen JPG-Dateien aus, welche im Finder die Farbe „Rot“ zugewiesen haben:

#!/bin/sh

MDLS=`which mdls`
ATTRIBUTE="kMDItemFSFinderFlags" # Color
VALUE=12 # Red

for FILE in *.JPG
do
	RETVAL=$($MDLS -name "$ATTRIBUTE" "$FILE" | cut -d "=" -f 2)
	
	if [ $RETVAL -eq $VALUE ]
	then
		echo $FILE
	fi
done

exit 0

Alle zutreffenden Dateien kopiere ich mit folgendem Script in den Unterordner Highlighted (das obige Script habe ich unter filter-highlighted.sh abgelegt):

#!/bin/sh

FILES=`./filter-highlighted.sh`

for FILE in $FILES
do
	cp "$FILE" "Highlighted/"
done

exit 0

Tags: , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 7. November 2013

Die gängigsten Unix-Kommandozeilen-Tools unter Windows

Welcher Linux-Benutzer kann unter Windows schon auf nützliche Kommandozeilen-Tools wie cat, cut, sed, awk, tr und Konsorten verzichten? Das Complete package, except sources der CoreUtils for Windows rüstet unter Windows die gängigsten Linux-Kommandos nach.

Damit Windows nach der Installation die Linux-Befehle aber auch wirklich findet, muss der Pfad zu den ausführbaren Dateien in die Windows-Umgebungsvariable PATH aufgenommen werden. Dies geschieht folgendermassen:

  1. Computer
  2. Systemeigenschaften
  3. Erweitert
  4. Umgebungsvariablen…
  5. Path
  6. Bearbeiten…

An den String fügt man den Pfad C:\Program Files (x86)\GnuWin32\bin; (Windows 7 mit 64-bit CPU) respektive C:\Program Files\GnuWin32\bin; an.

Sobald man nun die Windows-Kommandozeile öffnet, hat man die ganze Palette an Befehlen zur Hand …

… ausser grep!

Dieses muss man als eigenständiges Installationspaket von derselben Web-Site herunterladen und installieren:

Grep for Windows

Tags: , , , , , , , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 3. November 2013

(Aus dem Archiv) Backup my Mac OS X home directory with rsync

Der vorliegende Artikel habe ich ursprünglich irgendwann einmal ab 2002 auf meinem damaligen Linux-Entwicklungsserver im Web publiziert. Da ich das bloggen erst 2005 entdeckt habe, waren die Tipps in einer grossen HTML-Seite untergebracht. Anlässlich einer Aufräumaktion auf dem Server habe ich mich entschieden, die „Perlen“ über meine heutige Kommunikationsplattform ins Web zu posaunen. Seitdem ich die Artikel verfasst habe, sind viele Tage ins Land gegangen — ob der Artikel noch Gültigkeit hat, entscheidet der geneigte Leser selber.

Please be aware to use the special rsync-Version written for Mac OS X (fucking resource forks, again!). Otherwise you could end up with a mess (only on the backup side, but this sucks as much!).

I separated iPhoto-Files from the rest, because the .sparseimage wouldn’t fit on a DVD anylonger.

backup.sh

#!/bin/sh

if [ $# -lt 1 ]
then
	echo "Please provide a destination to store the backup to:"
	echo "fwdsk (Firewire-Drive)"
	echo "eth (Server-Share)"
	echo "tmp (/tmp)"
	exit 1
fi

case $1 in
	"fwdsk")
		IMAGEFOLDER="/Volumes/TRANSFER";;
	"eth")
		IMAGEFOLDER="/Volumes/RSYNC";;
	"tmp")
		IMAGEFOLDER="/tmp";;
	*)
		echo "Please provide a destination to store the backup to:"
		echo "fwdsk (Firewire-Drive)"
		echo "eth (Server-Share)"
		echo "tmp (/tmp)"
		exit 1;;
esac

if [ ! -d "$IMAGEFOLDER" ]
then
	echo "Directory '$IMAGEFOLDER' not found"
	exit 1
fi

BACKUPINFO=( "home" "iphoto" )

for VOLNAME in ${BACKUPINFO[@]}
do
	DISKIMAGENAME="$VOLNAME"
	DISKIMAGEPATH="$IMAGEFOLDER/$VOLNAME.sparseimage"
	
	BACKUPSOURCEFILE="/Users/mario/Rsync/bkpsrc/$VOLNAME.txt"
	
	if [ ! -f "$BACKUPSOURCEFILE" ]
	then
		echo "File '$BACKUPSOURCEFILE' not found"
		exit 1
	fi
	
	BACKUPSOURCE=`more $BACKUPSOURCEFILE`
	BACKUPDESTINATION="/Volumes/$VOLNAME"
	RSYNCEXCLUDE="/Users/mario/Rsync/exclude/$VOLNAME.txt"
	
	#-------------------------------------------------
	# Create/reuse & mount Disk-Image
	#-------------------------------------------------
	if [ ! -f "$DISKIMAGEPATH" ]
	then
		# Disk-image-file doesn't even exist - create it
		echo "Creating disk image \"$DISKIMAGEPATH\""
		hdiutil create -fs HFS+ -type SPARSE -size 20g -volname "$DISKIMAGENAME" "$DISKIMAGEPATH"
	else
		echo "Using pre-existing disk image \"$DISKIMAGEPATH\""
	fi
	
	if [ ! -d "$BACKUPDESTINATION" ]
	then
		# Disk-image doesn't seem to be mounted
		hdiutil attach "$DISKIMAGEPATH"
	fi
	
	#-------------------------------------------------
	# Did Disk-Image mount correctly?
	#-------------------------------------------------
	if [ ! -e "$BACKUPDESTINATION" ]
	then
		echo "There was a problem creating or mounting the disk image"
		exit 1
	fi
	
	#-------------------------------------------------
	# Rsync
	#-------------------------------------------------
	/Users/mario/Rsync/rsync.sh "$BACKUPSOURCE" "$BACKUPDESTINATION" "$RSYNCEXCLUDE"
	
	#-------------------------------------------------
	# Unmount Disk-Image and do maintenance operations
	#-------------------------------------------------
	# hdiutil info | grep /Volumes/$VOLNAME | cut -f 1
	# 
	# Expected output: /dev/disk2s2    Apple_HFS       /Volumes/Rsync-Backup
	#                  ^ this info is required to unmount
	
	DISKIMAGEDEVICE=`hdiutil info | grep /Volumes/$VOLNAME | cut -f 1`
	echo "Disk image mounted as $DISKIMAGEDEVICE"
	
	hdiutil detach -quiet "$DISKIMAGEDEVICE"
	echo "Disk image ejected"
	
	hdiutil compact "$DISKIMAGEPATH"
	echo "Disk image compacted"
done

rsync.sh

#!/bin/sh

if [ $# -ne 3 ]
then
	echo "Usage:"
	echo "rsync.sh   "
	exit 1
fi

BACKUPSOURCE="$1"
BACKUPDESTINATION="$2"
RSYNCEXCLUDE="$3"

if [ ! -d "$BACKUPSOURCE" ]
then
	echo "Source directory '$BACKUPSOURCE' not found"
	exit 1
fi

if [ ! -d "$BACKUPDESTINATION" ]
then
	echo "Destination directory '$BACKUPDESTINATION' not found"
	exit 1
fi

if [ ! -f "$RSYNCEXCLUDE" ]
then
	echo "Exclude file '$RSYNCEXCLUDE' not found"
	exit 1
fi

# --verbose
# --showtogo
# --dry-run
time sudo /usr/local/bin/rsync -a --delete --delete-excluded --eahfs --showtogo --exclude-from\
 "$RSYNCEXCLUDE" "$BACKUPSOURCE" "$BACKUPDESTINATION"

bkpsrc/home.txt

/Users/mario/.

bkpsrc/iPhoto.txt

/Users/mario/Pictures/iPhoto Library/.

exclude/home.txt

Music/
Movies/
PoisonDownloads/
Cache/
Caches/
.Trash/
Fun-Stuff/
.DS_store
iPhoto Library/

exclude/iphoto.txt

.Trash/
.DS_store

Tags: ,
Labels: Apple

Keine Kommentare | neuen Kommentar verfassen