Die Spielwiese für Windows-Hasser.
Die folgende Konstrukte sind entweder unter Linux oder CCC-RTU
<uääääx> entstanden. Sie sollten unter den meisten UNIX-Derivaten
in der Shell /bin/sh lauffähig sein. Es kann natürlich immer wieder vorkommen, daß dieses oder
jenes Kommando andere Parameter erwartet. So ist zum Beispiel grep
mal mit -q wie
"quiet" und mal mit -s wie "silent" dazu zu bewegen, sich ruhig zu verhalten.
Als C-Compiler kamen gcc version 2.6.3 und Concurrent C Version 2.1 zum
Einsatz und glaubt jetzt bitte nicht, man könnte einen Source so einfach auf den anderen Rechner spielen
und neu compilieren... :(
UNIX ist eben doch nicht gleich UNIX, da hilft kein POSIX, kein BSD (BSE schon gar nicht) und auch afrikanische
Antilopen sind relativ machtlos.
Mit folgenden Tricks kann ich dienen ...
Mittlerweile muß ich einer ganzen Reihe Leuten, die mir Error-Reports, Verbesserungsvorschläge, aufmunternde Briefe und all sowas geschickt haben, danken. Auch wenn ich nicht alles einfliessen lassen konnte, war ich doch fasziniert, wie viele Mails ich diesbezüglich bekam. Vielen Dank an die fleißen Helfer und einen besonderen Gruß an Ricki, der meine Dummheit mit mehrfachem Senden von Lösungen kompensiert hat. ;)
Immer wieder kommt es vor, daß man wegen unterschiedlich reagierender Befehle vor Ausführung eines Kommandos wissen möchte, wie denn eigentlich das Betriebssystem heißt, mit dem man sich gerade herumschlägt. Wie zum Beispiel dieses lästige -e das das Linux' echo so gerne haben möchte, um Sonderzeichen wie '\t' oder '\c' darzustellen.
#! /bin/bash ECHO="echo" case `uname -s` in Linux|linux) ECHO="echo -e";; Unix|unix) ECHO="echo";; *) ECHO="echo";; esac $ECHO "Siehe da, ich kann \n\n\tSONDERZEICHEN\n\ndarstellen.\n" exit
Als Ergebis müßte folgendes Bild erscheinen, sonst ist gewaltig was schiefgelaufen. Okay, der Prompt wird natürlich etwas anders aussehen...
myhost:[carsten]# systest Siehe da, ich kann SONDERZEICHEN darstellen. myhost:[carsten]#
... und schon hegen alle fleißigen Shell-Programmierer die Hoffung, daß zumindest der Befehl
uname
auf allen System gleich reagiert, sonst steht man ziemlich tief im Wald, gelle? Die Variable
$OSTYPE
ist nämlich auch nicht überall definiert.
Wo wir gerade beim Thema echo
sind... Gute Programme lamentieren nicht
pausenlos herum. Hin und wieder kommt es jedoch vor, daß User umfangreichere Informationen benötigen und
dieses zum Beispiel mit dem Schalter -v bei den meisten Programmen auch erreichen. Um eigenen Scripts diese
Fähigkeit einzuimpfen, hat man verschiedene Möglichkeiten. Voraussetzung ist immer die Erkennung des Schalters
durch das Scipt, doch dazu später.
ausgabe() { if [ "${PLAUDERTASCHE:=nein}" = "ja" ] then echo $* fi }
main() { }dieses kompilieren und irgendwo geschickt im Pfad unterbringen.
/usr/local/bin
wird zum Beispiel
immer wieder gerne genommen.
Nun muß man nur noch die Parametererkennung durchführen (das Beispiel bezieht sich jetzt auf beide Varianten, man sollte natürlich immer nur eine implementieren):
#! /bin/bash ECHO="none" PLAUDERTASCHE="nein" while [ $# -gt 0 ] do case $1 in -v) ECHO="echo" PLAUDERTASCHE="ja";; *) ALLE_ANDEREN= "$ALLE_ANDEREN $1";; esac shift done ausgabe "Funktion hat -v begriffen..." $ECHO "Programm hat -v begriffen..."
Letzteres hat für mich den Vorteil, daß man es prima mit dem Thema System-Erkennung verknüpfen kann.
... oder: Die Folgen des "printf ("%20s", text);" für die Shellprogrammierung. Um
eine Ausgabe, die statt mit TAB's mit beliebig vielen Leerzeichen auf Tabellenform gebracht wurde (ls, df) wieder fuer
cut -f
zugänglich zu machen:
myhost:[carsten] # (command)|sed 's/\ */ /g'
Es it vielleicht nicht auf den ersten Blick zu erkennen, aber der replace-Ausdruck, also der zwischen den beiden letzen Schrägstrichen, ist natürlich notwendiger Weise ein Tabulatorzeichen.
... oder: Das Ctrl-M-Dilemma. Wenn man mal wieder so richtig reingegriffen hat und einen DOS-Text unter UNIX
betrachten muß ohne Tools wie todos
oder tolinux
:
myhost:[carsten] # sed 's/^M//' dosfile > unixfile
Das ^M wird dabei durch Halten der Ctrl-Taste, auf urdeutschen Tastaturen Strg, und drücken der Tasten V und M (nacheinander, während Ctrl schön fest gehalten wird !) erzeugt.
Zusätzlicher Linux-Tip:
Wer das Glück hat, auf eigenen Platten arbeiten zu dürfen, kann das Problem auch dadurch umgehen,
ebendiese DOS-Partition gleich mit ensprechender Unterstützung zu mounten. Dazu einfach als root
einloggen und einen entsprechenden Eintrag in der Datei /etc/fstab
einrichten. Im Beispiel mounte ich
meine Platte D: zusätzlich noch auf meine User-ID, damit ich mich nicht immer zweimal einloggen muß, nur
um mal wieder diese Datei zu editieren.
/dev/hdc1 /dos_d msdos user,noexec,nosuid,nodev,conv=auto,uid=39 0 2
Bitte denkt daran, daß das Auto-Converting ganz witzige Nebenwirkungen haben kann, wenn eine
Binärdatei mit einer Text-Extension angedallert kommt. Werft mal einen Blick in die man-Pages von
mount
.
Um beliebig zwischen großen und kleinen Buchstaben wechseln zu können hat man n verschiedene Möglichkeiten, hier die zwei beliebtesten:
awk
funktioniert, hat man es einfach. Nur die folgende Funktion
einfügen und schon ist alles in Butter. Das gleiche geht natürlich auch mit tolower
.
upcase() { echo $*|awk '{print (toupper($0))}' }
tr
bei fast allen Distributionen ohnehin dabei (und auch installiert)
ist. Für die umgekehrte Richtung einfach die Zeichenketten in den eckigen Klammern tauschen.
upcase() { echo $*|tr [a-z] [A-Z]' }
Schon mal versucht in einem Textfile einen Dateinamen zu suchen? Kein Problem? Im
Prinzip ja, aber... Wir wollen ja mit regulären Ausdrücken suchen und da glaubt der grep
was
anderes, als die normale Shell-Ersetzung. Also muß man aus dem Dateinamen einen "richtigen"
regulären Ausdruck machen.
createRegular() { echo $1|sed 's/[.]/\\\./g'|sed 's/[*]/\.\*/g'|sed 's/[?]/./g' }
Bitte genau die Anzahl der (Back-)Slashes einhalten. Am besten Cut&Paste benutzen.
Da hat man sich mühselig bis zu einem Verzeichnis vorgearbeitet, dann kommt der
Feierabend ... und morgens alles nochmal von vorn. <würg> Dem kann Abhilfe geschaffen werden. Aber Vorsicht!
Dieses Beispiel ist genau auf meine Linux-bash
zugeschnitten. Mit der tcsh
habe ich da keine
guten Erfahrungen gemacht.
~/.bash_logout
pwd > ~/.lwd
~/.bash_login
if [ -f ~/.lwd ] then LWD=`cat ~/.lwd` cd $LWD fi
Es sollte aber prinzipiell möglich sein, dieses Verfahren auch auf andere Systeme/Shells zu übertragen.
Habt Ihr auch einen neurotischen Systemverwalter, der stets darauf bedacht ist, alle
User, die mal gerade zehn Minuten nix tun, automatisch auszuloggen? Da kommt man also gestärkt und mit frischem
Tatendrang vom Klo zurück und was ist? Man darf sich als erstes neu einloggen, sich wieder bis zu dem Verzeichnis
durchhangeln, in dem man zuletzt gearbeitet hat und so weiter und so fort.
Duch ein kleines Programm, vor Verlassen des Raumes gestartet, kann man dem Abhilfe schaffen. <veg>
Aber Vorsicht: auch wenn das Programm kaum CPU-Zeit verbraucht und eben nur das Terminal mit Schreibaktivitäten am
Leben hält, bitte nicht zu exzessiv einsetzen und weder zehn mal im Hintergrund, noch vor Antreten des
Jahresurlaubes starten. (Sonst steigen mir alle SysOps Deutschlands auf's Dach...)
#include <stdio.h> #include <signal.h> #include <time.h> #define FOREVER for(;;) void sigAlarm (signo) int signo; { time_t just; struct tm *now; just= time (NULL); now = localtime (&just); printf ("\r[ %02d:%02d ] ", now->tm_hour, now->tm_min); fflush (stdout); } void main (void) { sigAlarm (); FOREVER // mit Ctrl-C abbrechen { signal (SIGALRM, sigAlarm); alarm (60); pause (); } }
Copyright © by C4U-Software 1997-2003 | Letzte Änderung: 24. März 2003 |