Kategorie: Scripts

Bash-Script um zeitgesteuert Programme zu starten

Wenn man beispielsweise heute um 20:15 Uhr ein bestimmtes Script starten möchte, kommt man meist um ein Crontab nicht herum. Mit diesem kleinen Script übergibt man als Parameter ein Datum und/oder Uhrzeit und das Script wartet dann bis zu diesem Zeitstempel, bevor das Script beendet wird und das darauf folgende Programm gestartet wird – somit spart man sich das aufwändige editieren der Crontab-Files.

Beispiel

Uhrzeit:

root@test:~$ ./tsleep.sh 14:30; reboot
i sleep until 2009-12-12 14:30:00 ...

Datum:

./tsleep.sh 2009-12-24; reboot
i sleep until 2009-12-24 00:00:00 ...

Datum mit Uhrzeit:

root@test:~$ ./tsleep.sh 2009-12-24 13:45:12; reboot
i sleep until 2009-12-24 13:45:12 ...

Funktionsweise

Der Zeitstempel wird in Sekunden umgerechnet und über eine while-Schleife sekündlich mit dem aktuellen Datum abgeprüft. Ist das aktuelle Datum gleich oder älter dem Zeitstempel, wird das Script beendet und das darauf folgende Program gestartet. Als Zeitstempel kann man alles verwenden was date futtert.

Eine alternative wäre die Differenz der aktuellen Zeit und des Zeitstempels in Sekunden umzurechnen und dann sleep zu übergeben. Ob das perfomanter ist – keine Ahnung, mein Script dagegen überlebt auch Zeit-Anpassungen (z.b. rdate/ntpdate), daher habe ich diesen Weg gewählt.

Sollte jemand Fehler finden oder das Script verbessern, würde ich mich freuen, wenn Ihr mir das mitteilt ;).

Script

#!/bin/bash
 
if [[ -z "$1" ]]; then
        echo "Usage: $0 <timestamp>" >&2
        exit 1
elif [[ -z "$2" ]]; then
        date="$1"
else
        date="$1 $2"
fi
 
date_end=$(date --date="$date" +%s 2>/dev/null);
 
if [[ ! $? -eq 0 ]]; then
        echo "error: invalid date" 2>&1
        exit 1
fi
 
if [[ $date_end -le $(date +%s) ]]; then
        echo "error: end time is lower or eqal start time" >&2
        exit 1
fi
 
echo "i sleep until $(date --date="$date" "+%Y-%m-%d %H:%M:%S") ..."
 
while [[ $(date +%s) -le $date_end ]]; do
        sleep 1
done
 
exit 0

Download

Download tsleep.sh

wget http://blog.kevin-k.com/wp-content/uploads/2009/12/tsleep.sh
chmod +x tsleep.sh

at

Alternativ gibt es auch at, das Befehle direkt von Standard-Input oder einer Datei ließt und zu einer bestimmten Uhrzeit ausführt.

Kopfschmerzen und PHP

Da denkt man, man hat PHP und dessen gestörten Datentypen einigermaßen im Griff und dann kommt soetwas:

$var = 0;
 
if ($var == "all") {
	echo "true";
} else {
	echo "false";
}

Man würde vermuten, das Ergbnis sei false, aber seltsamerweiße kommt hier true heraus.

Schauen wir uns $var und den String “all” mal genauer an:

$var = 0;
 
var_dump((bool)"all")."\n";
var_dump((bool)$var);
 
// Ergbnis:
// bool(true)
// bool(false)

Wieso ergibt dann in PHP true == false true?

Den Grund habe ich auf der PHP type comparison tables im letzen Comment gefunden:

“php” == 0

This is true, because the string is casted interally to an integer. Any string (that does not start with a number), when casted to an integer, will be 0.

Wie auch immer.

Ich nutze jedenfalls für meinen Teil strikte Vergleiche mit drei Leerzeichen ===, damit ist man immer “save”. Am besten wäre es natürlich überhaupt nicht die Datentypen einer Variable zu mixen, aber bei kleinen Quick&Dirty Scripte passiert soetwas mal.

Setup-Script nach Debian Installation

Nach einer Debian Installation passt man meist als erstes die Arbeitsumgebung an, d.h. installiert nützliche Pakete, Konfiguriert das Aussehen der Bash-Shell, installiert Crontabs und Konfiguriert Pakete nach eigenem Wunsch.

Mein Basis-Setup, was ich grundsätzlich nach jeder Debian-Installation durchführe, findet hier ihr:

#!/bin/bash
 
# install packages
apt-get install vim screen vnstat rdate ssh
 
# add crontabs
cat >> /etc/crontab <<EOF
# vnstat
*/5 *   * * *   root    /usr/bin/vnstat -u -i eth0 > /dev/null 2> /var/log/vnstat.log
 
# rdate
0 0     * * *   root    /usr/bin/rdate time.fu-berlin.de > /dev/null 2> /var/log/rdate.log
EOF
 
# add .bashrc
cat > /root/.bashrc <<EOF
umask 022
 
export LS_OPTIONS=' --color=auto'
eval \$(dircolors)
alias ls='ls \$LS_OPTIONS -l'
alias ll='ls \$LS_OPTIONS -l'
alias l='ls \$LS_OPTIONS -lA'
 
alias t-sys='tail -f /var/log/syslog'
 
BLACK="\[\033[0;30m\]"
BLUE="\[\033[0;34m\]"
GREEN="\[\033[0;32m\]"
CYAN="\[\033[0;36m\]"
RED="\[\033[0;31m\]"
PURPLE="\[\033[0;35m\]"
BROWN="\[\033[0;33m\]"
LIGHT_GRAY="\[\033[0;37m\]"
DARK_GRAY="\[\033[1;30m\]"
LIGHT_BLUE="\[\033[1;34m\]"
LIGHT_GREEN="\[\033[1;32m\]"
LIGHT_CYAN="\[\033[1;36m\]"
LIGHT_RED="\[\033[1;31m\]"
LIGHT_PURPLE="\[\033[1;35m\]"
YELLOW="\[\033[1;33m\]"
WHITE="\[\033[1;37m\]"
NO_COLOUR="\[\033[0m\]"
 
export PS1="\u\$DARK_GRAY@\$NO_COLOUR\h\$DARK_GRAY:\$NO_COLOUR\w\$GREEN\\\$\$NO_COLOUR "
EOF
 
# edit vimrc to enable syntax highlighting
sed -e 's/\"syntax/syntax/g' -i /etc/vim/vimrc

Download setup.sh

PostgreSQL Backup Script für Windows

@echo off
 
set PG_BIN_PATH=C:ProgrammePostgreSQL8.3bin
set PG_BACKUP_PATH=C:backuppg
 
set PGHOST=localhost
set PGUSER=postgres
set PGPASSWORD=postgres
set PGPORT=5432
set PGDATABASE=database
set PGCODING=UTF8
 
 
if not exist "%PG_BIN_PATH%" goto exit
if not exist "%PG_BACKUP_PATH%" goto create_pg_backup_path
 
goto run
 
:create_pg_backup_path
mkdir "%PG_BACKUP_PATH%"
 
:run
set PG_BACKUP_TIME=%TIME:~1,1%_%TIME:~3,2%_%TIME:~6,2%
set PG_BACKUP_DATE=%DATE:~6,4%_%DATE:~3,2%_%DATE:~0,2%
 
%PG_BIN_PATH%pg_dump.exe -i --format c --verbose --file=%PG_BACKUP_PATH%%PGDATABASE%-%PG_BACKUP_DATE%-%PG_BACKUP_TIME%.backup
 
:exit
exit