bish(K) cat(K) crc(K) cut(K) echo(K) expr(K) grep(K) bgrep(K) line(K) wc(K) cmp(K) rel(K) tr(K) test(K) tee(K) coder(K) man(K) xregexp(R) regexp(R) ansi(R) readc(K) calc(K) comx(K) dat(K) dd(K) hx(K) ov(K) pg(K) timex(K) touch(K) vi(S) bish(V) Copyright © 1995-2018 Helmut Schellong |
bish(K) bish(K) NAME bish.exe - Shell-Programm, Kommando-Programmiersprache SYNTAX bish [-afhinpstuvxBCEINOPSUX9!] [-o opt]... [-c str] [datei [arg ...]] BESCHREIBUNG bish ist ein Kommando-Interpreter, der Kommandos von der Tastatur, von einem String-Argument, von der Standard-Eingabe (handle 0) oder aus einer Datei liest und ausführt. bish stellt eine leistungsfähige Programmiersprache zur Verfügung, die sich u.a. sehr wesentlich am Exit-Code von Kommandos orientiert. Daneben gibt es viele nützliche eingebaute Kommandos. Für die Syntax in bish dient die Syntax der ksh als Leitlinie. Zwischen dem später beschriebenen set-Kommando und dem Aufruf der bish besteht eine starke Verwandtschaft bezüglich der Optionen. bish ist insgesamt ein äußerst leistungsfähiges Shell-Programm. Zusätzliche Eigenschaften der bish, über die die ksh nicht verfügt, sind nachfolgend durch (-Z-) gekennzeichnet. Zum Thema Kompatibilität siehe bish(I). Es lohnt sich, nachfolgend nach BISHAUTOR und BISHPROGRAM zu suchen. Der Name 'bish' ist eine Abkürzung von BInarySHell und BuiltInSHell. Beides ist voll zutreffend. Kommando-Argumente sind null-terminiert und das einzige wesentliche Merkmal, das nicht binär arbeitet. Variablen und vieles mehr sind allerdings binär konzeptioniert. Es kann eine Variable mit einer Null als Inhalt in ein Argument eingebaut werden. Das funktioniert auch. Jedoch lesen die Kommandos nur bis zur ersten Null im Argument. Das Konzept des Kommandos an sich wurde intensiv realisiert. So können Kommandos Variablennamen entgegen nehmen und selbständig deren Inhalt besorgen und lesen, auch Null-Bytes darin. Definitionen Spezialzeichen ; & ( ) | < > NL SP TAB NL Zeilenvorschub ([CR-]new-line) SP Leerzeichen (space) TAB Tabulator-Zeichen Zwischenraum= SPACE TAB (NL) zeichen Sonderzeichen # = $ ` ~ ? * [ % " ' { } : Zeichenfolgen mit operativer Bedeutung: '' %NL && || &| $( ) $(( )) |! |2 `- $(- :- :+ := [[ ]] {{ }} ;; ;, () { ()) { ${ } ${# } ${: } ${@ } ${{ } ${{# }} Name Alphanumerische Zeichenfolge plus Unterstrich (_) : A-Za-z_0-9 . Ein Digit (0-9) darf nicht erstes Zeichen sein. Dient als Bezeichner von Shell-Variablen und -Funktionen. Namelänge maximal 31 Zeichen. Wort Zeichenfolge, ggf. aufgeteilt durch eines oder mehrere nichtmaskierte Spezialzeichen. Kommando Zeichenfolge gemäß bish-Syntax, bestehend aus einem oder mehreren Wörtern (Argumente), die von der Shell interpretiert und ggf. expandiert bzw. ersetzt werden. Die Shell liest jedes Kommando und führt es als internes oder externes Kommando aus. # Leitet einen Kommentar ein. Diejenigen Zeichen ab und einschließlich # bis ausschließlich NL werden ignoriert. # wirkt nur als erstes Zeichen eines Argumentes, also nur nach NL oder anderen Trennzeichen, oder am Dateianfang. Andernfalls ist es ein normales Zeichen. Die Shell verarbeitet sämtliche Zeichen, mit Ausnahme der beiden mit den Dezimalwerten 0 und 255 (und ^Z). Kurzerklärung der Zeichen ; NL (&) Trennen Kommandos (und Pipes,Listen) voneinander & Startet ein externes Kommando im Hintergrund SPACE TAB Trennen Argumente voneinander && || &| Exit-Code-abhängige Verkettung von Kommandos | |! |2 (|h) Verknüpfung von Aus- und Eingabe von Kommandos (Pipe) > >> < << <> Umlenkung von Aus- und Eingabe von Kommandos {...} {{...}} Zusammenfassung von Kommandos $(...) `...` Einsetzung der Ausgabe von Kommandos $(-..) `-..` Einsetzung der Ausgabe von Kommandos $.. ${..} Einsetzung eines Variablen- oder Parameterinhalts ${{..} Indirekter Zugriff (1-fach indirekt) ${{..}} Indirekter Zugriff (1-fach indirekt) ${#..} Einsetzung einer Variablen- oder Parameterinhaltslänge ${:..} Einsetzung einer Variablenspeichergröße ${@..} Einsetzung einer Variablenadresse ${{{#..} Indirekter Zugriff (2-fach indirekt) ${{{#..}}} Indirekter Zugriff (2-fach indirekt) $s Einsetzung von (Steuer-)Werten (s==[*@?!$-]}...]) ${..:x..} Entweder/Oder-Einsetzung $((...)) Einsetzung des Resultats eines arithmetischen Ausdrucks ? * [ Einsetzung von passenden Dateinamen (Wildcards) name[i] Arrays ((...)) Berechnung eines arithmetischen Ausdrucks (...) Sub-Shell-Aufruf ".." '..' % Maskierende Einfassungen und Maskierzeichen = Variablen-Zuweisung name:znnnn Variablen-Füllen mit nnnn-mal zeichen name:w.nnnn Variablen-Füllen mit nnnn-mal wert ;; ;, Beenden eine Kommando-Folge beim case-Kommando fname() { } Definition einer Shell-Funktion fname()) { )} Definition einer (verschachtelten) Shell-Funktion %NL Zeilenverlängerung # Kommentar-Zeichen label: goto-Marke : Leer-Kommando [[...]] [...] Symbolische Syntax des test-Kommandos ! kommando Invertierung des Exit-Codes ^.*[^a-b]%{a,b%} Reguläre Ausdrücke = Super-Wildcards %(%)%1%9$ Reguläre Ausdrücke = Super-Wildcards Speicher-Management Ab Version 4.00 wird Speicher dynamisch besorgt. Deshalb wurden manche Startwerte (MIN) gesenkt, jedoch immens hohe Maximallimits gesetzt. In [Byte], dezimal: ------------------- BEZEICHNUNG MIN IST MAX ADRESSE ADR_ALT 12# echo "$__MEM__" FUDEFSs 1024 1024 16384 34370330624 34370330624 FUDEFSp 2048 2048 32768 34370342912 34370342912 NAMDEFS 16384 16384 262144 34370364032 34370364032 VARBUF 49152 49152 536870912 34370497216 34370497216 VARBUFl 4096 4096 67108864 34370383872 34370383872 ARGS 65536 65536 536870912 34370426816 34370426816 ARGBUF 65536 65536 536870912 34370549760 34370549760 In [Byte bzw. Anzahl]: ---------------------- 13# ver l pnlen=1024 fnlen=255 dirslen=1024 namlen=31 njmp=16 npipes=64 ibufsz=2048 fudefs_min=256 fudefs=256 fudefs_max=4096 namdefs_min=512 namdefs=512 namdefs_max=8192 namdefsl_min=48 namdefsl=48 namdefsl_max=48 vbufsz_min=49152 vbufsz=49152 vbufsz_max=536870912 vbufszl_min=4096 vbufszl=4096 vbufszl_max=67108864 abufsz_min=65536 abufsz=65536 abufsz_max=536870912 nargs_min=8192 nargs=8192 nargs_max=67108864 Die Anzahl der lokalen Namen ist konstant und relativ gering, weil das ein Geschwindigkeitsmerkmal ist. Bei Bedarf können sehr große Variablen als Quasi-Array angelegt werden und mit catv (binär) bearbeitet werden. Nach Fehlermeldungen in der interaktiven Kommandozeile werden die beiden Argumentespeicher auf MIN gesetzt. FreeBSD: -------- time csh -c "echo /usr/*/*/*/* >> /dev/null" time bash -c "echo /usr/*/*/*/* >> /dev/null" time sh -c "echo /usr/*/*/*/* >> /dev/null" time bish -c "echo /usr/*/*/*/* >> /dev/null" 21.57 real 18.21 user 2.74 sys 5.84 real 4.80 user 0.87 sys 1.35 real 0.52 user 0.78 sys 1.21 real 0.28 user 0.87 sys time bash -c "echo /usr/*/*/*/* | wc" time bish -c "echo /usr/*/*/*/* | wc" time bish -c "echo /usr/*/*/*/*" | wc 82.43 real 79.13 user 0.89 sys 1.58 real 0.32 user 0.95 sys 1.37 real 0.25 user 0.91 sys 1 80377 2916481 1 80424 2918325 1 80426 2918382 bish expandiert bei * auch .namen Beispiele: ---------- Je nach MAX kann eine Variable auch mit 100 Millionen Bytes (hier 'a') gefüllt werden: set Buf:a100000000 #dauert beispw. ~0.5 s Kontrolle: echo ${#Buf} echo "$__MEM__" und nachfolgend in eine Datei geschrieben werden: catv Buf >datei Füllen mit nnnnn(n) Pfadnamen: Pfade=/usr/*/*/*/* Dies sind in der Regel mehrere MByte. Kommandos Ein 'normales' Kommando ist eine Folge von Wörtern, die durch Zwischenraumzeichen getrennt sind. Diese Kommandowörter geben die Argumente direkt als Konstanten an oder sie werden durch die Shell-Interpretation zu Argumenten umgebildet. Das erste Argument (Arg0) ist der Name des Kommandos, die ggf. weiteren sind die eigentlichen Argumente zu dem Kommando. Der (Rückgabe-)Wert eines Kommandos ist sein Exit-Code. Dieser ist gewöhnlich 0 (=TRUE!) bei bestimmungsgemäßer Funktion des Kommandos. Um dem Exit-Code einen Informationsgehalt zuzuweisen, der für Steuerzwecke genutzt werden kann, werden Werte zwischen 0 und 127 explizit von Kommandos selbst gesetzt. Kommandos werden voneinander getrennt u.a. durch die Zeichen NL und ; Das Zeichen ! vor einem Kommando (! Kdo) bewirkt, daß nach Ausführung des jeweiligen Kommandos der globale Exit-Code invertiert wird. Siehe auch Kommando 'inv'. Es wird nicht geprüft, ob ein Kommando einen Exit-Code hat. Eine Pipeline ist eine Folge von einem oder mehreren Kommandos, die (bei mehr als einem) durch | getrennt sind. Die Standard-Ausgabe eines Kommandos vor | wird mit der Standard-Eingabe des | folgenden Kommandos verknüpft: kdo1 | kdo2 [ | kdo3 ]... NL und ; dürfen nicht VOR | stehen. Der Wert einer Pipeline ist der Exit-Code des letzten Kommandos in der Pipeline. Zusätzlich gelten die Zeichenfolgen |! |2 |h (h=0...9), (-Z-) wobei durch |! die Standard-Fehlerausgabe zusätzlich zum nachfolgenden Kommando gelenkt wird und |h nur den explizit angegebenen Handle umlenkt. Die Zeichen ! und 0...9 haben nur direkt nach einem unmaskierten Zeichen | diese Spezialbedeutung. Anm.: Schleifen (...done | ...), Blöcke ({...} | ...), etc., können -als ganzes betrachtet- nicht in eine Pipeline hinein schreiben! Umlenkungen, die ein Vorauslesen erfordern, über die Argumente eines 'normalen' Kommandos hinaus, kann die bish nicht. Eine Liste ist eine Folge von einer oder mehreren Pipelines, die durch NL ; && oder || getrennt sind. NL und ; dürfen nicht VOR && und || stehen. Der Operator && (||) bewirkt, daß eine nachfolgende Pipeline nur ausgeführt wird, wenn der Wert (Exit-Code) der davorstehenden Pipeline Null=TRUE (Nicht-Null=FALSE) war. Eine durch && (||) getrennte Pipeline-Folge wird abgebrochen, sobald zum Operator && (||) Exit=Null (=Nicht-Null) nicht mehr auftritt. Zusammenfassungen per { Liste; } (s.u.) sind möglich. Der Oder-Operator &| ist nicht kompatibel mit bekannten UNIX-Shells. Er hat Vorrang vor && und || und bewertet den Exit-Code der Pipelines links und rechts von ihm. (-Z-) Eine Folge von Pipelines, getrennt durch &|, ist erfolgreich, sobald ein TRUE-Exit auftritt. Restliche Kommandos innerhalb einer solchen Oder-Kette werden nicht mehr ausgeführt, nach einem TRUE-Exit. Der Exit-Wert einer Oder-Kette wird aufbewahrt, bis zu einem optionalen Operator && oder ||, bei dem entsprechend fortgefahren wird. && oder || können auch vor einer Oder-Kette stehen, mit Wirkung auf alle durch &&,||,&| getrennten nachfolgenden Kommandos. Zusammenfassungen per { Liste; } (s.u.) sind möglich. Beispiel: *false || *true &| false &| false && *kdo *true && *false &| *true &| false && *kdo *true && *false &| *true &| false || kdo *true && *false &| *false &| *false || *kdo *true && *false &| *false &| *false && kdo *true || false &| false &| false && kdo Ausgeführte Kommandos wurden mit * gekennzeichnet. In diesem Zusammenhang ist auch das Kommando 'inv' nützlich, das Exit-Werte invertiert. Mit den Operatoren && || &| {...} und inv,true,false können lange Verarbeitungsketten auch mit if-else-Effekten gebildet werden. Die Pipelines arbeiten in Voreinstellung mit temporären Dateien, genau: mit seek-baren, verschachtelten Dateiendabschnitten, wahlweise (per -U, set -U) mit der Funktion pipe(). Das hat mehr Vorteile als pipe() Vorteile hat: o Nicht nur externe Kommandos in der pipe-Kette, sondern auch interne und Shell-Funktionen normal möglich. o Argumente zu internen Kommandos dürfen tausendfach länger sein als die zu anderen Prozessen. o Funktioniert mit allen Betriebssystemen. o Man erhält eine temporäre Datei 'on the fly'. o Diese Datei kann mittels 'seek' mehrfach gelesen werden. o Es gibt keine (Lese-)Probleme mit Kommandos, die bei 'echten' pipe()s versagen. (Kommandos, die keine ausdrücklichen Filterkommandos sind.) o Die Prozesse werden nacheinander gestartet, o sie können sich nicht gegenseitig stören, o die momentane Prozeßlast ist geringer, o der Exit ist von jedem in der Kette eindeutig erhältlich. o Kommando a | b kann eine Variable -zum Schluß- setzen, die -danach- von Kommando b ausgewertet wird. o SIGPIPE kann nicht vorkommen, bei vorzeitigem Beenden eines Kommandos in der Pipe. o Beliebige gewollte Rückwirkungen aus der Pipe-Kette heraus sind möglich (nur 1 Prozeßkontext). Vorteile von pipe(): o Der Datenstrom darf beliebig groß sein. o Arbeitet deutlich/mehrfach/vielfach schneller, zumindest bei großen Datenmengen pro Vorgang. o Permanentes Monitoring ist möglich. Echte Pipelines per -U/+U und set -/+U nur unter Unix. (Siehe set-Kommando) Beispiel Geschwindigkeit: ------------------------- time bish -pU -c "cat /usr/ARCH/3.tar | sumv -l" time bish -pU -c "cat /usr/ARCH/3.tar | sumv -l" time bish -p -c "cat /usr/ARCH/3.tar | sumv -l" time bish -p -c "sumv -l < /usr/ARCH/3.tar" 16580123892488523 1.99 real 0.06 user 0.26 sys 0.28 real 0.04 user 0.22 sys 4.99 real 0.07 user 1.56 sys 0.19 real 0.04 user 0.13 sys (Datei 3.tar == 50 MB) Spezial-Kommandos zur Ablaufsteuerung (Intern): Der Wert dieser Kommandos ist der Wert des innerhalb dieser Kommandos zuletzt ausgeführten 'normalen' Kommandos, wenn nicht anders angegeben. for Name [ in Wort ... ] do Liste done Name wird nacheinander auf alle Argumente gesetzt, die in der Wort-Liste enthalten sind, und Liste wird dann jeweils mit einem solchen Argumentwert einmal ausgeführt. Wenn ``in Wort'' fehlt, wird die Liste zwischen do und done mit jedem positionalen Parameter einmal ausgeführt. ``in "$@"'' entspricht der Weglassung. for N Name ... in [ Wort ... ] do Liste done Diese Erweiterung (N) ist nicht kompatibel mit bekannten UNIX-Shells. (-Z-) N ist eine positive Zahl größer Null und gibt die Anzahl der Variablennamen an, die jeweils mit entsprechend vielen Argumenten aus der Wort-Liste gefüllt werden sollen. Es müssen entsprechend viele Namen angegeben werden. Der Platzhalter-Name '-' ist zugelassen. (s. read) Die Variable __ARGS__ wird für Kontrollzwecke auf die jeweilige Anzahl der überwiesenen Argumente gesetzt, weil diese zum Schluß (Rest!) kleiner sein kann als das angegebene N. Überzählige Variablen werden leer ("") gesetzt. $__ARGS__ summiert ergibt stets die Anzahl der Argumente, die in der Wort-Liste enthalten sind. Die vorstehend beschriebene Erweiterung der for-Schleife ist vorzüglich für die Bearbeitung von Tabellen im weitesten Sinne geeignet. Siehe bish(B). [ for Name ] [ from a ] [ by i ] [ to b ] repeat do Liste done Diese zweite Form der for-Schleife kann mit jedem der fünf genannten Schlüsselworte beginnen, und ist nicht kompatibel mit bekannten UNIX-Shells. (-Z-) Wird ``for Name'' angegeben, ist Name innerhalb von Liste verfügbar, mit einem Digit-String als Inhalt, der von einer internen Laufvariablen gespeist wird, die mit `a' startet, nach jedem Durchlauf um `i' erhöht bzw. vermindert wird, und mit `<=b' bzw. `>=b' letztmalig durchläuft. Voreingestellt sind: for interne_laufvariable from 1 by 1 to × (unendlich,infinite) Die interne Laufvariable ist vom Typ long-Integer, 32 Bit oder 64 Bit. Beispiel: to 5 repeat do Liste done Liste wird 5-mal ausgeführt. Man sollte anstelle von 'for Name' (erste Form von for) die explizite Darstellung 'for Name in $*' wählen, weil ein positionaler Parameter das Wort 'repeat' enthalten könnte. In solch einem Fall könnten die beiden for-Variationen nicht mehr eindeutig erkannt werden. case Wort in pattern[|pattern]...) Liste;; pattern[|pattern]...) Liste;, pattern[|pattern]...) Liste ;; pattern[|pattern]...) Liste;; ... esac Es wird diejenige Liste ausgeführt, hinter demjenigen Suchmuster (pattern), das -von oben nach unten (und von links nach rechts)- zuerst zum Wort paßt. Die Zeichenfolgen | ) ;; ;, gehören zur Syntax. Wenn als Listenabschluß ;, statt ;; gegeben wird, erfolgt ein Sprung zum nächsten Listenbeginn (fallthrough) (-Z-), anstelle eines Sprunges hinter 'esac'. (Siehe auch unten Kommando 'goend'.) Ein Listenabschluß ist gleichzeitig eine Markierung, die darauf hinweist, daß nun ein Pattern oder esac folgt. Hinter den Listenabschlüssen dürfen nur NL oder Zwischenraumzeichen stehen. Direkt hinter esac muß NL oder Zwischenraum folgen. Der Mechanismus bei den Pattern entspricht dem bei der Dateinamenexpansion (s. regexp®). Expansionszeichen sind ? * [ . Zusätzlich gibt es eine ODER-Funktion per | . Innerhalb eines Patterns haben nur die Zeichen % | ) neben den Expansionszeichen Spezialbedeutung. ) beendet ein Pattern. % maskiert die Spezialzeichen und Zwischenraumzeichen. Die Folge %NL bzw. %CRNL wird ignoriert/weggeworfen. Pattern müssen Konstanten sein. Das Kommentarzeichen # muß nur maskiert werden, wenn man es als erstes Pattern-Zeichen bewertet haben will, andernfalls nimmt es an dieser vordersten Position die Zeile weg. Man beachte bei Kommentar-Kennzeichnungen NACH ')' ...) #... daß die Listenabschlüsse aktiv bleiben! if liste then Liste [elif liste then Liste]... [else Liste] fi Die Liste hinter if wird ausgeführt und, falls TRUE, dann die Liste nach dem ersten then. Andernfalls die Liste nach elif und, falls TRUE, dann die Liste nach dem nächsten then (soweit elif vorhanden). Ansonsten die Liste nach else (soweit else vorhanden). Wenn keine then- oder else-Liste ausgeführt wurde, ist der Wert des if-Kommandos TRUE. (Siehe auch unten Kommando 'goend'.) while liste until liste do do Liste Liste done done Die Liste zwischen do und done wird (wiederholt) ausgeführt, solange die Liste nach while TRUE bzw. die Liste nach until FALSE als Wert liefert. while und until liefern TRUE, wenn keine do-Liste ausgeführt wurde. break [n] Verläßt die umgebende(n) for-, while- oder until-Schleife(n). Multilevel-break bei n>1. Wird ignoriert bei n=0; Ohne Angabe von n gilt n=1. continue [n] Lenkt die Verarbeitung zum Startpunkt der umgebenden Schleife. Multilevel-continue bei n>1. Wird ignoriert bei n=0; Ohne Angabe von n gilt n=1. goend [n] Verläßt das/die umgebende(n) if- oder case-Kommando(s). Multilevel-goend bei n>1. Wird ignoriert bei n=0; Ohne Angabe von n gilt n=1. (-Z-) (s.u.: goto) break und goend setzen nicht den Exit-Wert. break und continue beziehen sich nur auf Schleifen, goend nur auf if und case. Das heißt z.B., ein goend 1 verläßt beliebig viele Schleifen und einen case auf einmal, wenn die Schleifen sich verschachtelt in einem case befinden! FOLGENDE EINSCHRÄNKUNGEN WURDEN BESEITIGT: Die Listen (liste) nach while, until, if und elif betreffend, gibt es (üblicherweise) Einschränkungen bezüglich der Kommandos break [n], continue [n] und goend [n], bei n=1 und/oder n>1. Diese Kommandos dürfen sich dort nur auf Körper beziehen, die sich selbst auch dort befinden. Das gilt nicht für die Listen nach do, then und else, denn diese sind die eigentlichen Arbeits-Listen. Hinter: done fi esac dürfen TAB und/oder Leerzeichen stehen. Es muß ein Zeilenvorschub, Semikolon (;), Kommentar (#) oder EOF folgen. Die folgenden Schlüsselwörter müssen an der Position eines Kommandonamens stehen, bzw. als Einzelargument plaziert werden. Andernfalls werden sie nicht als Schlüsselwort erkannt: if then else elif fi case esac for while until do done time { } {{ }} [ ] [[ ]] in from by to repeat (-Liste) Liste wird in einer Subshell ausgeführt. Entspricht etwa: bish -c "Liste" (-Z-) Die Subshell erbt keine Daten der Shell. Die Klammern wirken nahezu wie ("Liste") . Für Liste gilt hier ein Längenlimit von 2 KB. Nach der Klammer ( haben nur folgende Zeichen Spezialbedeutung: % $ ` ) Diese Maskierung gilt nur für die die Subshell aufrufende Shell. Beispiel: echo aaaaa(echo sss%%%)sss)AAAAA Subshell-Input: echo sss%)sss Ausgabe: sss)sss aaaaaAAAAA Beispiel: (cd \dos; DIR) Nur die Subshell wechselt das Directory! (Liste) Liste wird unix-like in einer Subshell ausgeführt. Für die Subshell wird eine Prozeßkopie hergestellt. Die Subshell erbt alle Daten der Shell. Diese Original-Variante ist nur unter Unix verfügbar. Die Klammern wirken nahezu wie ('Liste') . Nach der Klammer ( haben nur folgende Zeichen Spezialbedeutung: % ) Diese Maskierung gilt nur für die die Subshell aufrufende Shell. Für Liste gilt hier ein Längenlimit von 2 KB, da der Liste-Text im Input-Buffer ausgeführt wird. Allgemein darf Liste allerdings unbegrenzt lang sein. Beispiel: ( echo %%%) ) ) Beispiel: ( echo abc;sleep 20; ( echo erf;sleep 20;echo uvw %) ) 1512 root 9480K 996K wait 1 0:00 0.00% bish 1556 root 9480K 992K wait 0 0:00 0.00% bish 1557 root 9480K 1000K nanslp 0 0:00 0.00% bish Vorstehend eine verschachtelte Subshell. Entsprechend sind zeitweise 3 bish-Prozesse zu beobachten. Der Sinn der Maskierung wird sichtbar. Beispiel: a=zzz (- echo Z$a ) Zzzz (- a=iii; echo Z$a ) Zzzz (- a=iii; echo Z%$a ) Ziii ( echo Z$a ) Zzzz ( a=iii; echo Z$a ) Ziii Es ist erkennbar, daß die Variante (Liste) die Daten der Shell erbt. Die Shell expandiert hier $a nicht. Zum Schluß überschreibt die Subshell die geerbten Daten. { Liste;} Liste wird ausgeführt. Dient zur Blockbildung, um beispielsweise die Wirkung von &&, || oder &| auf beliebig viele Kommandos auszudehnen. {{ Liste;}} (-Z-) Wie oben. Jedoch können per local-Kommando lokale Variablen definiert werden, und das global-Kommando ist hierin lokal. [ ausdruck ] [[ ausdruck ]] Siehe test(K). Das Kommando test ([ [[) ist ein eingebautes Kommando mit einer größeren Anzahl von Test-Funktionen, das zur Steuerung TRUE oder FALSE als Exit-Code zurückgibt. Bei der Zwei-Klammer-Syntax haben nur folgende Zeichen Spezialbedeutung: % " ' ` $ SP TAB NL Deshalb muß direkt hinter ]] eines der drei letztgenannten Zeichen platziert werden. Beispiel: if [[ abc > ABC ]] ;then echo Größer; fi [[ ABC > abc ]] || echo Kleiner test ABC %> abc||echo Kleiner Man beachte, daß wegen dieser anderen Basismaskierung einige Operatoren nicht mehr explizit maskiert werden müssen/dürfen. Die Zwei-Klammer-Syntax stellt auch Vergleiche mit pattern (*?[!a-b]) zur Verfügung: [[ abc = a?c ]] && echo gleich [[ abc != a*bc ]] && echo ungleich Name() { Liste; } Name()) { Liste; )} Name() { Name()) { Liste Liste } )} Definieren Shell-Funktionen. Die Aufrufsyntax ist identisch zu der der 'normalen' Kommandos: Name [Args ...] Shell-Funktionen werden abgespeichert und sind in dem Shell-Prozeß, in dem sie definiert wurden, immer wieder ausführbar. Innerhalb des Funktionskörpers sind positionale Parameter entsprechend dem Funktionsaufruf zugreifbar. Funktionsaufrufe dürfen beliebig verschachtelt und direkt oder indirekt rekursiv sein. Auch quasi-verschachtelte Definitionen sind möglich! (-Z-) Funktionen müssen vor ihrem ersten -aktiven- Aufruf definiert worden sein! Man beachte, daß 'Liste' die gesamte Shell-Syntax zuläßt. Innerhalb von Funktionen sind lokale und statisch-lokale Variablen definierbar (s.u.: local, global, static (-Z-)). --- Die Abschlußzeichen betreffend können mehrere Syntaxformen benutzt werden: SP|TAB|;}NL ohne(!) NL zuvor. oder NL} oder )} ))} )))} ... Die erste Form ist für Ein-Zeilen-Definitionen, die zweite für große Funktionen, wobei ein unabsichtlicher Abschluß innerhalb des Körpers durch Einrücken leicht vermieden werden kann - was ohnehin üblich ist. Die dritte Form ist universell, verlangt aber, daß die Anzahl der ')' in der oben gezeigten Form angekündigt wird. Auf diese Weise können die Funktionskörper wesentlich einfacher und schneller gelesen und gespeichert werden. Denn innerhalb des Körpers dürfen { und } im anderen Zusammenhang beliebig vorkommen. Siehe auch return- und fprint-Kommando. --- Funktionen können zwar nicht direkt verschachtelt definiert werden, jedoch zeitlich nacheinander! Die dritte Abschlußform ist besonders dafür geeignet. Grundsätzlich, wenn Shell-Syntax aktiv(!) durchlaufen wird, werden Funktionen "gelernt"! Man kann also durchaus Funktionsdefinitionen in einen if-Zweig setzen, und diese wird global gespeichert, wenn der Zweig aktiv durchlaufen wird! Mit dem Kommando 'fprint' können Funktionskörper ausgegeben werden. Der Inhalt darf auch beliebiger Text sein, der gar nicht ausführbar ist! time Liste Die Liste wird ausgeführt und die dafür benötigte Zeit auf die Standard-Fehlerausgabe ausgegeben. Die Zeit wird in Sekunden angegeben, weshalb bei kleinen Zeitspannen 0 angezeigt wird. (siehe auch timex(K)) Tilde-Substitution Ein Tilde-Zeichen ~ als erstes Zeichen eines Argumentes wird durch den Inhalt der Environment-Variablen HOME ersetzt. Kommando-Substitution Wenn ein Kommando zwischen $( und ) oder zwischen ` und ` steht, wird seine Standard-Ausgabe an die Stelle dieser Ausdrücke gesetzt. $(Kommando) oder `Kommando` wird also per Umlenkung durch den Text, den Kommando normalerweise auf den Bildschirm ausgeben würde, ersetzt. Alle Zeichen von Kommando werden so interpretiert als befände man sich am Prompt der Kommando-Zeile, auch wenn sich `Kommando` innerhalb von zwei maskierenden " befindet: "`kdo`" (Demaskierung!) Innerhalb von Kommando-Substitutionen sind also äußere Maskierungen -vorübergehend- unwirksam. Maskierungen innerhalb kann man beliebig vornehmen. Nach Abschluß der Einsetzung wird eine äußere Maskierung wieder gültig; der eingesetzte Text wird DANN entsprechend behandelt! Ein Minus-Zeichen direkt nach dem einleitenden Operator $(- `- entfernt anhängende Zeilenvorschübe vom eingesetzten Text. (-Z-) Ein Substitutionsausdruck kann mehrere Kommandos enthalten, die durch die üblichen Zeichen getrennt werden - $(Liste) ist hier erlaubt! Diese Substitutionsausdrücke können ineinander verschachtelt werden; allerdings ` ` nicht (direkt) innerhalb von ` ` . (Maskierungen siehe unten) Arithmetik-Substitution $((arithmetischer_ausdruck)) wird durch das Ergebnis der Berechnung des Ausdrucks ersetzt. Siehe auch Arithmetische Berechnungen, ((arithmetischer_ausdruck)) und Kommando let "arithmetischer_ausdruck" ... Parameter-Substitution Wenn das Dollar-Zeichen $ einem Namen, einem oder mehreren Digits oder einem der Zeichen * @ # ? - $ ! voransteht, findet Parameter-Substitution statt. Ein durch einen Namen identifizierter Parameter ist eine Shell-Variable (benamter Parameter) und ist standardmäßig global. Parameter haben Zeichenketten beliebiger Länge als Inhalt. Der dafür reservierte Speicher wird dynamisch verwaltet, weshalb es mitunter nützlich sein kann, Variableninhalte per unset-Kommando freizugeben. Es können lokale Variablen definiert werden (s.u.: local (-Z-)). Vereinbarung lokaler Variablen wirkt wie ein Cache, da hier nur eine relativ kleine Namenmenge deklariert werden kann. Bei Erreichen eines Limits wird eine Reorganisation des jeweiligen Variablenspeichers aktiviert. (s.u.:__VLIM__) (s.bish(I)) Wertzuweisung: Name=Wert [Name=Wert] ... Deklaration: Name="" Name='' Name= ... (Inhalt=Null-String) Null-String-Zuweisungen: a= b= c=;d= Drei Zuweisungen : a=aaa b=bbb;c=ccc Eine Zuweisung a=Wert : a=aaab=bbbc=ccc Kommando '=aaa' : =aaa Kommando '=' : = Fehlerhafter Name =aaa : =aaa=AAA Kommando mit 2 Argum. : echo = aaa Kommando mit 3 Argum. : echo aa=AA bb=BB cc=$CC (keine Zuw.!) Zuweis. plus Kommandos : A=aaa echo $A ; B=bbb;echo $B Zuweisung : echo=ohce Spezielle Zuweisungen (s.u. Kommandos local, set) local name:cn name:d.n : c=Zeichen, d=Dezimalzahl, n=Anzahl set name:cn name:d.n : c=Zeichen, d=Dezimalzahl, n=Anzahl Binäre Werte per :d.n : d=0..255 Dies ist Speicherbesorgungs-Syntax, mit calloc() vergleichbar. Normal möglich ist z.B.: set buf:4.130000000 Positionale Parameter werden beim Aufruf der Shell gesetzt. $0 enthält den Shell-Kommandonamen oder den Namen der Script-Datei. Für Shell-Funktionen und Shell-Script-Dateien werden ebenfalls positionale Parameter entsprechend der Aufrufargumente gesetzt, die u.a. mittels $0, $1, $2, ..., ${23}, ... lesbar sind, und lokal sind. Zugriff auf den Inhalt: $KOSTEN2 Shell-Variable. ${KOSTEN2}RG { }, wenn der Name von nachfolgenden Zeichen isoliert werden muß, die sonst als Bestandteil des Namens gewertet würden. Geschweifte Klammern werden ebenfalls gebraucht, wenn mehr als ein Digit bei positionalen Parametern angegeben wird: $1$2$3 $4${19} Positionale Parameter. Indirekter Zugriff auf Variablen-Inhalte: (-Z-) Standard-Zugriffe sind beispielsweise $name und ${name} . Durch Hinzufügen von öffnenden geschweiften Klammern in beliebiger Anzahl werden entsprechend viele Indirektionen vorgenommen: ${{name} ${{{name} ${{{{name} ${{digits} ${{#name} ${{name}} ${{{name}}} ${{{{name}}}} ${{digits}} ${{#name}} Aus Symmetriegründen können auch gleich viele schließende Klammern angegeben werden. ${{{name}} ist ein Syntax-Fehler! Der Inhalt einer Variablen (oder positionaler Parameter) muß selbst ein gültiger Variablenname sein, mit dem wiederum zugegriffen wird, und so weiter. Nichtexistenz von Variablen führt zu Fehlermeldungen, mit Ausnahme des letzten, am tiefsten verschachtelten Namens. Diese Funktionalität erspart die Verwendung des eval-Kommandos, das zwar universeller jedoch viel umständlicher ist. # a=b b=c c=ddd # echo ${{{a} ddd # echo ${{{#a} 3 # Innerhalb von Funktionen kann beispielsweise ${{3} verwendet werden, falls beim Aufruf als drittes Argument ein gültiger globaler Variablenname angegeben wurde: funktion 24 3 qval Die folgenden Variablen werden von der Shell automatisch gesetzt: $* Ersetzt alle positionalen Parameter ab $1, getrennt durch ein Feld-Trenn-Zeichen. $@ dito - Unterschied durch Maskierung "$@". $# Anzahl der positionalen Parameter ab $1. $- Optionen vom Shell-Aufruf oder set-Kommando. $? Exit-Code des letzten ausgeführten Kommandos. $: Kommandonummer, für Prompt-Ausgabe. $. Offset der Kommandos conv, cmpv, list, (-Z-) catv, expr, readmv $/ $] Anzahl expandierte Dateinamen (?*[!]) (-Z-) (siehe set -f) $, $} Anzahl Argumente hinter Kommando-Namen (-Z-) $% Das aktuelle Maskierzeichen: % oder \ (-Z-) $$ UNIX: Prozeßnummer der Shell $! UNIX: Prozeßnummer Hintergrund-Kdo $PWD Aktuelles Directory (pwd- u. cd-Kommando). $OLDPWD Vorheriges Directory (cd-Kommando). Diese beiden Variablen werden bei Shell-Start und durch das bish-cd-Kommando gesetzt. $RANDOM Liefert eine Zufallszahl. Eine Zuweisung setzt die Zufallssequenz, was jedoch nicht notwendig ist, weil automatisch. (Siehe unten Gleitkomma-Arithmetik: random()) $SECONDS Liefert die Sekunden seit Shell-Aufruf. Nach einer Zuweisung werden die Sekunden auf diesen Wert addiert. $__ARGS__ Siehe for-Schleife. (-Z-) $__VLIM__ Wird gesetzt bei jeder Reorganisation (-Z-) eines Variablenspeichers: "Anzahl Summe der Summe der Reorga= gewonnenen gewonnenen nisat. Variablen Bytes" Siehe oben. $__MEMn__ Anzahl der realloc()-Aufrufe. (-Z-) Die initialen calloc() und malloc() werden nicht gezählt. $__MEM__ Speicher-Parameter. Siehe ganz oben. (-Z-) Durch aufeinanderfolgendes Lesen von $. (Offset, s.o.) können mehrere verschiedene Werte gelesen werden. Gültige Werte werden jedoch nur erlangt, wenn die jeweilige Definition beim betreffenden Kommando beachtet wird (s.insb. expr(K)). Die betreffenden Kommandos setzen $. nach erfolgreicher Arbeit auf mindestens einen gültigen Wert. Ein eventueller Wert von -1 wäre ungültig. Werte können auch undefiniert sein, da die meisten der in Frage kommenden Kommandos nur einen Wert setzen. Shell-Option -O ist zu beachten! Die folgenden Variablen werden von der Shell benutzt: IFS Interne Feld-Trenn-Zeichen. Standard ist SP-TAB-(CR-)NL. Das erste Zeichen wird benutzt, um Argumente voneinander zu trennen, z.B. bei "$*". PS1 Primärer Prompt-String. Siehe unten. PS2 Sekundärer Prompt-String. Siehe unten. $: Kommandonummer, für Prompt-Ausgabe. Für das Setzen von IFS gilt eine Besonderheit: IFS=' %9%13%10%0' Es können Dezimalzahlen wie vorstehend gezeigt eingebracht werden. Wertebereich 0..255; aus '%%' (\\) wird nicht '%' (\). Deshalb wird aus '%%0' '%\0', nicht aber '%0'. Die bish kann die binäre Null (\0) als Trennzeichen verwenden! (-Z-) Es sollte nicht davon ausgegangen werden, daß an wirklich allen Stellen mit allen denkbaren Kombinationen 0-getrennt werden kann. Getestet wurden bisher 'for A in $B' und '.. | read A B C'. bish berücksichtigt folgende Umgebungsvariablen (Environment): (Setzen nach Shell-Start wird bezüglich des neuen Inhalts ignoriert.) PATH Suchpfade für auszuführende Kommandos. CDPATH Argument-Suchpfade für das cd-Kommando. HOME Standard-Directory für das cd-Kommando, für autoexec.bish, history.bish. Der interne Home-Wert ist anfangs '\'. Die drei vorstehenden Variablen werden beim Start im Environment gesucht, und nochmals nach Abarbeitung von autoexec.bish, ob sie jetzt als Shell-Variablen vorliegen, mit ggf. neuem Inhalt. BISHTEMP, TEMP, TMP, TEMPDIR und TMPDIR in der angegebenen Reihenfolge, zur Angabe eines Verzeichnisses für temporäre Dateien. Standardverzeichnis ist das aktuelle Verzeichnis. BISHAUTOR Um die Autoren-Meldung zu unterdrücken: BISHAUTOR=H.Schellong,Vlotho export BISHAUTOR BISHPROGRAM Um die FreeLizenz-Meldung zu unterdrücken: BISHPROGRAM=FreeLizenz_Software_von_Helmut_Schellong export BISHPROGRAM (BISHAUTOR muß hierfür auch gesetzt sein.) setenv BISHAUTOR H.Schellong,Vlotho setenv BISHPROGRAM FreeLizenz_Software_von_Helmut_Schellong Der Autor selbst macht es wie vorstehend, in der tcsh. Unter Windows geht das auch, dort wo PATH gesetzt wird. Spezielle Substitutionen mit Variablen Einsetzung der Inhaltslänge einer Variablen oder eines Parameters: ${#name} ${#digit...} Einsetzung der Speichergröße einer Variablen: ${:name} Einsetzung der Speicheradresse einer Variablen: ${@name} (als Info) Entweder-Oder-Substitutionen: ${name:-wort} ${digit...:-wort} ${name:+wort} ${digit...:+wort} ${name:=wort} :- Falls 'name' gesetzt und nicht leer ist, wird sein Inhalt eingesetzt, andernfalls 'wort'. :+ Falls 'name' gesetzt und nicht leer ist, wird 'wort' eingesetzt, andernfalls nichts. := Eingesetzt wird der name-Inhalt. Falls 'name' ungesetzt oder leer ist, wird 'wort' zuvor zugewiesen. Positionale Parameter können hier nicht gesetzt werden! Bei fehlendem ':' wird 'name' nur auf gesetzt/ungesetzt geprüft. 'wort' muß ein geschlossener Ausdruck sein, ohne unmaskierte Trennzeichen! Diese Syntax ist verschachtelbar: ${a:-A${b:-$ab' '$c}B}C Kommando 'pwd' wird nur ausgeführt, wenn 'dir' ungesetzt oder leer ist: ${dir:-`pwd`} Falls die Einsetzung nicht benötigt wird, kann das Leer-Kommando ':' folgendermaßen verwendet werden: : ${name:=wort} ${name:=wort} ... Unterschiede zwischen ${#name} und ${:name} ergeben sich, wenn ein Variableninhalt durch Setzen auf einen kleineren Inhalt verkürzt wird. Die Speichergröße wird dadurch nicht verändert. (siehe catv) Die Form ${@ ist nicht mit {{ oder mehr { möglich. Durch die Kommandos 'set :[zahl] name...' und 'local : ...' kann die Länge ${#name} beliebig gesetzt werden, bis maximal ${:name}. Die Länge ${#name} ist einfach nur eine Zahl, die die derzeitige Ausgabelänge einer Variablen anzeigt. Mit dem _Inhalt_ einer Variablen bis zum Ende ${:name} hat dieser Wert nichts zu tun. Die Länge ${#name} wird beispielsweise berücksichtigt von: echo $name ; catv name readmv ; writemv findccc ; findcs Die Länge ${:name} wird hier als Endanschlag beachtet. Mitunter wird auch eine Vergrößerung über ${:name} hinaus vorgenommen. Die Kommandos set, catv können das beispielsweise. Array-Variablen Die bish enthält Einrichtungen zum Umgang mit Arrays, mit denen ungewöhnlich vielfältig und leistungsfähig operiert werden kann. (-Z-) Außerhalb von arithmetischen Ausdrücken: Zuweisungen: A[index]=wert [ B[index]=wert ... ] A[" index "]=wert "A[ index ]"=wert Aindex=wert A[123]=wert A[name]=wert A[$name]=wert A[$((...))]=wert A$name=wert A$name$name=wert A$((...))=wert A[a[3]]=wert A[a[name]]=wert array [von [bis]] A [ wert ... ] set -A name [ wert0 wert1 ... ] typeset -i[base] Aindex=wert ... Lesen: echo ${A[123]} "$A[123]" $Aindex echo ${A[a[ i ] ]} "$A[ a[ i ] ]" array name=A index array name=A 123 array name=A name array name=A $name array name=A $((...)) Wie man sieht, ist hier fast alles erdenkliche möglich, beispielsweise indirekte Indexnamen. Als Index sind eine Konstante oder ein Variablenname gültig. Wie der Index zustandekommt, ist egal. Wichtig zu wissen ist, daß beispielsweise bei a[11]=22 eine Variable namens 'a11' gesetzt wird. Das Zeichen '[' ist beim ERSTEN Argument kein Wildcard! Verschachtelte Substitution ${A[$a]}, $A[$a] ist bei diesen Lesevarianten nicht möglich! Innerhalb von arithmetischen Ausdrücken: Hier gibt es die Erweiterung, daß innerhalb der Index-Klammern unmittelbar ein arithmetischer Ausdruck verarbeitet wird! Dies jedoch nur, wenn nach der öffnenden Klammer ([) KEIN Digit und KEIN Buchstabe steht, sondern beispielsweise ein Leerzeichen: array[ arithm_ausdruck ] Dazu wird der Arithmetik-Modul rekursiv aufgerufen. Andernfalls wird derjenige schnellere Index-Leser aufgerufen, der auch außerhalb von arithm. Ausdrücken arbeitet. Falsch : a[10+3] Richtig: a[ 10+3], a[13], a[i], a[ a*b+1 ] Das Semikolon ist innerhalb [] nicht erlaubt, aber das Komma. (Siehe unten: 'Operatoren') Binäre und sonstige Array-Formen: mit tausenden Elementen und die nur unter einem einzigen Namen bekannt sind, können mit den Kommandos catv, base, prints, cut, ... erzeugt und bearbeitet werden! Das Kommando eval ist für indirekte Zugriffe allgemein nennenswert. Shell-Variablen und Speicher Die Variablen werden folgendermaßen im Speicher angelegt: name0inhalt0 Nach set acc:,10 sieht das so aus: acc0,,,,,,,,,,0 wenn die Variable neu angelegt wurde. Die abschließenden 0-Bytes werden pauschal angefügt, obwohl die Kontrollstruktur drei Längenwerte festhält: l = ln + li Wert li kann kleiner werden, während l und ln unverändert bleiben. set a:.100 # mit 100 Punkten füllen echo ${#a} ${:a} 100 100 set a:-50 # mit 50 Minusz. füllen echo ${#a} ${:a} 50 100 catv a /%n -------------------------------------------------- catv /qq =60,0,a # auf Offset=60 0 Byte schreiben echo ${#a} ${:a} 60 100 catv a /%n --------------------------------------------------......... base -b a +10 45 45 45 45 45 ................. 45 45 45 45 45 45 45 0 46 46 46 46 46 46 46 46 46 Durch catv wurden also 60 Zeichen ausgegeben, mit der unsichtbaren 0 nach dem letzten '-' und vor dem ersten '.'. a=rrrrrrrrrr echo ${#a} ${:a} $a ${@a} 10 100 rrrrrrrrrr 34372645778 Es ist erkennbar, daß die Speichergröße von Variablen ${:name} nie kleiner wird. Das ist nur möglich durch Löschen (unset) und Wiederanlegen. Zur Orientierung und Verhaltensforschung liefert ${@name} die Adresse eines Variableninhalts. catv /qq =60,1,a: echo ${#a} ${:a} 61 100 catv a /%n rrrrrrrrrr---------------------------------------.........q base -b a +10 114 114 114 114 114 114 114 114 114 114 0 45 45 ........ 45 45 0 46 46 46 46 46 46 46 46 46 113 Das Kommando catv allein kann in den gesamten Bereich einer Variablen schreiben und kann ihn auch lesen. Eine Null wird nur hinter der letzten Schreibposition angefügt, wenn die Syntax 'name:' verwendet wird und zuvor mindestens ein Byte geschrieben wurde. Das ermöglicht beliebiges Komponieren von Byte-Folgen. Die Kommandos set und local können in weiten Grenzen initialisierte Variableninhalte erzeugen. Sie sind die Speicherbeschaffer. Zwischenraum-Interpretation Nach Parameter- und Kommando-Substitution wird das Resultat gemäß dem Inhalt der Variablen IFS aufgeteilt und so Argumente gebildet. Man beachte hier die Maskierungsmöglichkeiten, die eine explizite (andersartige) Argumentbildung ermöglichen. (siehe unten.) Explizite Null-Argumente per "" und '' werden erhalten, implizite jedoch nicht. Zwischen $HAND und "$HAND" besteht also ein Unterschied, wenn HAND den Null-String enthält. Mindestens ein Leer-Argument kann man erzwingen durch: "$HAND" oder ""$HAND oder $HAND'' oder ""` kommando ` (wenn kommando nichts ausgibt.) Bei Fehlermeldung sollte zuerst überlegt werden, ob diese durch 'kein Argument' ausgelöst werden konnte. Dateinamen-Expansion Nach Substitution wird jedes Kommando-Wort nach unmaskierten Zeichen ? * [ durchsucht, sofern die Option -f nicht gesetzt ist. Bei Arg0 wird [ nicht bewertet, wenn es eine Konstante ist. Zwei oder mehr entstehende Kommandonamen (Arg0) sind ein Fehler. (siehe regexp®) Ein solches Wort wird durch eine Liste von passenden Dateinamen ersetzt. Paßt kein Dateiname, bleibt das Wort unverändert. Die Dateinamen werden zum Vergleich so: NNNN.EEE oder so: NNNN angeliefert, deshalb würde NNNN. nie gefunden (Punkt!). Achtung! Ein vorhandener Punkt wird als normales Zeichen gewertet. *.* würde daher zu sämtlichen Dateinamen passen, die eine Erweiterung haben. Ein einzelner Stern * paßt zu sämtlichen Dateinamen. Beispiele: echo c:\windows\*\pscrpt.drv Sucht in allen Unterverzeichnissen in \windows nach der angegebenen Datei und zeigt sie per echo-Kommando. \???\??\??\*txt Alle Namen, die mit txt enden, mit oder ohne Punkt davor, in Verzeichnissen mit 2 Zeichen (Erweiterung ausgeschlossen), die in Verzeichnissen mit 2 Zeichen sind, die wiederum in Verzeichnissen mit 3 Zeichen sind. Z.B.: \K.Z\AB\BC\RGTXT ?*erf?*.?[i-o]* Alle Namen, die 'erf' enthalten, und davor und danach -bis zur Erweiterung- mindestens ein beliebiges Zeichen, und die eine Erweiterung haben aus mindestens 2 Zeichen, wobei das zweite ein Buchstabe von I bis O sein muß. Z.B.: kerfi.sig merfolg.ak merfl.roh echo \sys\*\?*.[a-h] \SYS\CFG\INIT.D \SYS\CFG\CF.D \SYS\CFG\NODE.D \SYS\CFG\SD EVICE.D \SYS\CFG\PACK.D \SYS\CFG\SFSYS.D \SYS\CFG\MFSYS.D \SYS\CFG\RC.D \SYS\CFG\SD.D Alle Namen, die in beliebigen Unterverzeichnissen des Verzeichnisses \sys stehen und mindestens ein Zeichen vor einem Punkt haben und nach dem Punkt als letztes Zeichen eines der Zeichen A...H haben. Bei solchen Ausdrücken kann es natürlich mitunter vorkommen, daß hunderte passende Pfade gefunden werden und der Argumentspeicher dafür nicht mehr ausreicht. Die Namen ganz rechts können grundsätzlich auch Verzeichnisse sein! Bei Maskierung der Spezialzeichen mit Hilfe von % (s.u.) wird % nicht entfernt, damit man letztlich z.B. nach Dateien ??K_VES, ??L_VES, ... suchen kann: Suchmuster: %?%??_VES Man sollte jedoch solche Dateinamen vermeiden und am besten per "?*[" oder '?*[' maskieren; die Maskierung per % macht auch nur Sinn, wenn man anschließend tatsächlich Dateinamen suchen will. (Siehe auch oben: $] ) Maskierung Die Spezialbedeutung von Zeichen kann durch verschiedene Formen der Maskierung ( % \ '...' "..." ) aufgehoben werden. % \ Das Prozentzeichen % oder der Backslash \ (per Option -B) ist das generelle Maskierzeichen. Es hebt jede aktuelle Spezialbedeutung auf und wird danach entfernt. Es maskiert sich auch selbst. Wenn es vor einem Zeichen steht, das gar keine (aktuelle) Spezial= bedeutung hat, wird es jedoch nicht entfernt! Man beachte, daß %c (c) für die Shell keine Spezialbedeutung hat, aber wohl für das echo- und print-Kommando. Die Zeichenfolge %NL wird ignoriert (Zeilenverlängerung). Bei Maskierung der Spezialzeichen für die Dateinamen-Expansion (?*[, s.o.) wird % ausnahmsweise nicht entfernt! '..' Zwischen zwei Apostroph ' sind alle Zeichen maskiert; Nach dem ersten ' werden zwei Apostroph ('') durch ein ' ersetzt. 'wer|seq''&&%%' resultiert zu wer|seq'&&%% (-Z-). Oder: Nach einem ersten ' hat nur noch ' eine Spezialbedeutung. ".." Nach einem ersten " haben nur $ ` % und " Spezialbedeutung. $* und $@ sind unmaskiert identisch. Jedoch "$*" entspricht "$1_$2_$3_...", wobei _ das erste Zeichen in IFS ist (i.a. SP), und "$@" entspricht "$1" "$2" ... Beispiel: ZVSCH=Zeilenvorschübe echo "%r%n Bis jetzt gelten 2(!) $ZVSCH, gefolgt von 3 Leerz. " Nach dem Satz folgen 2 Zeilenvorschübe. A r i t h m e t i s c h e B e r e c h n u n g e n Arithmetische Ausdrücke folgen den Regeln der Programmiersprache C, sind aber nicht vollkommen damit identisch (-Z-). Drei Syntax-Formen: let ".." '..' ... und ((..)) und $((..)) Abschließend wird Gleitkomma-Arithmetik beschrieben. Operatoren, von oben nach unten mit fallendem Rang: () [] {} ** :: ! ~ ++ -- + - * :: # unär * / % + - << >> < <= > >= == != & ^ | && ^^ || ?: = += -= *= /= %= &= ^= |= <<= >>= , ; Komma und Semikolon trennen (Teil-)Ausdrücke. (-Z-) Der unäre * berechnet das Quadrat. a^^b entspricht !a^!b . Der Ausdruck x**e entspricht x^e . Der Ausdruck x::n entspricht x^(1/n), also der n-ten Wurzel. Der Ausdruck ::x entspricht sqrt(x). Mittels #z wird der Wert des Bytes nach # generiert. Mehrfachzuweisungen und ++name --name (-Z-) sind möglich. Operator 'cond?true:false' ist vorhanden (-Z-), der zusätzlich auch Referenzen (wie bei C++) verarbeitet! array[ arithm_ausdruck], array[name_oder_zahl]: siehe oben. Auf Variablen kann/sollte ohne das Dollar-Zeichen zugegriffen werden. Zur Berechnung kann das Kommando let (s.u.) verwendet werden und die symbolische Syntax ((ausdruck)) und $((ausdruck)) . Dieser Mechanismus überflügelt (bei Arithmetik) das alte test-Kommando. Datentyp 64 Bit oder 32 Bit breit (siehe typeset -S). Zwischenraumzeichen und NL können beliebig eingefügt werden. Positionale Parameter ($0,$1,...) können nicht verarbeitet werden! --- Integer Zahlenkonstanten sind standardmäßig dezimal. Es sind jedoch Konstanten mit allen Basen von 2 bis 36 und 256 verarbeitbar! Dazu muß 'base#number' angegeben werden. Die Ausgabebasis für $((...)) kann man so: $((base#, ...)) setzen,(-Z-) wobei dies temporär die globale Basis überschreibt, die mittels 'typeset -sbase' (s.u.) gesetzt werden kann. Ausdruckbasis 256 $((256#, ...)) funktioniert allerdings nicht! Beispiel: V44=44 echo $(( W=---23+$V44* -(2+-5);1111 )) echo $W ((D={[(11+2)*3-6]*4-33}*5)) echo $D let "A=B=C=W*6-*2*8;W=*W" "D={[(11+2)*3-6]*4-33}*5" echo $A $B $C $W $D Ausgabe: 1111 109 495 622 622 622 11881 495 Man beachte, daß das erste echo-Kommando nur '1111' ausgibt! Die Argumente zu let werden zuerst von der Shell interpretiert und nachfolgend noch einmal vom Arithmetik-Modul (s. eval, trap)! Daher sind HIER positionale Parameter möglich! AUSDR='X=3*7' let "$AUSDR+$2" Möglich sind auch: echo aaa((A=222+111))bbb${A}ccc --> aaabbb333ccc ((bs=123+9))echo $bs --> 132 sofern ( unmaskiert ist. '$((' ist hier NICHT maskiert!: "...$((...))..." Es wird nicht nach Nur-Environment-Variablen gesucht. Folgende Ausdrücke sind durchaus möglich: echo $(( l=8 ; l+(++l+=5) )) $l --> 22 14 echo $(( l=8 ; l+++l+=5 )) $l --> 22 22 Letzterer wird verarbeitet, l bekommt aber eine weitere Zuweisung. NACHgestellte ++ -- werden nicht(!) als Inkrement/Dekrement verarbeitet. (( 16#ffff<256#zzzz && 555<=666 )) && echo TRUE Die Formen 'let ...' und ((...)) haben einen Exit-Code! $(( a=b= c!=48 ? 11 : 22, 88 )) Zuweisung in Abhängigkeit einer Bedingung. Ausgabewert ist 88. (( c>=33 ? a : b = 66 )) In Abhängigkeit wird a oder b auf 66 gesetzt! Klammern beim ternären Operator versperren jedoch solche Referenzen! Diese Konstruktion kann auch mitten in einer Mehrfachzuweisung stehen, und Verschachtelungen (mit Klammern!) sind auch möglich. G l e i t k o m m a - A r i t h m e t i k Eine Gleitkommaverarbeitung erfolgt automatisch, einfach durch Angabe einer Gleitkomma-Notation mit Punkt '.' und/oder Exponentzeichen 'e|E'. Dabei muß vor und hinter dem Dezimalpunkt eine Ziffer stehen. Gültige Notationen: 2.3 +2.3 -2.3 23.45e4 2.3e+4 2.3e-4 2e4 -2e4 Falls eine Konversion zu 2345 vorkommt, wird '.0' angehängt, so daß eine Ausgabe von 2345.0 entsteht, um eine Weiterführung der Gleitkommazahl-Eigenschaft zu gewährleisten. Funktionen verlangen bei Integer-Argumenten den Integer-Typ. Es wäre falsch, bei einer Angabe factorial(3.4) einfach implizit zu factorial(3) oder factorial(4) zu verändern. let "functions()" f= acosh(f) f= acos(f) i= arith_() f= asinh(f) f= asin(f) f= atan2(f,f) f= atanh(f) f= atan(f) f= avogadro() f= boltzmann() f= c() f= cart_polar(f,f,$) f= cbrt(f) f= ceil(f) i= constants() f= copysign(f,f) f= cosh(f) f= cos(f) i= dec_hour(f,$,$) f= degtorad(f) f= e() f= earthacc() f= ec() f= eps0() f= epsilon() f= erfc(f) f= erf(f) f= exp2(f) f= exp(f) f= expm1(f) f= fabs(f) f= factorial(i) f= faraday() f= fdim(f,f) f= floor(f) f= fma(f,f,f) f= fmax(f,f) f= fmin(f,f) f= fmod(f,f) i= formula_yx($,$) f= frexp(f,$) i= functions() i= getround() f= goldenratio() f= gravity() i= hash($,i,i) f= hour_m_s(i,i,i) f= hypot(f,f) f= klitzing() f= ldexp(f,i) f= lgamma(f) i= llrint(f) i= llround(f) f= log10(f) f= log1p(f) f= log2(f) f= logb(f) f= log(f) f= modf(f,$) f= mue0() f= nan() f= nchoosek(i,i) f= nearbyint(f) f= nextafter(f,f) f= nexttoward(f,f) f= pi() f= pi2() f= planck() f= plancke() f= polar_cart(f,f,$) f= pow(f,f) f= quaequ3p(f,f,f) f= quaequ3m(f,f,f) f= quaequ2p(f,f) f= quaequ2m(f,f) f= radtodeg(f) i= random(i) f= remainder(f,f) f= remquo(f,f,$) f= reciprocal(f) f= rint(f) f= root(f,f) f= round(f) f= rpar2(f,f) f= rpar3(f,f,f) f= scalbln(f,i) i= setround(i) f= sinh(f) f= sin(f) f= sqrt2() f= sqrt3() f= sqrt(f) f= tanh(f) f= tan(f) f= tgamma(f) f= trunc(f) f= z0() f: Float, i: Integer, $: Variablenname <-> Wert Als Funktionsargument dürfen nur ein Variablenname oder eine Konstante angegeben werden - kein größerer Ausdruck. Die meisten Funktionen entsprechen dem C-Standard C99. Beschreibungen sind auch in kostenlosen Drafts des Standard vorhanden: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf Beispiel-Skript, welches bish-Gleitkomma intensiv benutzt: http://www.schellong.de/htm/rpar.bish.html Die Funktionen 'rpar2' und 'rpar3' berechnen den Gesamtwiderstand von zwei bzw. drei parallel geschalteten Widerständen: 1 a * b a * b * c ----------------------- ------- ----------------- 1 1 1 a + b a*b + a*c + b*c --- + --- + --- + ... a b c Das ist nicht auf elektrische Widerstände beschränkt. Die Formel gilt z.B. auch für in Reihe geschaltete Kondensatoren. Die Funktion 'nchoosek' wird auch 'n über k' und Binomial-Koeffizient genannt: n! ----------- ; nchoosek(49,6) = 13983816 k! (n-k)! Die Darstellung x! ist die 'Fakultät von x'. Siehe oben factorial(i); Maximum von i ist 1754 bei 80-Bit-Float. Die Maxima bei 'nchoosek' werden davon nicht berührt, da hier die vorstehende Formel in viele Schritte zerlegt wird. Die Funktion z= random(i) liefert Integer-Zufallszahlen und implementiert den Algorithmus 'Spritz', den Nachfolger des 'arc4/RC4'. Kryptographisch sichere, hochqualitative Zufallszahlen werden generiert. Das Funktionsargument i hat zwei besondere Werte und einen Wertbereich: 0 Standard: z = 0..2^32-1 1 Neue Sequenz setzen (return=0). 2..n Max-Wert: z = 0..n-1; n<=2^63-1 (2^64-1) Da der Arithmetik-Modul bei Integer und Gleitkomma vorzeichenbehaftet arbeitet, kann der höchste Wert nur durch random(-1) angegeben werden, wobei ein Teil der Werte von z negativ dargestellt werden. Max-Wert: random(2) .. random(9223372036854775807). Die Funktion random() benötigt keinen seed-Wert zum Ändern der Sequenz der Zufallszahlen. Sie initialisiert sich selbst mit sich ständig ändernden Dateninhalten. Sie initialisiert sich ebenfalls nach einer bestimmten Menge an ausgegebenen Zufallszahlen periodisch neu. Bei 0 = Standard gibt es keine Reduzierung der Werte; Die Deckelung des Wertes der Zufallszahlen erfolgt nicht einfach nur durch eine Restwertdivision, sondern vermeidet einseitige Werte. (Operator ^ ist in der Arithmetik kein Exponent-Operator!) (Siehe oben den Mechanismus '$RANDOM'.) Die Funktion i= hash(name,max,var) liefert Hash-Werte, die als Zugriffsindex geeignet und abhängig von den in 'name' enthaltenen Daten (gewöhnlich Zeichenketten) sind. name Variableninhalt soll eine Byte-Folge sein. Byte-Werte von 0 dürfen enthalten sein. max i = max-1 als Maximum; max = 2..2^32-1; Bei max<2 wird die Begrenzung (i mod max) abgeschaltet und i kann Werte 0..2^63-1 annehmen. var Auswahl des Algorithmus; Wertebereich 0..6 Bei der Auswahl 'var' gibt es drei Algorithmen: 0|1,2,3|4,5,6. Die beiden letzten Algorithmen können mittels je drei verschiedener Aufrufzahlen unterschiedlich gesteuert werden: 1|4 Initialisierung bei jedem Aufruf (wie bei 0). 2|5 Initialisierung durch vorherigen Hash-Wert. 3|6 Initialisierung durch oberen Teil von 'var'. Der obere Teil von 'var' beginnt ab dem fünften Bit. Die unteren vier Bit (0..15) müssen die Auswahl enthalten. Bei 2|5 beträgt der vorherige Hash-Wert nach Shell-Start 0. Falls bei 2|5 der obere Teil von 'var' größer 0 ist, wird der initialisierende Wert (normalerweise der vorherige Hash) auf 0 gesetzt. In Verbindung mit 'Hashes' sind Kollisionen ein wichtiges Thema: Wenn unterschiedliche Daten gleiche Hash-Werte ergeben! Beispiel 1: hash(zeichen,100,0) abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ (a b c d e f ...; ab cd ef gh ...; abcd efgh ijkl ...) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 97 98 99. 6 8 10 12 14 18 20 22 24 40 42 44 46 50 52 54 56 58 74 76 78 80 84 86 88 90. 12 14 18 36 42 54 60 64 66 84 88 90 94. Es sind Kollisionen vorhanden, allerdings wurde für die 52|26|13 Zeichenketten ein enger Wertebereich von 0..99 erzwungen. Innerhalb jeweils einer Länge (1|2|4) gibt es keine Kollision. Beispiel 2: hash(zeichen,58,0) abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 Beim Verhältnis 58:52 noch keine Kollisionen! Die fehlenden 58-52=6 Werte sind 33..38. Die Funktionen 'quaequ[23][pm]' berechnen quadratische Gleichungen. Die Argumente sind von links nach rechts a b c und p q. Das Vorzeichen vor der Wurzel wird durch p und m bestimmt. Die Funktion 'm=getround()' bzw. 'r=setround(m)' liefert den aktuellen Rundungsmodus bzw. setzt diesen: Rundung in Richtung 0.0 : 0 Rundung zur nächsten ganzen Zahl: 1 Rundung in Richtung +Unendlich : 2 Rundung in Richtung -Unendlich : 3 Bei 'setround' ist der Rückgabewert r=1|0 der Okay|Fehlschlag-Wert. Der Exit-Wert außerhalb der Arithmetik ist dazu e=0|1. Folglich ist möglich: let "setround(0)" && echo "Modus 0 gesetzt." Der Modus '1' ist die häufigste Voreinstellung. Die Funktionen 'rint', 'nearbyint' und 'llrint' verwenden den aktuell eingestellten Rundungsmodus. Die Funktionen x= polar_cart(r,phi,y) r= cart_polar(x,y,phi) wandeln polare in kartesische Koordinaten um und umgekehrt. Es ist zu beachten, daß das dritte Argument ($) das zweite Ziel für einen Resultatwert ist. Die Funktionen h= dec_hour(dh,m,s) dh= hour_m_s( h,m,s) wandeln Dezimalstunden (dh) in Stunde, Minute, Sekunde um und umgekehrt. Bei dec_hour() sind die Argumente m,s zwei Ziele ($) für Resultatwerte. Beispiel: 100.01 = hour_m_s(0,0,360036) Die Funktion count= formula_yx(vars,formel) ist eine Besonderheit. Sie errechnet in Formeln (mehrere) X, abhängig von Y, anstatt umgekehrt. Das erspart die algebraische Umstellung einer Formel. Weiterhin eröffnen sich verschiedene Analysemöglichkeiten. Die Bezeichner 'vars' und 'formel' sind Variablennamen. Die Variable 'vars' enthält mindestens 5 Variablennamen. Die Variable 'formel' enthält grundsätzlich beliebigen Shell-Code, der mindestens eine Formelberechnung mit Resultat Y enthalten muß. vars : Ysoll Prozent Divisor Y Parameter_X... formel: Shell-Code mit maximal 2040 Zeichen Umfang. Der formel-Code ruft den Arithmetik-Modul rekursiv auf. Alle Variablennamen sind frei wählbar. Deren semantische Reihenfolge ist jedoch zwingend festgelegt. Die Größe 'Ysoll' bezeichnet den zu erreichenden Sollwert. Mittels 'Prozent' werden initiale Delta-Werte errechnet. Diese werden zyklisch durch 'Divisor' reduziert. Beispiel 1: typeset -f ysoll=290.0 proz=3.0 div=5.0 typeset -f y=0.0 r1=200.0 r2=200.0 r3=300.0 typeset -i count=0 local yc:09 ARITH_FMT='%Lg' formel='let "y= 1.0 / (1.0/r1+1.0/r2+1.0/r3)" "++count" echo $y $r1 $r2 $r3 : $count' vars='ysoll proz div y r1 r2 r3' let "yc=formula_yx(vars,formel)" echo $yc : $y $r1 $r2 $r3 Ausgabe 1: 75.0 200.0 200.0 300.0 : 1 75.8282 206.0 200.0 300.0 : 2 76.6749 206.0 206.0 300.0 : 3 ... ... 290.004 774.752 770.0 1164.43 : 309 289.995 774.752 770.0 1164.29 : 310 289.993 774.704 770.0 1164.36 : 311 4 : 289.993 774.752 770.0 1164.36 Auffällig ist: 300/200 = 1164/772 = 1.5 Der evolutionäre Algorithmus erhöht also die Initialwerte im gleichen multiplikativen Maß. Im Beispiel oben (Formel wie 'rpar3') können 'r3' oder 'r2 r3' beim Inhalt von 'vars' weggelassen werden: Ein Ysoll = 290 ist durch ein Weglassen von 'r2 r3' allerdings nicht mehr erreichbar, weil lediglich 'r1' zur Änderung zur Verfügung steht! Denn r2||r3 = 200||300 = 120, was zur Folge hat, daß 120 nicht erreichbar ist, weil 'r1' dafür unendlich groß werden müßte, was jedoch nicht möglich ist: Ausgabe 2: 119.985 929396.0 200.0 300.0 : 154915 119.985 929396.0 200.0 300.0 : 154916 'formula_yx(): kein Resultat!' -27 : 119.985 929396.0 200.0 300.0 In Beispielen hier werden die Formelgrößen/Parameter: 'r1 r2 r3' bzw. 'a d l' verwendet. Es können in 'vars' jedoch bis zu 5000 Formelgrößen angegeben werden. Die Werte oben für 'proz' und 'div' sind als Ansatz empfehlenswert. Verminderung von 'proz' verursacht mehr Durchläufe, ergibt aber genauere Resultate. Der Rückgabewert 'count' beträgt in der Regel 1 bis 5. Er zeigt an, wie oft 'Divisor' verwendet wurde. Der Zeitbedarf beträgt nur etwa 0,001 Sekunden für 1000 Durchläufe! Beispiel 2: typeset -f ysoll=50.0 proz=3.0 div=5.0 typeset -f y=0 a=1.0 d=0.1 l=100 k=0 r=0 g=0 typeset -i count=0 local yc:09 ARITH_FMT='%Lg' formel='let "k=2.0*a/d" "r=1.0-1.0/(k*k)" "g=k*(1.0+sqrt(r))" % "y=0.24*l/log10(g)" "++count" echo $y $a $d $l : $count' vars='ysoll proz div y a d l' let "yc=formula_yx(vars,formel)" echo $yc : $y $a $d $l Ausgabe 1: 14.9833 1.0 0.1 100.0 : 1 14.864 1.03 0.1 100.0 : 2 15.1082 0.97 0.1 100.0 : 3 ... ... 49.9997 0.28 0.168958 168.999 : 106 50.0001 0.28 0.168959 169.0 : 107 6 : 50.0001 0.28 0.168958 169.0 Auffällig ist auch hier: 100/0.1 = 169/0.169 = 1000 Ausgabe 2: 149.833 1.0 0.1 1000.0 : 1 148.64 1.03 0.1 1000.0 : 2 ... ... 50.0001 1.6144 0.04 460.0 : 77 49.9928 1.6156 0.04 460.0 : 78 3 : 49.9928 1.6144 0.04 460.0 Die Größe 'l' wurde hier größer gewählt: 1000 statt 100. Die Initialisierung bei typeset -f muß nicht per Gleitpunktnotation erfolgen, sondern statt '0.0' ist auch '0' möglich, weil die Option -f (float) Gleitpunkt vorgibt. Kommando 'typeset' erzeugt standardmäßig lokale Variablen. Außerhalb von Funktionen gibt es ebenfalls eine lokale Ebene. Die maximale Anzahl von lokalen Variablen ist relativ gering. Es kann nötig sein, das Kommando 'global' zu verwenden. Falls eine Variable in 'vars' nicht per 'typeset -f' erzeugt wurde, wird sie intern von 'formula_yx()' so verändert, als ob sie per 'typeset -f' erzeugt worden wäre. Siehe auch Kommandos 'localset', 'set' und 'ver l'. FORMYX_ERFOLG: 0.1e-6 FORMYX_DEVDIV: 250.0e3 Vorstehend Konfigurations-Variablen für 'formula_yx()' mit ihren voreingestellten Werten. Der Inhalt der ersten Variable (vorher - aktuell >= ERFOLG) ist ein Schwellenwert für eine Differenz. Die zweite Variable enthält einen Divisor (dev = Ysoll/DEVDIV), der eines von zwei Beendigungskriterien bildet. Ein kleinerer Wert führt zu einem früheren Beenden. let "constants()" avogadro 6.022140857e+23 [mol^-1] boltzmann 1.38064852e-23 [J/K] c 299792458 [m/s] e 2.718281828459045235 [1] Eulersche Zahl earthacc 9.80665 [m/s^2] Erdbeschleunigung ec 1.6021766208e-19 [C] Elementarladung eps0 8.854187817620389851e-12 [As/Vm] Elektrische Feldkon epsilon 1.084202172485504434e-19 [1] faraday 96485.3365 [C/mol] goldenratio 1.618033988749894848 [1] gravity 6.67408e-11 [m^3/(kg s^2)] klitzing 25812.8074555 [Ohm] mue0 1.256637061435917295e-06 [N/A^2] Magnetische Feldkon pi 3.141592653589793239 [1] pi2 6.283185307179586477 [1] planck 6.62607004e-34 [Js] Wirkungsquantum plancke 4.135667662e-15 [eVs] Wirkungsquantum sqrt2 1.414213562373095049 [1] sqrt3 1.732050807568877293 [1] z0 376.730313461772567 [Ohm] Die vorstehenden Service-Tabellen werden von Funktionen ausgegeben. let "functions()" let "n=constants()" ; echo $n echo $((functions())) Bei den letzteren Ausgaben wird zum Schluß '20' bzw. '96' ausgegeben. Kontroll-Variablen ARITH_FMT='%.*Lg' Format für Print-Funktionen ARITH_EXP3=yes Exponent-Darstellung 0 3 6 9 12 15 ... ARITH_DEG=no Grad oder Radiant bei Trigonometrie Gezeigt sind die Voreinstellungen. Falls ein Stern * im Format angegeben wird, dann nur .* für Präzision. Bei .* wird LDBL_DIG (<float.h>) verwendet. Ohne .* kann beispielsweise .10 direkt angegeben werden. 'L' für 'long double' muß zwingend angegeben werden. Als Formatzeichen können f e g F E G gewählt werden. Das Format wird nicht geprüft, da es zu vielschichtig ist! Als 'Ja' wird erkannt: Y y 1 (nur das erste Zeichen), andernfalls 'Nein'. Die Funktionen arith_(), functions() und constants() sorgen dafür, daß die drei Variablen vor ihrer nächsten Verwendung neu gelesen werden. Für einen konvertierten Wert steht begrenzter Speicher zur Verfügung. Dieser reicht aus, um bei einem 128-Bit-Format (Quad-extended-precision) jedes eEgG-Format-Konversionsergebnis zu speichern. Das Format 'fF' jedoch kann prinzipiell ein mehrere Tausend Zeichen langes Konversionsergebnis zur Folge haben! ARITH_FMT='%.*Lf' let "a=23e27";echo $a bish: Arithmetischer Ausdruck: 'Konversion fehlgeschlagen' let "a=23e26";echo $a 2300000000000000000067108864.000000000000000000 Es ist vorstehend erkennbar, daß hinter der Stellenanzahl, die noch eine genaue Zahl repräsentiert, Ungenauigkeiten auftauchen. Deshalb ist es so wichtig, 'epsilon' zu verwenden. Zur Konversion wird die C-Funktion 'snprintf' verwendet. Bei den Operatoren == != && || ^^ ! und bei logischem 'Ist nicht Null' wird Epsilon (LDBL_EPSILON <float.h>) verwendet. Siehe oben 'epsilon()' und 'epsilon'. Ausgaben mit technischer Exponent-Notation: ARITH_FMT='%.5Le' let "a=123e8";echo $a 12.3000e+09 let "a=1.23e8";echo $a 123.000e+06 let "a=1.23e-8";echo $a 12.3000e-09 Exponent: ... mikro milli kilo Mega Giga ... Man kann hier das Wort 'Gleitkomma' als falsch ansehen, da hier überall 'Gleitpunkt' dargestellt ist. Andererseits kann korrekt 'Gleitkomma' (im Deutschen) und 'Floating point' (im Englischen) als Begriff genannt werden. Eine Internationalisierung im Gleitkommabereich wurde nicht vorgenommen. Insgesamt wäre das auch letztlich unsinnig und problematisch. Auf der Ebene der Syntax einer Programmiersprache gibt es ohnehin keine Wahl von '.' oder ','. Auch Tausender-Trennzeichen gibt es nicht. Und die hier beschriebenen Gleitkomma-Merkmale sind ebenfalls auf der Ebene der Syntax der Shell-Programmiersprache befindlich. --- Eine zeichenweise Umformung kann leicht von internen bish-Kommandos vorgenommen werden: conv -T., dval kval teiler ... Mittels 'expr' kann sowieso Alles gemacht werden. Eingabe/Ausgabe Vor der Ausführung eines Kommandos kann seine Ein- und Ausgabe mit einem oder mehreren speziellen Umlenkungs-Argumenten umgelenkt werden. Diese Argumente werden nicht an das Kommando übergeben. Nach Interpretation durch die Shell darf aus ``Datei'' nur ein einzelnes Argument geworden sein. Umlenkungsargumente können auch als eigenständiges Kommando abgesetzt werden, wirken dann global und können schrittweise oder auf einmal zurückgenommen werden (-Z-). Vor die unten angegebenen Zeichen < > können Digits als explizite Angabe des Datei-Handles gestellt werden. Implizit werden die Handles 0< oder 1> angenommen. Desweiteren können die Buchstaben b O_BINARY-Modus t O_TEXT-Modus e O_EXCL - Exklusive Kreation, mit entsprechendem Exit-Kode. s O_SYNC-Flag C O_NOCTTY-Flag N O_NDELAY(SCO)- oder O_NONBLOCK-Flag B Blockmode (siehe unten) (SCO-Unix,[WinNT]) vorangestellt werden (-Z-): [{b|t}esCNB][digit]{>|<} Standardmäßig ist BINARY eingestellt, auch für die Handles 0,1,2. Bei den Umlenkungsformen mit '&' haben b oder t keinen Sinn! Blockmode: Die lseek()-Funktion (siehe Kommando 'seek') wird auf BlockMode eingestellt und arbeitet somit nicht mit Byte-Einheiten, sondern mit Sektor-Einheiten (je 512 Byte). Auf diese Weise können Objekte bis 1 TeraByte Größe erfaßt werden. Dabei: Lesen und Schreiben nur mit n=x*512 ! bish64 (z.Z.UnixWare7) arbeitet stets im LARGEFILE-Modus. <Datei Standard-Eingabe kommt aus Datei. >Datei Standard-Ausgabe geht zu Datei. Datei wird erzeugt oder auf Null-Größe gebracht. Bei gesetzter Option -N gibt es eine Fehlermeldung, wenn Datei schon existiert und Inhalt hat. <>Datei Datei wird zum Lesen und Schreiben geöffnet und mit Handle 0 verknüpft. Datei wird erzeugt, falls sie nicht existiert, und bei Existenz NICHT auf Null-Größe gesetzt. >|Datei Ignoriert eine gesetzte Option -N. >>Datei Standard-Ausgabe geht zu Datei. Datei wird erzeugt oder es wird an bisherigen Inhalt angehängt. << Wort HERE-Dokument: <<-Wort Handle 0 wird mit dem Text verknüpft, der nach Wort folgt. Der Text wird beendet durch 'Wort' falls Wort ebenfalls 'Wort' lautet, oder durch EOF. Bei <<- werden führende TABs entfernt. Nach <<[-] hat kein Zeichen Spezialbedeutung. Nicht innerhalb von $( ) oder ` ` verwenden! Siehe unten. <&Digit Die Standard-Eingabe (Handle 0) wird mit Handle Digit verknüpft. >&Digit Die Standard-Ausgabe (Handle 1) wird mit Handle Digit verknüpft. <&- Standard-Eingabe wird geschlossen. Als Argument: Verkn. mit /dev/null Als Kommando: close(); >< nicht anwendbar. >&- Standard-Ausgabe wird geschlossen. Als Argument: Verkn. mit /dev/null Als Kommando: close(); >< nicht anwendbar. >&t0 ioctl(fd, TIOCNOTTY, 0) >&t1 ioctl(fd, TIOCNOTTY, 1) Assoziation als Controlling Terminal (<> werden ignoriert; keine Rückverkn.) >&c0 fcntl(fd, F_SETFD, 0) >&c1 fcntl(fd, F_SETFD, 1) Close on exec Flag (<> werden ignoriert; keine Rückverkn.) >< Nimmt die letzte vorgenommene globale Umlenkung zurück. (-Z-) ><<< Nimmt drei globale Umlenkungen zurück. Die Anzahl der < ist hier entscheidend. (-Z-) Globale Umlenkungen entsprechen den System-Calls 'open()' und 'close()', mit zusätzlicher Verknüpfung mit einer ganz bestimmten Dateinummer (handle) und späterer Rückverknüpfung und Wiederherstellung des ursprünglich mit der Dateinummer verknüpften Objektes bzw. seines Dateizeigers. Man kann ein und dieselbe Nummer mehrfach verschachtelt mit mehreren Objekten verknüpfen ...!!! Umlenkungsargumente zu einem Kommando wirken temporär. Nach Ausführung des Kommandos wird automatisch zur ursprünglichen Verknüpfung zurückverknüpft. Bei globalen Umlenkungen muß der Programmierer für eine korrekte Rückführung sorgen. (siehe sane-Kommando) Bei Fehlermeldungen und Shell-exit werden -falls nötig- automatisch die beim Shell-Start vorgefundenen Verknüpfungen wieder hergestellt. Es darf nur eine Umlenkung pro Argument vorgenommen werden: richtig: Kdo <datei1 >datei2 falsch : Kdo <datei1>datei2 datei muß nicht direkt hinter > oder < stehen: richtig: Kdo arg> datei richtig: Kdo arg > datei richtig: Kdo arg >datei richtig: Kdo arg>datei Man beachte bei expliziten Voranstellungen: kdo2>datei # Kommandoname ist kdo2, 1>datei kdo 2>datei # Kommandoname ist kdo, 2>datei k>datei # Kommandoname ist k b>datei # Globale Umlenkung, binär 1>datei b >datei # Kommandoname ist b Am besten ist, man trennt stets explizit: Kdo arg b2>datei 1>&2 Beispiele: Kdo ... >Datei 2>ErrDatei Standard-Ausgabe gelangt in Datei und Standard-Fehlerausgabe gelangt in ErrDatei. Kdo ... 1>Datei 2>&1 Handle 1 wird mit Datei verknüpft. Dann wird Handle 2 mit der Datei verknüpft, mit der Handle 1 verknüpft ist. Also werden Ausgabe und Fehlerausgabe in Datei geschrieben. Kdo ... 2>&1 1>Datei Handle 2 wird mit demjenigen Objekt verknüpft, mit dem Handle 1 verknüpft ist, also mit dem Bildschirm, falls Handle 1 zu diesem Zeitpunkt mit dem Bildschirm verknüpft ist. Dann wird Handle 1 mit Datei verknüpft, ohne die Verknüpfung von Handle 2 zu ändern. Handle 2 wird NICHT mit Handle 1 zusammengeschlossen - Unterschied! Kdo1 2>&1 | Kdo2: Ausgaben von Kdo1 mit Handle 2 gelangen NICHT in die Pipeline! Zu diesem Zweck müßte man Handle 2 mit dem erst SPÄTER gültigen Pipe(Datei!)-Handle verknüpfen. Handle 2 erbt ggf.u.a. lediglich eine andere Pufferungsart von Handle 1. ( '|!' in der bish ersetzt '... 2>&1 | ...' von sh und ksh.) Ein rechts von & angegebener Handle bzw. dessen Verknüpfung wird nie verändert. Er dient nur als Wegweiser zu dem Objekt, mit dem der linksstehende Handle ebenfalls verknüpft werden soll. Die alte Verknüpfung des linken Handle wird zerstört, sofern überhaupt eine vorhanden ist. Vor dieser Zerstörung wird die Verknüpfung aber intern gespeichert, um später wieder hergestellt werden zu können. Beispiele: 1>datei; 9>&1; print -u9 zu1datei; ><<; ... print -u7 zu1datei 1>datei 7>&1; ... echo abcdefghijklmnopqrstuvwxyz > datei <>datei ; catv 8,0 ; 1>&0 ; echo AAAAA ; ><< Neuer Inhalt von datei: abcdefghAAAAA opqrstuvwxyz datei wird zum Lesen und Schreiben per Handle 0 geöffnet. catv liest 8 Zeichen von 0 und schreibt sie per Handle 1 zum Bildschirm. Handle 1 wird mit 0 und damit mit datei verknüpft. echo schreibt per 1 in Datei und überschreibt ab der Position, die catv zurückgelassen hat, mit 'AAAAA\n' die Zeichen 'ijklmn'. Eine Alternative: <>datei ; catv 8,0 ; print -u0 AAAAA ; >< HERE-Dokumente: cat << END hhhhhh hhhh hhhhhhhhhh hhhh END cat > Here <<!!! hhhh hhhh !!! << EEE (-Z-) hhhhh hhhhh hhhhh EEE echo HHHHH cat >< Nicht innerhalb von $( ) oder ` ` verwenden! Ein HERE-Dokument ist quasi das Gleiche wie: print [-r] '.....' | cat Jedoch findet hier prinzipiell eine Interpretation von Spezialzeichen innerhalb des Textes statt. Wegen dieser Ersatzmöglichkeit sind die bish-HERE einfach und elementar implementiert. Andere Shells interpretieren den Text beispw. bei cat << \END aufgrund von '\' (Wort-Quoting). Die temporären Dateien der bish werden hinsichtlich ihrer Handles auf Werte größer 9 justiert, so daß es garantiert keine unerwarteten Konflikte mit programmierten Umlenkungen geben kann. Ausführung von Kommandos geschieht gemäß folgender Reihenfolge: - Argumentbildung und Zuweisungen - Spezial-Kommandos und Schlüsselwörter zur Ablaufsteuerung - time-Pipeline - Alias-Substitution - Interne Kommandos I (:, true, false, set, unset, alias, ...) - Interne Kommandos II (read, cd, echo, [, [[, test, ...) - Shell-Funktionen (anwenderdefiniert) - system-Kommandos (aus Großbuchstaben: z.B. 'DIR') - Batch-Kommandos (*.BAT) - Externe Kommandos I : Shell-Scripts - Externe Kommandos II: Executables Externe Kommandos: Wenn der Name kein Pfadnamen-Trennzeichen (\) enthält, wird in Directories gemäß dem Inhalt von $PATH nach dem Kommando gesucht. Wenn der Name keinen Punkt enthält, werden nacheinander die Endungen "", ".com", ".exe", ".bat", ".bish" probiert. Wurde ein passendes Kommando gefunden, wird untersucht, ob ein Shell-Script vorliegt. Bei einer Endung ".bat" wird unmittelbar an 'system' übergeben. Bei einer Endung ".bish" wird unmittelbar ein bish-Script angenommen. Andernfalls wird geprüft, ob die ersten beiden Zeichen in der Datei "#!" sind. Wenn den Zeichen #! kein Pfadname folgt, wird "...\bish.exe Datei ..." ausgeführt. Falls ein Pfadname folgt (z.B."#!\dos\shell.exe"), wird dieses Kommando anstelle von "bish.exe" verwendet. Wenn die Prüfung kein Shell-Script ergeben hat, wird das passende Kommando selbst als externes Kommando ausgeführt und nicht als Argument an ein Shell-Programm übergeben. Die Directory-Namen in der Variablen PATH können mittels der Zeichen ; , und SP getrennt werden. (UNIX=':') Ein Trennzeichen zu Beginn oder am Ende wird als .\ interpretiert. Wird das aktuelle Directory nicht (explizit) angegeben, wird es am PATH-Ende angenommen. Voreinstellung für PATH ist "\dos;". Siehe auch CDPATH, cd, chdir. Spezial-Kommandos (Intern) Interne Kommandos haben mehrere eminente Vorteile: o Argumente zu internen Kommandos dürfen tausendfach länger sein als die zu externen Kommandos. POSIX fordert hier mindestens 2048 Byte als Summe aller Argumente. Üblich sind beispielsweise 250 KB. Interne Kommandos können hingegen xxx MB entgegennehmen. o Interne können auf alle Objekte direkt und schnell zugreifen. o Es entsteht eine weitere Indirektionsebene, ohne daß eval nötig ist. o Interne sind schneller, da jeweils kein neuer Prozeß gestartet wird. Wenn nicht anders angegeben, erfolgen Ausgaben auf die Standardausgabe und der Exit-Code ist ohne Syntaxfehler 0. Eingabe-/Ausgabe-Umlenkung ist möglich. Alphabetische Auflistung . : alias array autor base basename bgrep break casemv casemv1 casemv2 casemv3 cat catv cd chdir cmpf cmpv coder continue conv copy copy1v? copy2v? copymv copymv1 copymv2 copymv3 crc ctime cut dirname dragon echo env eval exec exit export expr extern false findccc findcs fmode fork fprint fsize fstat fullname global goend goto grep hx ifdef ifset ifenv inv kill let line link list local localset mkdirs mktemp move mtime nop pgr print prints prompt pwd rabbit read readc readl readmv readonly rel remove return run? sane seek set sha256 sha512 shift sleep sortl spreadmv static stime sumv system systime tee test times tr trap true type typeset tz umask unalias unexport unset unsetenv ver wait wc whence writemv xchgv COMMAND.COM-Kommandos können per Großschreibung oder system-Kommando erreicht werden: BREAK CALL CHCP *CHDIR(CD) CLS +COPY CTTY +DATE +DEL(ERASE) +DIR *ECHO *EXIT FOR GOTO IF LOADHIGH(LH) +MKDIR(MD) *PATH PAUSE PROMPT REM +RENAME(REN) +RMDIR(RD) *SET SHIFT +TIME +TYPE VER VERIFY VOL Die in diesem Zusammenhang wichtigsten sind mit + und * gekennzeichnet. : [Arg ...] true [Arg ...] Leerkommandos. Exit-Code ist 0. (-Z-) false [n] [Arg ...] Leerkommando. Exit-Code ist 1 oder n. (-Z-) inv [Arg ...] Leerkommando. Exit-Code wird invertiert. (-Z-) (s.o.: &|) (s.o.: ! ) nop No OPeration - Dieses Kommando tut gar nichts. (-Z-) . Datei [Arg ...] Datei muß ein bish-Script sein und wird innerhalb(!) der aktuellen Shell ausgeführt. Definitionen in Datei bleiben also innerhalb der aktuellen Shell bestehen! Ein exit-Kommando innerhalb von Datei beendet die Shell! Exit-Code stammt vom letzten ausgeführten Kommando. (Unterschied: "bish Datei" ist ein Subprozeß.) break [n] Siehe oben. continue [n] Siehe oben. goend [n] Siehe oben. (-Z-) return [n] Beendet eine Shell-Funktion. n ist der Exit-Code der Funktion. Ohne Angabe von n gilt der Exit-Code des letzten ausgeführten Kommandos. Außerhalb von Funktionen wird ein Script oder eine nichtinteraktive Shell oder eine prompt-Sitzung beendet. exit [n] Beendet die aktuelle Shell oder das Shell-Script exit -P [n] mit Exit-Code n. (-Z-) Ohne Angabe von n gilt der Exit-Code des letzten ausgeführten Kommandos. Achtung! Innerhalb von 'script' bei '. script' wird auch eine interaktive Shell beendet. Hier bietet sich 'return' als Alternative an, oder ein Shell-Aufruf mit Option -P. Nach Aufruf 'bish -P ...' kann man die Shell nur mittels 'exit -P' verlassen. (s.u.: set) 'exit' ohne -P wirkt dann wie ein Super-return oder Reset zum Kommandozeilen-Prompt, egal woher. Eine interaktive Shell kann auch mit ^D oder ^Z verlassen werden - bei Tastatureingabe und sofern Option -I nicht gesetzt ist. goto Label Lenkt die Verarbeitung zur Sprungmarke Label: (-Z-) Label: Label muß an der Position eines Kommandonamens stehen und muß 2-7 Zeichen lang sein. (ohne :) Marken können auch nebeneinander stehen. Marken sind innerhalb von Funktionen und Scripts lokal. In Funktionen hinein oder aus ihnen heraus kann also nicht gesprungen werden. Gleiches gilt für {{ }}-Blöcke. --- Das goto-Kommando wurde relativ simpel implementiert; im Zusammenhang mit Labels werden sehr wenig informierende Daten abgespeichert. Deshalb sollte man standardmäßig nur außerhalb von Syntax-Konstruktionen -wie z.B. Schleifen- springen. Ein Heraussprung aus solcher Syntax ist aber möglich, falls man direkt auf die Grundebene springt, außerhalb jeder Verschachtelungs-Syntax. --- Unter UNIX hat nur die C-Shell ein goto-Kommando, jedoch manchmal wünscht man es sich doch. Zudem ist hier 'goto $LABEL_VARIABLE' möglich. Die Anzahl der Sprungmarken ist allerdings absichtlich limitiert. (s.u.) goto hat keinen Exit-Code. pwd Gibt stets den Namen des aktuellen Directories aus und setzt die Variable PWD. Die Variablen PWD und OLDPWD werden bei Wechseln per system-Kommando -'außen herum'- NICHT gesetzt, sondern nur durch das interne cd-Kommando. cd [Arg] chdir [Arg] cd/chdir - Wechselt das aktuelle Directory; Arg wird zum aktuellen Directory. Ohne Argument wird zum HOME-Directory gewechselt. Die Variablen PWD und OLDPWD werden gesetzt. Mit Argument '-' wird zum $OLDPWD gewechselt. cd berücksichtigt den Inhalt der Variablen CDPATH, für die auch die PATH-Syntax gilt. Standard-cd-Pfad ist: ".;\" . cd wechselt auch das Laufwerk, falls mit angegeben. Beispiel: Wenn ein Directory \usr\sh\cmd\init existiert und CDPATH \usr\sh enthält, genügt die Angabe von cd cmd\init, um nach init zu wechseln. let Arg ... Jedes Argument ist ein separater arithmetischer Ausdruck, der berechnet wird. (siehe oben) Der Exit-Code ist 0, wenn das letzte Ergebnis ungleich 0 ist, andernfalls 1. ((...)) setzt den Exit ebenfalls, $(()) jedoch nicht. test [Arg ...] Siehe test(K). [ und [[ sind Alternativnamen dieses Kommandos, als letztes Argument muß dabei ] bzw. ]] gegeben werden. Siehe oben. run? [!] [Arg1] [Arg2] (-Z-) Die Argumente Arg1 und Arg2 enthalten jeweils bish-Code. Deren Inhalt wird in Abhängigkeit des aktuell vorliegenden Exit-Codes ausgeführt: Bei Exit = TRUE wird der Inhalt des Arg1, und bei Exit = FALSE wird der Inhalt des Arg2 zur Ausführung gebracht. Ist das erste Argument ein '!', wird der Exit-Code invertiert bewertet. Ein Argument wird evaluiert, wenn es existiert und der Inhalt nicht leer ist. Ein Argumentinhalt darf maximal 2040 Zeichen umfassen. Dieses Kommando selbst setzt nicht den Exit-Code. Beispiel: set -B; false run? '....... echo $? ..........' \ '....... echo $? ......' Dieses Kommando ist dazu gedacht, mit wenig Schreibarbeit abhängigen Code in ein oder zwei Zeilen unterzubringen. Argumente wie folgt in einer Schleife: run? continue break sind nicht möglich, da diese Kommandos als Argumente eines Kommandos die umgebende Schleife nicht sehen. Sie müssen an der Position eines Kommandos stehen. run? '3>&2' 'k=$n' Meistens muß mittels '...' eingefaßt werden, damit keine Expansion der Argumente zu run? stattfindet. Es sei denn, dies ist beabsichtigt. echo [Arg ...] Siehe echo(K), print. cat [ -svtemnBT ] [-] [ datei ... ] (-Z-) Verkettet Dateiinhalte. Siehe cat(K). tr [ -cds ] [ string1 [ string2 ] ] (-Z-) Setzt um, löscht und reduziert Zeichen(folgen). Siehe tr(K). wc [ -lwcm ] [ datei ... ] (-Z-) Zählt Zeilen, Worte und/oder Zeichen, oder maximale Längen. Siehe wc(K). cut -cListe [-d'c...'] [-s] [ datei ... ] (-Z-) -fListe -lListe Schneidet Zeichen(folgen/felder), Zeilen oder Worte aus Dateien heraus. Siehe cut(K). expr string : regulärer_ausdruck [[+=] ersatztext] (-Z-) Vergleicht und selektiert Zeichenfolgen. Siehe expr(K), regexp®, xregexp®. grep [ -FSVXBAchilnm[#]qsvyxL ] [ vname ] [ -e ] RA [ datei ... ] (-Z-) Durchsucht Textzeilen nach einem Suchmuster. Siehe grep(K), expr(K), regexp®, xregexp®. bgrep [-gclihstvqM] [name] [-oN|-ON] [-nN] [-f]Folge datei ... bgrep [-gclihstvqM] [name] [-oN|-ON] [-nN] -Fdatei datei ... bgrep [-gclihstvqM] [name] [-oN|-ON] [-nN] -Vname datei ... (-Z-) Durchsucht Dateien nach einer Byte-Folge. Siehe bgrep(K). line [ {-|+}a[-[e]] ] [ datei ... ] (-Z-) Gibt (nicht-)selektierte Zeilen aus. Siehe line(K). rel [arg ...] [ < datei ] [ > datei ] (-Z-) Entfernt aufeinanderfolgende gleiche Zeilen. Siehe rel(K). tee [ -T ] [ datei ] (tee datei < idatei | kdo) (-Z-) (kdo | tee datei | kdo) Bildet ein T-Stück innerhalb einer Pipeline. Siehe tee(K). cmpf [-q] datei1 datei2 [offs1 [offs2]] (-Z-) Vergleicht Dateiinhalte byte-weise. Siehe cmp(K). hx [-a[d][b]] [-b[d][b]] [-t[g78d]] [-o[0]N] [-nN] [-[-]] [datei ...] h k h w (-Z-) H K H l [x]N c[g78d] Wandelt Daten um in lesbare Darstellungsformen. Siehe hx(K). pgr [-] [-zahl] [-cefns] [ datei(en) ...] (-Z-) Kommando zum komfortablen Lesen von Textdateien (pager) Siehe pg(K). coder -e [-nv] [-c code64] [ quell_vname [ziel_vname]] (-Z-) coder -d [-sv] [-c code64] [[quell_vname] ziel_vname ] coder -e [-n] [-c code64] [ quell_datei [ziel_datei]] coder -d [-s] [-c code64] [[quell_datei] ziel_datei ] coder -ue [ quell_datei ] ziel_datei_eintrag (uuencode) coder -ud [-s] [ quell_datei ] (uudecode) coder -A|-C Kodiert Dateien in Textformen um, und umgekehrt. Siehe coder(K). crc =32 crc =64 crc [ -vV{32|64} ] [name] [name] [ datei ... ] (-Z-) crc < datei kdo | crc Errechnet CRC32- oder CRC64-Prüfsummen. CRC64 benutzt das Polynom ECMA182. Die Optionen müssen als ein Argument angegeben werden. Die Reihenfolge der Optionszeichen(folgen) ist beliebig. =32 Wählt dauerhaft CRC32 (Voreinstellung). =64 Wählt dauerhaft CRC64. -32 Wählt CRC32; hat Vorrang vor =32 =64. -64 Wählt CRC64; hat Vorrang vor =32 =64. -v Der Name einer Shell-Variable wird angegeben, in die der generierte Wert gespeichert wird. -V Der Name einer Shell-Variable wird angegeben, aus deren Inhalt der CRC generiert wird. Bei Verwendung von Shell-Variable(n) wird nur ein CRC generiert. Es ist konzeptionell günstiger, wenn der Umgang mit vielen Quellen und Zielen in einem Skript vorgenommen wird, u.a. da dieses Kommando intern ist und somit keinen neuen Prozeß startet. Das Kommando liest auch von der Standard-Eingabe (fd=0). Beim Lesen vor der Tastatur werden hierbei anhängende Zeichen \r und \n entfernt. Beenden durch <Enter> und ^D bzw. ^Z. Ohne Option -v erfolgt Ausgabe zur Standard-Ausgabe: [datei:]crc. Siehe auch crc(K); Die Beschreibung hier hat Priorität. sha256 =23 sha512 =23 sha256 [-23scv] [name] [s_str] [c_str] [datei...] (-Z-) sha512 [-23scv] [name] [s_str] [c_str] [datei...] (-Z-) Diese beiden Kommandos generieren Hash-Werte mit einer Länge von 64 bzw. 128 Hexadezimal-Zeichen. Beispiel: 2ca69efd4ea5af91a637f19ba0bab8b081d2c03773\ c4a72fcbf8817c856b33ef Die Optionen müssen als ein Argument angegeben werden. Die Reihenfolge der Optionsbuchstaben ist beliebig. Die Reihenfolge der Argumente ist nicht beliebig! -2 Wählt die Version SHA2. Dies ist die Voreinstellung. -3 Wählt die Version SHA3 - den Keccak-Algorithmus. =2 Wählt SHA2 dauerhaft, erspart -2. =3 Wählt SHA3 dauerhaft, erspart -3. -s Eine Zeichenkette s_str wird als Argument angegeben, zu der ein Hash-Wert generiert wird. -c Eine Zeichenkette c_str wird als Argument angegeben oder als Variableninhalt übergeben, mit der der generierte Hash-Wert verglichen wird. -v Der Name einer Shell-Variable wird angegeben, in die der generierte Wert gespeichert wird. Zuvor wird (bei Option -c) der Inhalt als c_str festgehalten. Ohne Option -v wird der Hash auf 'stdout' ausgegeben. Datenquellen sind Zeichenkette s_str, die Standard-Eingabe 'stdin' und Dateien. Ohne s_str und Dateien werden Daten von 'stdin' gelesen. Falls hinter '=' nichts oder nicht 2|3 folgt, wird der normale Zustand und -2 (Voreinst.) hergestellt. Die maximale Datenlänge beträgt etwa 2300000 Tera-Byte. OPT ARGS DATEIEN scv v s [datei...] sc. s c [datei...] s.v v s [datei...] .cv v (datei...) s.. s [datei...] ..v v (datei...) .c. c (datei...) ... (stdin) Der Vergleich mit c_str erfolgt bei der ersten Möglichkeit und dann nicht wieder. Der Exit-Wert des Kommandos wird entsprechend gesetzt. Das Speichern in eine Variable erfolgt bei der ersten Möglichkeit und dann nicht wieder. Bei weiteren Datenquellen wird deren Hash auf 'stdout' ausgegeben. Die Algorithmen wurden gemäß der Dokumentation des 'National Institute of Standards and Technology (NIST)' implementiert. Es ist _praktisch_ nicht möglich, zu einem gegebenen Hash-Wert einen zugehörigen Text zu finden. Ebenso nicht möglich ist es, durch zwei verschiedene Texte gleiche Hash-Werte zu generieren. Jeder Text/Dateninhalt der Welt hat folglich einen individuellen Wert, wie ein Fingerabdruck. Theoretisch ist das allerdings nicht zutreffend. rabbit passwort rabbit schlüssel [init] quelldatei zieldatei (-Z-) 128 [ 64 ] zeichen 32 [ 16 ] zeichen 16 [ 8 ] zeichen Dieses Kommando implementiert den Rabbit-Algorithmus. Es handelt sich um eine bekannte und sehr bewährte Stromverschlüsselung. ENTschlüsselung erfolgt genau so, wie die VERschlüsselung. Als Schlüssel- und Init-Vektor müssen Zeichenketten mit 128 bzw. 64 Zeichen Länge übergeben werden. Beispielsweise wie die folgende durch 'coder -C' erzeugte: 2CG8!]m"hAMjcu:TO)9ty*>{[q;v,6BnEoH P\%R/.Uf30D(5dKV\Y1N`#<k7gLes+ Das Kommando verwendet nur das jeweils erste Bit der Zeichen (gerade|ungerade), sodaß Reihen aus 128 bzw. 64 Bit entstehen. Solche Zeichenketten sind in Shell-Skripten sehr gut handhabbar. Sie enthalten nicht die drei Zeichen (' =). Siehe auch: 'conv -i name' Schlüssel und IV können auch durch 32 bzw. 16 oder 16 bzw. 8 Zeichen angegeben werden. Dadurch entsteht: Zeichen: gerade Bit=0, ungerade Bit=1 Hexadezimal-Zeichen Zeichen mit ihren je 8 Bit Bit-Effektivität: 1, 4, 8 Bit pro Zeichen. Der Init-Vektor muß nicht angegeben werden. Das reduziert jedoch (nicht überraschend) die Sicherheit. Das Kommando muß zuvor durch ein Paßwort freigegeben werden. Ein falsches Paßwort löscht eine eventuell bereits erteilte Freigabe. Eine Freigabe bleibt für die Dauer eines bish-Prozesses bestehen. Der Algorithmus kann bis zu 2^68 Bytes generieren ohne ihn neu zu starten (key,iv). Rabbit hat seit 2003 keine Schwächen gezeigt! dragon passwort dragon schlüssel init quelldatei zieldatei (-Z-) 256 256 zeichen 64 64 zeichen 32 32 zeichen Dieses Kommando implementiert den Dragon-Algorithmus. Es handelt sich um eine Stromverschlüsselung. ENTschlüsselung erfolgt genau so, wie die VERschlüsselung. Als Schlüssel- und Init-Vektor müssen Zeichenketten mit 256 Zeichen Länge übergeben werden. Beispielsweise wie die folgende durch 'coder -C' erzeugte: 2CG8!]m"hAMjcu:TO)9ty*>{[q;v,6BnEoH P\%R/.Uf30D(5dKV\Y1N`#<k7gLes+ Das Kommando verwendet nur das jeweils erste Bit der Zeichen (gerade|ungerade), sodaß Reihen aus 256 Bit entstehen. Solche Zeichenketten sind in Shell-Skripten sehr gut handhabbar. Sie enthalten nicht die drei Zeichen (' =). Siehe auch: 'conv -i name' Schlüssel und IV können auch durch 64 oder 32 Zeichen angegeben werden. Dadurch entsteht: Zeichen: gerade Bit=0, ungerade Bit=1 Hexadezimal-Zeichen Zeichen mit ihren je 8 Bit Bit-Effektivität: 1, 4, 8 Bit pro Zeichen. Das Kommando muß zuvor durch ein Paßwort freigegeben werden. Ein falsches Paßwort löscht eine eventuell bereits erteilte Freigabe. Eine Freigabe bleibt für die Dauer eines bish-Prozesses bestehen. Der Algorithmus kann bis zu 2^61 Bytes generieren ohne ihn neu zu starten (key,iv). print [-nru[d]-] [arg ...] Siehe Kommando echo --> echo(K) -n Unterdrückt den abschließenden Zeilenvorschub. -r Unterdrückt die Funktion der Spezialzeichen= folgen (%c,%n,...) des echo-Kommandos. -u[d] d (digit) gibt einen Ausgabe-Handle an. Ohne -u oder ohne d gilt Handle=1. -- Falls das erste auszugebende Argument mit '-' beginnt. Die Optionen müssen als erstes Argument angegeben werden. prints [[v]format[-]] [vname] [arg ...] (-Z-) Dieses Kommando schreibt seine Argumente rechts- oder linksbündig oder zentriert innerhalb einer Feldlänge oder unaufgefüllt oder vorne oder hinten abgeschnitten zur Standard-Ausgabe. format-string: [v]s[.][-:][{ +}][fx][feldlänge][{btn}]... v Ausgabe in Variable 'vname'. (Kein NL am Ende.) s Leitet jedes Argumentformat ein. . Geht zum nächsten 's' und ignoriert zug. Argument. u[d] Angabe eines Handle-Digit, Voreinstellung ist 1. - Linksbündige statt rechtsbündige Ausgabe. : Zentrierte Ausgabe. ' +' Leerzeichen oder '+' wird einem Argument vorange= gestellt, falls dieses mit 0...9 beginnt. fx Für x kann ein beliebiges Zeichen eingesetzt werden, mit dem dann zur Feldlänge aufgefüllt wird, falls das zugehörige Argument kürzer als diese ist. Voreingestellt ist 'f '. Fddd Nach F kann eine ein- bis dreistellige Dezimalzahl eingesetzt werden, die ein Zeichen repräsentiert, das als Füllzeichen verwendet wird. Nötigenfalls führende Nullen angeben! feldlänge Zahl 0 ... 2^31-1 btn Leerzeichen, Tab oder Zeilenvorschub wird nach dem zugehörigen Argument ausgegeben (s.u.). format- Der abschließende Zeilenvorschub wird unterdrückt bei Angabe eines '-' am Ende des Format-strings. Falls weniger Formatelemente als Argumente angegeben werden, wird das letzte Format weiterbenutzt. Falls weniger Argumente als Formatelemente angegeben werden, wird das letzte Argument weiterbenutzt. Wird lediglich ein Format-Argument angegeben, wird so getan, als gäbe es Argumente mit der Länge Null. Exit-Code ist 2 bei Fehlern von System-Funktionen, sonst 0. Dieses Kommando ist überraschend universell! Beispiele: # prints ssss aaa bbb' ' aaabbb bbb bbb # prints sf.20 aaa bbb .................aaa.................bbb # prints s20sf.20 .................... # prints s2s3s-3 abcdef ABCDEF 123456 efDEF123 # prints sf06s' ' 123 333 -222 000123 333-222 # prints s10 `echo "..."` Bei Angabe von 'u' nicht die Feldlänge direkt folgen lassen, sondern gegebenenfalls explizit 'su1..' angeben! Ein u-Handle wird dauerhaft benutzt, wenn es nicht mittels einer erneuten Angabe geändert wird. btn: Es kann erweitert »bbb5bnb1234tt1tnn2« angegeben werden. Dabei wird das letzte Zeichen aus btn berücksichtigt und die Anzahlen werden aufaddiert. Bei Zeilenvorschub \r\n wird nur einmal \r ausgegeben. Z='1234 vvvvvvvvvvvvvvvv TTTTTTTTTT' prints s5b5s-28s $Z » 1234 vvvvvvvvvvvvvvvv TTTTTTTTTT« fprint [+str] fName... (-Z-) Dieses Kommando ist reichlich ungewöhnlich: Man kann damit die Inhalte von Funktionskörpern zur Standard-Ausgabe schreiben. Solche Inhalte können eine fast beliebige Ansammlung von Zeichen sein. Nur die Regeln, die den Funktionsleser Anfang und Ende erkennen lassen, müssen beachtet werden! Eine Funktion mit Textinhalt soll man natürlich nicht als Kommando aufrufen. Als Option kann eine Zeichenkette angegeben werden, die den Zeilen aus den Funktionskörpern vorangestellt wird. Exit ist FALSE, falls ein Name (noch) nicht bekannt ist. Siehe oben die Syntax zu Shell-Funktionen. read [-u#] [Name?Prompt] [Name ...] (Name='Name|-') (-Z-) Der Eingabemechanismus der Shell. Es wird eine Zeile gelesen und gemäß dem Inhalt der Variablen IFS in Argumente zerteilt. Diese Argumente werden der Reihe nach den angegebenen Variablennamen zugewiesen. Überzählige Argumente werden dem Inhalt der zuletzt angegebenen Variablen hinzugefügt. Bei zuwenig Argumenten werden die Variablen entsprechend mit dem Null-String gesetzt. -u# #==0...9 Wahl eines offenen Handles. Standard-Einstellung ist 0. Name darf auch '-' lauten, zwecks Überspringen. An den ersten Namen kann nach einem ? ein Prompt-String angehängt werden. Diese Funktion ist nur bei einer interaktiven Shell gegeben, wenn Standard-Eingabe und Standard-(Fehler-)Ausgabe mit einem Terminal verknüpft sind. (dabei "Name?Prompt" maskieren!) Vor und nach diesem Kommando kann das seek-Kommando verwendet werden. Bei diesem Kommando dürfen einer Variablen maximal 254 Zeichen zugewiesen werden (nur DOS16). Exit=FALSE bei Fehlern oder wenn keinerlei Zeichen gelesen werden konnten; dabei kein Variablensetzen. Beispiele: # read # read "-?<Enter>" # read inp # read "inp?<Enter>" inp2 sind Standard-Verwendungen. # read A <datei liest eine Zeile aus datei. # <datei ; read B ; read C ; read D ; >< liest drei Zeilen aus datei. (Schnelles Lesen!) # echo 'a b c' | read r1 r2 danach: r1=a r2='b c' # read - - f3 - liest das dritte Feld. '-' ist blind für weitere Felder. Wenn Kommandos, wie beispielsweise cat, von der Standard-Eingabe lesen, kann eine solche Eingabe durch <Ctrl><D> oder <Ctrl><Z> (^D^Z) beendet werden. Das gilt nur für Tastatur-Eingabe. (s. readc(K)) Beispielsweise mit zeile="`line`" kann man Eingaben machen, ohne daß Zwischenraum entfernt wird. readl [-u#0] [ Name ... ] (-Z-) Wie 'read', die Zeilen bleiben jedoch völlig unbearbeitet. Zeilenvorschübe werden nicht mit übertragen. (Leere Variable == Leerzeile) (Exit=FALSE == Dateiende) -u# #==0...9 Wahl eines offenen Handles. Standard-Einstellung ist 0. -0 0 ('\0') gilt als Zeilenende! (siehe Kommando 'list') Alle angegebenen Variablen werden mit dem(selben) Zeileninhalt gefüllt. Der Vorteil gegenüber 'line' ist, daß eine Datei dauerhaft geöffnet bleibt und stetig vorrückend, Zeile für Zeile, gelesen wird. Vor und nach diesem Kommando kann das seek-Kommando verwendet werden. Bei diesem Kommando dürfen einer Variablen maximal 1535 Zeichen zugewiesen werden (nur DOS16). Bei sofortigem EOF kein Variablensetzen. readmv writemv spreadmv copymv copymv1 copymv2 copymv3 casemv casemv1 casemv2 casemv3 Diese nachfolgend beschriebenen Kommandos, die das gleiche Konzept verfolgen, können sehr gut zusammen arbeiten. Sie ergänzen sich vorzüglich. Alle speichern Variablen-Zugriffsstrukturen dauerhaft. Diese Strukturen werden durch anmelden/registrieren von Namen existierender Variablen beschafft und gespeichert. Wenn diese Kommandos später ohne Argumente arbeiten, ist alles für die jeweilige Arbeit Notwendige bereits vorhanden. Zusätzlich entfallen die Argumente an sich. Besonders sinnvoll ist dieses Konzept, wenn mit mehreren und immer den gleichen Variablen sehr oft hintereinander immer die gleiche Arbeit verrichtet werden soll. Die ersten drei Kommandos sind relativ aufwendig und bieten eine hohe Variabilität. Das einfachere Kommando copymv ist dafür ein Dreifach-Kommando. Verwendungs-Beispiel: Das Kommando readmv liest Datensätze, die von findccc und findcs erzeugt wurden (Zeilen). Kommando spreadmv filtert aus dem jeweiligen Datensatz die einzelnen Datenwörter heraus und kopiert sie in entsprechend viele Variablen. Kommando copymv kopiert diese Datenwörter, weil oft der vorherige Datensatz später noch gebraucht wird. Kommando catv kann die Datenwörter mit Veränderungen zu einem Datensatz zusammen verketten, und writemv schreibt diese Datensätze in eine große Datensatz-Variable. Daraus kann readmv diese erneut lesen, für einen weiteren Arbeitsgang. Nach einzelnen Anmeldungen von Variablen können hunderttausende von Datensätzen immer wieder in gleicher Weise übersichtlich und rasend schnell verarbeitet werden! readmv [[delim,]offs,]iname ... =oname ... (-Z-) readmv -name ... iname ... =oname ... readmv - iname = =oname -= ... =- ... readmv (Standardverwendung nach namen-Anmeldung) --- Etwa wie 'readl', mit Syntax wie 'catv'. Siehe nachfolgend die Beschreibung zu 'writemv'. Es wird beliebig aus existierenden Variablen gelesen, die zuvor als iname(n) angemeldet werden müssen. Es wird in bereits existierende Variablen geschrieben, die zuvor als =oname(n) angemeldet werden müssen. Es können bis zu 16 Variablen gleichzeitig angemeldet sein. Es müssen mindestens ein iname und ein oname registriert sein. Bei einem iname sind weitere Angaben im Argument möglich. Eine Anmeldung kann eine Erstanmeldung oder eine Wiederholungsanmeldung sein. Bei einer Erstanmeldung werden offs=0 und delim=\n voreingestellt. Angaben im Argument können diese Voreinstellung ändern. Ein zuletzt angegebenes iAnmelde-Argument setzt den dort angegebenen iNamen aktiv. Ein zuletzt angegebenes oAnmelde-Argument setzt den dort angegebenen oNamen aktiv. Dabei können beliebig neue Daten mitgegeben werden. Das Kommando arbeitet stets mit einem aktiven iNamen und einem aktiven oNamen. Eine iVariable wird bis zur Länge ${#iname} gelesen. Der Offset wird nach jedem Lesen direkt hinter die soeben gelesenen Daten gesetzt. Wenn das Datenende erreicht ist, retourniert readmv mit Exit=FALSE. Eine oVariable wird stets von Beginn an beschrieben. Danach wird die Länge ${#oname} entsprechend gesetzt. Diese Länge kann auch durch die Kommandos 'set : ...' und 'local : ...' gesetzt werden. Eine Anmeldung bei bereits vorliegendem Angemeldetstatus aktiviert lediglich, sofern dabei keine Parameterwerte explizit angegeben sind: d,o,iname o,iname iname d,,iname ,,iname ,o,iname Wie zu sehen ist, werden die Parameter anhand der Position ihrer Werte erkannt. Die letzten beiden Zeilen zeigen eine _Abschaltung_ des Delimiters delim='', also einen leeren Delimiter. Variablen, die per Name und nicht per Ziffern angegeben sind, werden von readmv selbst 'ausgepackt' (o): readmv o,iname Selbstverständlich ist $d,$o,$iname möglich. Hier packt die Shell eben die Inhalte aus. --- Eine Abmeldung -name löscht den Zugriff, falls es sich um einen aktiven Namen handelt! Eine Abmeldung - meldet alle iNamen ab und löscht den Zugriff. Eine Abmeldung = meldet alle oNamen ab. und löscht den Zugriff. Eine Abmeldung -= oder =- meldet alle Namen ab und löscht den Zugriff. --- Bei Aufruf von readmv ohne Argumente wird gelesen und geschrieben und der Lese-Offset dem Delimiter entsprechend weitergesetzt. Falls kein Delimiter in den gelesenen Daten gefunden wird oder wenn der Delimiter abgeschaltet ist, wird die iVariable in einem Zug vollständig gelesen. Ein Delimiter wird nicht in eine oVariable übertragen. Falls mehrere Delimiter hintereinander vorkommen, wird auch mehrmals hintereinander die oVariable leer gesetzt! Das sind dann (quasi) Leerzeilen. Der Delimiter kann auf jeden Wert von 0..255 gesetzt werden, und zwar per Dezimalzahl oder durch ein Zeichen ungleich den Ziffern '0'-'9'. Bei delim='\n' wird '\r\n' automatisch berücksichtigt. --- Eine Delimiter-Angabe 12:34:56:78, ist möglich. Dadurch ändert sich das Verhalten dahingehend, daß beliebig viele Delimiter überlesen werden, bis Daten vorliegen, die keine Delimiter sind und daher in die oVariable übertragen werden. Es können hier maximal 11 Delimiter angegeben werden. Eine Angabe 34:, gestattet den anderen Modus mit nur einem Delimiter, denn der ':' ist die Erkennung dafür. Übliche Zwischenraumzeichen sind: 9:10:11:12:13:32 --- Durch einen Aufruf »readmv« wird $. jeweils auf die Offset-Schrittweite gesetzt, bei Exit=TRUE. Dadurch ist ein Vorliegen von '\r\n' erkennbar. Die Zielvariablen werden durch readmv nicht vergrößert, sie müssen vorher schon groß genug sein. Die Größe der Zielvariablen ${#Z} variiert je nach aktuell darin enthaltener Datenmenge/Zeilenlänge. Eine Veränderung der internen Länge ${:Z} jedoch wird bei bei readmv angemeldeten Variablen blockiert. --- Es ist der Gültigkeitsbereich lokaler Variablen zu beachten! readmv erfährt es nicht, wenn angemeldete Variablen durch andere Kommandos gelöscht oder verändert werden! Allerdings informiert der Variablen-Manager readmv bei Änderung von Basiszeigern durch realloc(). --- Vergleich readmv <> readl: -------------------------- readmv: 3.52 real 3.46 user 0.00 sys readl : 14.38 real 6.05 user 8.09 sys (PIII/700) Test-Script: ------------ set Z:.250 [ "$1" == readmv ] && { set F:.300000 catv =F: <bish.c #7700 Zeilen readmv F =Z to 100 repeat do readmv 0,F while readmv do nop done done } [ "$1" == readl ] && { to 100 repeat do <bish.c while readl Z do nop done >< done } Es ist zu beachten, daß Variablen 100 MegaByte groß sein können! Das Kommando catv in Zusammenarbeit mit conv könnte letztlich auch die Aufgabe von readmv erfüllen. Jedoch das Lesen bis jeweils zum (angebbaren) Delimiter hat den Ausschlag für readmv gegeben. catv kann die Daten von readmv weitergeben: catv Z /%r%n =o,,Ziel let "o+=${#Z}+2" --- writemv iname ... =[[anhang,]länge,]oname ... (-Z-) writemv -name ... iname ... =oname ... writemv - iname = =oname -= ... =- ... writemv (Standardverwendung nach namen-Anmeldung) --- Konzeptionell wie das vorstehend beschriebene Kommando readmv. Es wird beliebig aus existierenden Variablen gelesen, die zuvor als iname(n) angemeldet werden müssen. Es wird in bereits existierende Variablen geschrieben, die zuvor als =oname(n) angemeldet werden müssen. Es können bis zu 16 Variablen gleichzeitig angemeldet sein. Es müssen mindestens ein iname und ein oname registriert sein. Bei einem oname sind weitere Angaben im Argument möglich. Eine Anmeldung kann eine Erstanmeldung oder eine Wiederholungsanmeldung sein. Bei einer Erstanmeldung wird anhang=\n voreingestellt. Angaben im Argument können diese Voreinstellung ändern. Ein zuletzt angegebenes iAnmelde-Argument setzt den dort angegebenen iNamen aktiv. Ein zuletzt angegebenes oAnmelde-Argument setzt den dort angegebenen oNamen aktiv. Dabei können beliebig neue Daten mitgegeben werden. Das Kommando arbeitet stets mit einem aktiven iNamen und einem aktiven oNamen. Eine iVariable wird stets komplett gelesen (${#iname}). Eine oVariable wird stets hinter ihr aktuelles Ende beschrieben: ${#oname}. Diese Länge wird nach jedem Schreiben weitergesetzt. Diese Länge kann durch eine explizite Angabe von 'länge' gesetzt werden. Hinter den Daten aus einer iVariablen wird jeweils ein 'anhang' in eine oVariable geschrieben, falls der Anhang nicht abgeschaltet ist. Eine Anmeldung bei bereits vorliegendem Angemeldetstatus aktiviert lediglich, sofern dabei keine Parameterwerte explizit angegeben sind: a,l,oname l,oname oname a,,oname ,,oname ,l,oname Wie zu sehen ist, werden die Parameter anhand der Position ihrer Werte erkannt. Die letzten beiden Zeilen zeigen eine _Abschaltung_ des Anhangs anhang='', also einen leeren Anhang. Variablen, die per Name und nicht per Ziffern angegeben sind, werden von writemv selbst 'ausgepackt' (l): writemv l,oname Selbstverständlich ist $a,$l,$oname möglich. Hier packt die Shell eben die Inhalte aus. --- Eine Abmeldung -name löscht den Zugriff, falls es sich um einen aktiven Namen handelt! Eine Abmeldung - meldet alle iNamen ab und löscht den Zugriff. Eine Abmeldung = meldet alle oNamen ab. und löscht den Zugriff. Eine Abmeldung -= oder =- meldet alle Namen ab und löscht den Zugriff. --- Bei Aufruf von writemv ohne Argumente wird gelesen und geschrieben und der Schreib-Offset der jeweiligen Datenmenge entsprechend weitergesetzt. Der Anhang kann auf jeden Wert von 0..255 gesetzt werden, und zwar per Dezimalzahl oder durch ein Zeichen ungleich den Ziffern '0'-'9'. Eine Anhang-Angabe 12:34:56:78, ist möglich. Es können hier maximal 11 Werte angegeben werden. Übliche Zwischenraumzeichen sind: 9:10:11:12:13:32 --- Durch einen Aufruf »writemv« wird $. jeweils auf die Längen-Schrittweite gesetzt, bei Exit=TRUE. Die Zielvariablen werden durch writemv nicht vergrößert, sie müssen vorher schon groß genug sein. Eine Veränderung der internen Länge ${:Z} wird bei bei writemv angemeldeten Variablen blockiert. --- Es ist der Gültigkeitsbereich lokaler Variablen zu beachten! writemv erfährt es nicht, wenn angemeldete Variablen durch andere Kommandos gelöscht oder verändert werden! Allerdings informiert der Variablen-Manager writemv bei Änderung von Basiszeigern durch realloc(). spreadmv [delim,]iname ... =oname ... (-Z-) spreadmv -name ... iname ... =oname ... spreadmv - iname = =oname -= ... =- ... spreadmv (Standardverwendung nach namen-Anmeldung) --- Siehe auch die vorstehenden Beschreibungen zu 'readmv' und 'writemv'. Es wird beliebig aus existierenden Variablen gelesen, die zuvor als iname(n) angemeldet werden müssen. Es wird in bereits existierende Variablen geschrieben, die zuvor als =oname(n) angemeldet werden müssen. Es können bis zu 24 Variablen gleichzeitig angemeldet sein. Es müssen mindestens ein iname und ein oname registriert sein. Bei einem iname sind weitere Angaben im Argument möglich. Eine Anmeldung kann eine Erstanmeldung oder eine Wiederholungsanmeldung sein. Bei einer Erstanmeldung wird delim = 32:10:9:13:12:11 voreingestellt. Das ist in anderer Notation: ' \n\t\r\f\v' Es handelt sich um die üblichen Zwischenraumzeichen. Angaben im Argument können diese Voreinstellung ändern. Ein zuletzt angegebenes iAnmelde-Argument setzt den dort angegebenen iNamen aktiv. Dabei können beliebig neue Daten mitgegeben werden. Das Kommando arbeitet stets mit einem aktiven iNamen und mindestens einem angemeldeten oNamen. iname=' waw iut ika ' Aus dem vorstehenden Inhalt filtert das Kommando die Wörter waw|iut|ika heraus und schreibt sie in drei oVariablen hinein, wenn als Delimiter mindestens ein Leerzeichen angegeben wurde und falls mindestens drei oVariablen angemeldet sind. Eine iVariable wird bis zur Länge ${#iname} gelesen. Eine oVariable wird stets von Beginn an beschrieben. Danach wird die Länge ${#oname} entsprechend gesetzt. Eine Anmeldung bei bereits vorliegendem Angemeldetstatus aktiviert lediglich, sofern dabei keine Parameterwerte explizit angegeben sind: d,iname iname ,iname Wie zu sehen ist, werden die Parameter anhand der Position ihrer Werte erkannt. Die letzte Zeile zeigt eine _Abschaltung_ des Delimiters delim='', also einen leeren Delimiter. In diesem Fall wird der gesamte Inhalt einer iVariable in eine oVariable kopiert. --- Eine Abmeldung -name löscht den Zugriff, falls es sich um einen aktiven Namen handelt! Eine Abmeldung - meldet alle iNamen ab und löscht den Zugriff. Eine Abmeldung = meldet alle oNamen ab. und löscht den Zugriff. Eine Abmeldung -= oder =- meldet alle Namen ab und löscht den Zugriff. --- Bei Aufruf von spreadmv ohne Argumente wird gelesen und geschrieben. Falls kein Delimiter in den gelesenen Daten gefunden wird oder wenn der Delimiter abgeschaltet ist, wird die iVariable in einem Zug vollständig gelesen. Der Delimiter kann auf jeden Wert von 0..255 gesetzt werden, und zwar per Dezimalzahl oder durch ein Zeichen ungleich den Ziffern '0'-'9'. --- Eine Delimiter-Angabe 12:34:56:78, ist möglich. Es können hier maximal 11 Delimiter angegeben werden. Das Verhalten ist dahingehend, daß beliebig viele Delimiter überlesen werden, bis Daten vorliegen, die keine Delimiter sind und daher in eine oVariable übertragen werden. --- Durch einen Aufruf »spreadmv« wird $. jeweils auf die Anzahl der ausgefilterten und übertragenen Wörter gesetzt. Gibt es in der iVariablen nur Delimiter, wird die erste oVariable leer gesetzt, also ${#oname} = 0. Die Zielvariablen werden durch spreadmv nicht vergrößert, sie müssen vorher schon groß genug sein. Die Größe der Zielvariablen ${#Z} variiert je nach aktuell darin enthaltener Datenmenge/Zeilenlänge. Eine Veränderung der internen Länge ${:Z} jedoch wird bei bei spreadmv angemeldeten Variablen blockiert. --- Es ist der Gültigkeitsbereich lokaler Variablen zu beachten! spreadmv erfährt es nicht, wenn angemeldete Variablen durch andere Kommandos gelöscht oder verändert werden! Allerdings informiert der Variablen-Manager spreadmv bei Änderung von Basiszeigern durch realloc(). --- Vergleich spreadmv <> Shell <> bish <> bash: -------------------------------------------- spreadmv: 0.62 real 0.62 user 0.00 sys bish: 1.53 real 1.53 user 0.00 sys Shell: 12.37 real 12.34 user 0.00 sys bash: 52.34 real 52.18 user 0.00 sys (Core2Duo/3333) Um einen Faktor 20 schneller als gewöhnlicher Shell-Code ist beeindruckend und wohl kaum zu überbieten. Die normale bish-Lösung mit for 5 a b c d e ist mit einem Faktor 2,5 langsamer erstaunlich schnell. Die bash-Lösung, ausgeführt von /usr/local/bin/bash, wird um einen Faktor 84 übertroffen! Die bish ist hier bei gleichem Code 4,2-mal schneller als die bash. --- Test-Script: ------------ Spread() { local i=' weg urg yiihoh qq wusta ' local a:.10 b:.10 c:.10 d:.10 e:.10 spreadmv i =a =b =c =d =e to 1000000 repeat do spreadmv done return 0 } Bish() { local i=' weg urg yiihoh qq wusta ' local a:.10 b:.10 c:.10 d:.10 e:.10 to 1000000 repeat do for 5 a b c d e in $i do nop done done return 0 } Shell() { local i=' weg urg yiihoh qq wusta ' local a:.10 b:.10 c:.10 d:.10 e:.10 local n=1 w:.10 to 1000000 repeat do for w in $i do case $n in 1) a=$w;; 2) b=$w;; 3) c=$w;; 4) d=$w;; 5) e=$w;; esac let "++n>5" && n=1 done done return 0 } Bash() { i=' weg urg yiihoh qq wusta ' a=........... b=........... c=........... d=........... e=........... n=1 w=wwwwwwwww cnt=0 while let "++cnt<=1000000" do for w in $i do case $n in 1) a=$w;; 2) b=$w;; 3) c=$w;; 4) d=$w;; 5) e=$w;; esac let "++n>5" && n=1 done done return 0 } Kontrollausgabe: echo "$.:$a:$b:$c:$d:$e:" spreadmv: 5:weg:urg:yiihoh:qq:wusta: copymv [quelle ziel]... (-Z-) copymv {-|--} copymv Arbeitsverwendung nach Namen-Anmeldung copymv Kommando 1 copymv1 Kommando 1 copymv2 Kommando 2 copymv3 Kommando 3 Dieses Kommando verfolgt das Konzept der dauerhaften Speicherung von Variablen-Zugriffsstrukturen, so wie die vorstehend beschriebenen Kommandos readmv, writemv, spreadmv. Es ist allerdings wegen seiner Aufgabe des Kopierens wesentlich einfacher. Intern und auch in der Bedienung. Hinsichtlich der dauerhaften Speicherung sind es drei unabhängige Kommandos. Vor dem Kopiervorgang (ohne Argumente) müssen ein bis zwölf Paare von Variablennamen existierender Variablen registriert werden: copymv q z q z q z q z q z Zuvor gespeicherte Informationen werden dabei pauschal überschrieben, und ungenutzter Restspeicher wird gelöscht. Die Zielvariablen müssen bezüglich Länge ${:name} groß genug sein. Bei diesen wird nach dem Kopiervorgang die Inhaltslänge ${#name} angepaßt. Durch ein Argument '-' wird der Speicher des aufgerufenen Kommandos gelöscht. Ein Argument '--' löscht bei allen drei Kommandos. casemv suchmuster case-liste [liste ziel]... (-Z-) casemv {-|--} casemv Arbeitsverwendung nach Namen-Anmeldung casemv Kommando 1 casemv1 Kommando 1 casemv2 Kommando 2 casemv3 Kommando 3 Dieses Kommando verfolgt das Konzept der dauerhaften Speicherung von Variablen-Zugriffsstrukturen, so wie das vorstehend beschriebene Kommando copymv. Kommando casemv ist ebenfalls ein Dreifach-Kommando: Es gibt drei voneinander unabhängige Speichersätze. Durch ein Argument '-' wird der Speicher des aufgerufenen Kommandos gelöscht. Ein Argument '--' löscht bei allen drei Kommandos. Das Kommando stellt eine case..esac-Konstruktion in völlig anderer Form dar: case "suchmuster" in a) ...;; b) ...;; C) ...;; D) ...;; *) ...;; esac Vorstehend die bekannte Code-Form. Nachfolgend die gleiche Aufgabe in einer Daten-Form: suchmuster='sl5' cases='32; slk4 sl5 fmk4 /fmk. fms3' liste1='10,13; slk4)echo kfurt: sl5) fendar -jp fmk4)foo; bar' casemv suchmuster cases liste1 ziel1 liste2 ziel2 # ... casemv && { $ziel1; eval $ziel2; } Vorstehend würde ' fendar -jp' ausgeführt werden. Es können bis zu 127 cases/Fälle aufgelistet werden. Bis zu vier Paare [ liste ziel ] sind möglich. Jede Liste darf bis zu 65534 Byte groß sein. Wenn das Suchmuster beispielsweise zum zweiten Eintrag in der case-Liste paßt, wird der zweite Eintrag aus jeder angemeldeten Paar-Liste in das jeweils zugehörige Ziel kopiert. Generell wird eine case-Liste in Einzelschritten von vorne an durchlaufen. Jedoch wenn es keine Regulären Ausdrücke gibt (s.u.), wird eine eventuelle Verlinkung auf das Anfangszeichen durchlaufen, und wenn diese keinen Treffer ergibt, wird auf einen Default-case geprüft. Das Suchmuster ist das sich oft ändernde Element. Dieser Variableninhalt kann nach jeder Änderung durch Aufruf von casemv getestet werden. In eine Paar-Liste können prinzipiell beliebig viele Einträge aufgenommen werden. Allerdings werden im Vergleich zur case-Liste überzählige Einträge ignoriert, und umgekehrt können höher indexierte Einträge in der case-Liste aus nicht vorhandenen korres- pondierenden Einträgen in Paar-Listen nichts ins jeweilige Ziel kopieren. Die Zwischenraumzeichen/Trennzeichen/Delimiter können in jeder Liste zu Anfang in Form von durch Kommata getrennte Dezimalzahlen notiert werden. Abschluß dieser Zahlenkette erfolgt durch ein Semikolon. Ein Weglassen oder nur ein ; zu Beginn führen dazu, daß keine Delimiter registriert werden. In solch einem Fall besteht eine Liste aus nur einem Eintrag. Es sind maximal 14 Delimiter möglich. Jedem Eintrag in einer Paar-Liste muß eines der Zeichen ) : vorangestellt sein. Bis dahin können beliebige Notizen geschrieben werden, die aus Nicht-Zwischenraumzeichen bestehen müssen. Auch direkt dahinter darf kein Zwischenraumzeichen stehen. Die beiden Zeichen ) : sollten logischerweise nicht als Zwischenraumzeichen definiert werden. Falls suchmuster bei der Anmeldung der Variablen genau den Inhalt "note=none" hat, schaltet dies den Notizzwang ab. Inhalt "note=note" schaltet ihn wieder ein. Der jew. Zustand bleibt im laufenden bish-Prozeß erhalten. Jedes Kommando 1,2,3 hat einen solchen Schalter. --- Einem Eintrag in der case-Liste kann ein Zeichen / voran- gestellt werden, um einen Regulären Ausdruck zu kennzeichnen: /_[Rr]k.sa* Das Zeichen / hat daher ein Spezialbedeutung in der gesamten case-Liste. Um ein gewöhnliches Zeichen / herzustellen, müssen zwei davon (//) angegeben werden. Um einen RA zu kennzeichnen, der zusätzlich /// als Inhalt enthält, bedarf es /////// (sieben). Das sind drei Paare und einen weiteren / zur Anzeige eines RA, also eine _ungerade_ Anzahl. Einem Eintrag in der case-Liste, der _keinen_ RA repräsentieren soll, müssen gleichfalls Paare // voran- gestellt werden, um je ein Zeichen / darzustellen, also eine _gerade_ Anzahl von /. Der Ausdruck _[Rr]k.sa* (s.o.) kann auch als gewöhnliche Zeichenfolge verwendet werden, ohne einen einen RA anzeigenden / davor. Eine Angabe von Paaren (//) ist nur erforderlich, falls es sich um _vorne_ stehende / handelt! Ein Listeneintrag /// ist ein RA, der aus / besteht. Ein Eintrag / ist ein _leerer_ RA, der zu allem paßt! Dies ist also der Default-case. (Intern wird dieser nicht als RA geführt!) Auch .* ist ein RA, der zu allem paßt. Eine leere case-Liste paßt ebenfalls zu allem! Als RA werden BRE verwendet; Siehe expr(K). --- Das Kommando retourniert TRUE (0), bei einem zum Such- muster passenden case-Listen-Eintrag oder einer passenden case-Liste, andernfalls FALSE. Die Inhalte von $. $. zeigen den Listenindex nach Finden und denjenigen vom Eintritt in die Suche. Den zweiten Zugriff auf $. nur per bish-Option -O. Angemeldete Zielvariablen werden bei einem argumentlosen Aufruf des Kommandos zu Beginn auf Länge ${#name} = 0 gesetzt. Ohne eine angemeldete Paar-Liste gibt es nur den Exit-Code und den Inhalt von $. als Information. --- Umgang mit Zielvariablen: a='echo aa bb' $a cc b='echo aa; echo $bb' bb=BB eval $b cc funktionieren jeweils. Das legt nahe, Funktionsnamen mit eventuellen Argumenten in Zielvariablen kopieren zu lassen. Die Kommandos eval, run? können aufwendiger sein. --- Das Kommando kann auch für beliebige Mapping-Zwecke benutzt werden. Beispielsweise RGB-Daten (#AACCFF) an Farbnamen zuordnen. Als Farbnamen können z.B. gelb Gelb GELB verwendet werden. Für diese können drei Fälle mit gleichen korrespondierenden Einträgen in Paar-Listen gebildet werden. Gegenüber RA hat dieses Konzept Geschwindigkeitsvorteile. Eine case-Liste ohne RA wird verlinkt und ist unter anderem dadurch ultraschnell. Durch die bis zu vier Paar-Listen kann das Kommando beliebig Code- wie auch Daten-Inhalte selektieren; vertikal und horizontal. Es ist geeigneter, vor der Verwendung eines Suchmusters dieses z.B. per conv anzupassen, als einen Algorithmus zum Ignorieren von Groß- und Kleinschreibung, für jeden Fall individuell, in dieses Kommando einzuflechten. --- Vergleiche der Geschwindigkeit: ------------------------------- bish: 0.39 real 0.39 user 0.00 sys bish: 0.45 real 0.45 user 0.00 sys bish: 0.67 real 0.66 user 0.00 sys bash: 9.97 real 9.92 user 0.00 sys cases='32; aaaa bb bbb bbbb ccc ddd e ee / fff' (1) cases='32; aaaa bb bbb bbbb ccc ddd e ee /.* fff' cases='32; aaaa /bb /\w[BCb]b bbbb /ccc ddd /e ee /.* fff' bash mit normalem case..esac, gleiche cases (1) --- Die bash braucht 26-mal mehr Zeit, was nicht überrascht. Testskript-Code bish: set -fBO casemv muster cases lista ziela listb zielb muster='zkl' casemv echo $.,$.: ec=$? za=${#ziela} zb=${#zielb} echo ":$ziela::$zielb:" to 100 repeat do for m in aaa bbb sld ddd vil ffff do muster="$m" to 1667 repeat do casemv done done done Die Inhalte von lista und listb sind hier nicht gezeigt. Die bish benötigt hier 390 Nanosekunden für eine einmalige Erfüllung der Aufgabe. Das ist noch weniger als beim Test des Kommandos spreadmv (620 ns). Prozessor Core2Duo/3333. readc Liest Tastendrücke und antwortet (-Z-) mit Strings oder Zeichen. Siehe readc(K). list [-fdoecpRF0] [ dir [file ...] ] (-Z-) Listet Inhalte von Verzeichnissen. Die Funktion ähnelt denen von 'ls -R' und 'dir /b/s'. Es werden nur Namen oder Pfadnamen gelistet, also keine weiteren Merkmale, wie Zeitstempel, etc. -f Nur normale Dateien werden gelistet. -d Nur Verzeichnisse werden gelistet. -o Alle Dateinamen, die nicht vom Typ -f und -d sind, werden gelistet. Die Optionen -f,-d,-o sind voreingestellt, falls keine davon angegeben wird. -e Nur leere Verzeichnisse werden gelistet. -c Nur die Anzahl der Namen wird ausgegeben, die Ausgabe der Namen wird unterdrückt. Die Optionen -f,-d,-o werden berücksichtigt. -p Die Kommandoargumente werden mit den Namen aus den Verzeichnissen zu Pfaden verkettet. -R Es wird rekursiv gesucht. Option -p wird hierbei aktiviert. -F In Verbindung mit den Optionen -f,-d,-o können die Argumente nach Typ gefiltert werden. Sinnvoll bei Wildcard-Argumenten. Mit dieser Option werden NUR die Kommando- -argumente (teilweise) gelistet. -0 Als Zeilenvorschub wird 0 ('\0') ausgegeben! Dies nur bei isatty(1)==FALSE. (Siehe Kommando 'readl') Die Optionen müssen als einzelnes Argument angegeben werden. Die Anzahl der Namen wird in $. gespeichert. Dieses Kommando ist nicht dafür da, um schöne, formatierte Listen zu erzeugen, sondern um Daten zu gewinnen zur Weiterverarbeitung. (s. DIR / ls -l) Exit==FALSE, falls eine angegebene Datei nicht existiert. sortl [-r] [-f[nr]#[,[nr]#]...] [-d[c...]] [-D#] [-odatei] [datei...] Sortiert Textdateien zeilenweise. -r Kehrt die Sortierreihenfolge um. (reverse) -f Maximal 4 Feldnummern können angegeben werden, nach denen sortiert wird. Das zuerst angegebene Feld hat die höchste Priorität, usw. Voreinstellung: -f1,2,3,4 Der Buchstabe 'n' bewirkt, daß das betreffende Feld als Dezimalzahl bewertet wird. 'n' kann vor oder nach der Zahl stehen. Die DOS-Version ignoriert 'n'! 'r' wirkt feldbezogen wie -r und zusammenwirkend mit -r: reverse = r != -r -d Angabe der Zwischenraumzeichen, die die Felder abgrenzen. (delimiter) Voreinstellung: -d" TAB" -d ohne nachfolgende Zeichen bedeutet, daß es gar keine Trenner gibt. In diesem Fall werden die Zeilen als ein einziges Feld angesehen. -D Angabe des Zeilenende-Zeichens als Dezimalzahl. Voreinstellung: -D10 -o Ausgabe erfolgt in die hier angegebene Datei, nicht zur Standardausgabe. Falls keine Datei angegeben ist, wird von der Standardeingabe gelesen, jedoch nicht von einem tty-Gerät. Mehrere Dateien werden zusammengefaßt und als eine Gesamtheit sortiert. Dieses -interne- Kommando ist (aus diesem Grund) in Teilbereichen relativ einfach konzeptioniert. Es erwartet, daß alle Inhalte und die Steuerdaten zu jeder Zeile komplett in den Arbeitsspeicher passen. Zu jeder Zeile werden 64/32 Byte (Unix/Dos) zusätzlich benötigt. Das Kommando ist extrem schnell, etwa 2 Sekunden bei 2 MByte:40000z auf einem mittelschnellen PC, einschließlich dem Schreiben der Ausgabedatei - - etwa 6-fach schneller als 'sort'. Unter DOS können Inhalte bis etwa 250 KB in einem Stück sortiert werden. (DOS-sort: 64KB) Darüber hinaus kann man ein kleines bish-Script verwenden, das die Inhalte zerteilt und dann die Teile vertikal+horizontal sortiert. Kommandos dazu: wc, mktemp, line, sortl, ... Ein einzelnes Zeichen am Dateiende nach dem letzten Zeilenvorschub wird von der DOS-Version entfernt - das dürfte fast immer ^Z sein, das sonst nach oben sortiert würde. findccc [-SAN0o_l_a_r_n_i_e_z_L_H_T_,-] quelle ausgabe zeilen [k0 k1]... [kz ke zv]... [z0 z1 zn zj zy mz]... Findet in Quelltexten einer beliebigen Programmiersprache Kommentare, Zeilenkommentare, Zeichenketten-Konstanten und Zeilenvorschübe. -S Ausgabe von nur der festgestellten Ausgabelänge. -A Ausgabe hinter die vorliegende Länge ${#ausgabe}. -N Ausgabe von Zeilenvorschub-Daten wird aktiviert. -0 Der Offset (-o#) wird _nicht_ zur jeweiligen Startposition (s.u.) hinzuaddiert. -o# Angabe eines Offsetwertes für den Quelltext. Voreingestellt ist 0. -l# Angabe einer Länge für den Quelltext ab Offset. Voreingestellt ist Länge = Ende - Offset. -a329 Angabe der Anzahlen von Kommentaren, Zeilen- kommentaren und Zeichenketten. Es kann jeweils 0..9 angegeben werden. Voreingestellt sind 112. Falls die Optionen -anie verwendet werden, muß Option -a als erste davon angegeben werden. -r201 Angabe der Reihenfolge der Abarbeitung der Kommentar[1]-, Zeilenkommentar[2]- und Zeichenketten[3]-Blöcke. Voreingestellt ist 123. Die erste Ziffer bestimmt, welche Position[#] als erste aufgesucht wird, usw. Die Ziffer 0 führt dazu, daß auf der jeweiligen Ziffernposition nichts gesucht wird, da es eine solche Position[#] nicht gibt. -n..-. Berücksichtigt verschachtelte Kommentare und Zeichenketten (nested). Anwählbar per '.' und abwählbar per '-'. Es müssen so viele Zeichen [.-] angegeben werden, wie Kommentare und Zeichenketten definiert sind. Also {0..9}+{0..9} - maximal 18. Für Zeilenkommentare ist eine Verschachtelung nicht konfigurierbar. -i..-. Groß- und Kleinschreibung wird nicht unterschieden (insensitiv), gemäß Zeichensatz ISO8859-15. Anzahlen {0..9}+{0..9}+{0..9} - maximal 27. -e..-. Separiert beide Enden der Bereiche (s.u.). Anzahlen {0..9}+{0..9}+{0..9} - maximal 27. Separierung erfolgt nicht bei einschachtelten Bereichen. -z# Ausgabe von Zeilennummern wird aktiviert (s.u.). Gleichzeitig kann eine Start-Zeilennummer angegeben werden. Voreinstellung ist 1. -Labc Der Bezeichner 'dat' wird hiermit überschrieben. Länge maximal 10 Wort-Zeichen. -Habc Bezeichnervorsatz (Head). Länge maximal 10 Wort-Zeichen. -Tabc Bezeichneranhang (Tail). Länge maximal 10 Wort-Zeichen. , - Füll-/Trennzeichen in der Optionskette. Beispiel: -o23651-l243 Die Optionen müssen als ein einziges Argument angegeben werden. Für die Voreinstellung -a112 ist z.B. gültig: -i..-. . . -. 112 1 1 2 Drei Argumente, die jeweils einen frei wählbaren Variablennamen enthalten: quelle Variable, die den Quelltext enthält. ausgabe Variable, in die Daten geschrieben werden. zeilen Variable, in die die Zeilenanzahl geschrieben wird. Argumente ({0..9}*{2+3+6} <= 99), die je eine Zeichenfolge enthalten: k0 Startsequenz eines Kommentars. k1 Endsequenz eines Kommentars. kz Startsequenz eines Zeilenkommentars. ke Vorzeitig beendende Sequenz Zeilenkommentar, optional, exklusiv, wie auch der Zeilenvorschub. Wenn das erste Zeichen _kein_ Zwischenraumzeichen ist, muß _vor_ der Sequenz ein solches stehen. zv Zeichen für Zeilenverlängerung Zeilenkommentar. z0 Startsequenz einer Zeichenkette. z1 Endsequenz einer Zeichenkette. zn Zeichen, die nicht direkt vor einer Zeichenkette stehen dürfen, -> Abbruch. zj Zeichen(folgen), die direkt vor einer Zeichenkette stehen können. zy Zeichen, die direkt nach einer Zeichenkette stehen können. mz Maskierzeichen oder Maskierzeichenfolge in Zeichenkette. Bei mehr als einem Maskierzeichen ist diese Folge nicht beendend für die Zeichenkette (s.u.). Mit Ausnahme des Optionsargumentes müssen alle Argumente vorhanden sein. Leere Argumente ('') (außer quelle, ausgabe) schalten die jeweilige Funktion ab. Anstelle von '' kann auch vOId verwendet werden. Nämlich in einem Variableninhalt kann kein Leerargument direkt dargestellt werden. Falls z.B. Argument z0 leer ist, werden alle damit in Zusammenhang stehenden Argumente bis mz ignoriert. Falls mz leer ist, entfällt nur dessen Funktion. Bis auf die beendenden Sequenzen beim Zeilenkommentar sind die Sequenzen und Zeichen inklusiv. Zeichenfolgen-Argumente haben keine Längenbegrenzung! Die Zeichen \r \n sollten nicht Bestandteil von solchen Argumenten mit Bezug zur Quelle sein! Diese sind für das Kommando die einzigen Zeichen mit Spezialbedeutung in der Quelle. Eine nicht existierende Variable 'zeilen' wird lokal mit ausreichender Größe angelegt. zn: z.B. in C sind '"' und '\"' möglich! zj: z.B. in C sind L u U u8 möglich! zy: z.B. A W sind nachgestellt möglich! mz: bekannt sind \ und ''. Es handelt sich um eine Auswahl von Einzelzeichen. Bei zj und mz sind auch bis zu 16 Zeichenfolgen mit jeweils mehr als einem Zeichen möglich, getrennt durch Zeilenvorschübe oder benachbart von einem Zeilenvorschub (zj). Ein erkannter Zeilenvorschub schaltet den Einzelzeichenauswahl-Modus ab: Ein Inhalt: \n\nL\r\ru\nU\nu8 (L u U u8) Die Zeichen \r und/oder \n dürfen beliebig zwischen und neben den Zeichenfolgen angeordnet sein. Eine Reihenfolge sollte kf f statt f kf sein, damit f nicht kf abfängt. Siehe Kommando findcs. Variable 'ausgabe' muß bei Option -S wenigstens 25 Byte groß sein. Ohne Option -S kann eine Größe von vielen MB notwendig sein. Das ist vom Quelltext und von Optionen abhängig. Die notwendige Größe ist oft etwa ein Siebtel der Quelle. Kommando findccc vergrößert Variable 'ausgabe' NICHT! Das Management extrem großer Variablen ist besser von außen zu überblicken. (Siehe set, local, unset) Es wird maximal bis zur Länge ${:ausgabe} geschrieben und danach die Länge ${#ausgabe} angepaßt. Die Datenausgabe besteht aus folgenden Folgen von je drei Zeichenfolgen: dat startposition länge ko1 startposition länge ... ko9 startposition länge kz1 startposition länge ... kz9 startposition länge zk1 startposition länge ... zk9 startposition länge ko1s startposition länge ... ko9s startposition länge ko1e startposition länge ... ko9e startposition länge kz1s startposition länge ... kz9s startposition länge zk1s startposition länge ... zk9s startposition länge zk1e startposition länge ... zk9e startposition länge lf startposition länge ln zeilennummer länge dat Daten allgemein (Rasen) ko# Genereller Kommentar kz# Zeilen-Kommentar zk# Zeichenkette ??#s Startsequenzen (nicht eingeschachtelt) ??#e Endsequenzen (nicht eingeschachtelt) lf Zeilenvorschub ln Zeilennummer mit deren Länge Die Ausgabe kann per Schleife ausgewertet werden: for 3 label start length in $ausgabe ... catv offs,len,quelle ... Das typisch nachfolgende Kommando ist: findcs Kommando expr kann weitere Aufgaben übernehmen. Zeilenvorschübe \n und \r\n gemischt werden verarbeitet. Bei vorliegendem \r muß zuvor per Kommando 'tr' oder Editor 'vim' oder anderen Werkzeugen die Quelle konvertiert und/oder repariert werden. Wenn eine ungerade Anzahl von Maskierzeichen vor einer Endsequenz steht, wird die Zeichenkette hier nicht beendet. Bei mehr als einem angegebenen Maskierzeichen wird bei antreffen einer solchen Folge in der Zeichenkette fortgefahren. Beispiel: 'abc''def' (''). Exit-Code: 1 Argumente 2 Variablen 3 Variable quelle 4 Limits Argumente 6 Bereich nicht geschlossen 10..38 Ausgabe a (label, wert) 40..68 Ausgabe b (2. wert) Exit-Werte >0 werden von Fehlermeldungen begleitet. Es gibt hier nur einen Abbruch des Kommandos. Exit=6 ist nur eine Information - ohne Abbruch. --- Dieses Kommando findccc ist ein Anfangspunkt beispielsweise zur Herstellung von Syntax-Highlighting. Die gelieferte Anzahl Zeilen z.B. hilft bei der Festlegung der notwendigen Füllzeichen vor Zeilennummern. set -fB set src:' 1000000' out:' 10000' lines:020 catv 0 =src: <./modules/grase.c findccc src out lines /* */ // '' \\ \ \" \" "\'" LuU '' \\ \ \' \' '' LuU '' \\ ec=$? catv out /:\n echo "exit=$ec" ${:src} ${:out} ${#src} ${#out} $lines Vorstehend ein Beispiel mit folgender Ausgabe: ko1 0 72 dat 699 15 dat 923 36 dat 72 4 zk2 714 3 zk2 959 3 kz1 76 60 dat 717 144 dat 962 36 lf 136 2 zk2 861 3 zk2 998 3 dat 138 454 dat 864 17 dat 1001 36 zk2 592 3 ko1 881 19 zk2 1037 3 dat 595 101 dat 900 20 dat 1040 36 zk2 696 3 zk2 920 3 zk2 1076 3 exit=0 1000000 100000 11948 1593 12 328 Hier wurde Zeichenkette2 für Zeichenkonstanten 'x' in C benutzt. Das vergrößert die Ausgabe beträchtlich. Die Größe ist etwa ein Siebtel der Quelle. ln 1 1 lf 89 2 ln 6 1 ko1 0 72 ln 4 1 dat 138 46 lf 72 2 kz1 91 1 lf 184 2 ln 2 1 lf 92 2 ln 7 1 lf 74 2 ln 5 1 dat 186 60 ln 3 1 kz1 94 42 lf 246 2 kz1 76 13 lf 136 2 ln 8 1 Für vorstehende Ausgabe wurden die Optionen -Nz gegeben. Die Ausgabe ist dabei etwa gleich groß mit der Quelle. --- Zeilenvorschübe (lf) sind ausdrücklich isoliert, mitunter auch ohne Option -N. Option -z erzwingt als Nebeneffekt viele 'lf'. Ohne Option -N sind Zeilenvorschübe generell in allen Bereichen enthalten, wobei in Zeilenkommentaren dies nur bei Zeilenverlängerung vorkommt. Für ein Syntax-Highlighting sind Zeilenvorschübe ohne Bedeutung, da dies keine abdruckbaren Zeichen sind. --- Es können für einen Kommentar z.B. die Sequenzen dätö> <dätö angegeben werden, und in der Quelle werden dann DäTÖ>...<dÄtö gefunden, falls -i zielgerichtet gesetzt ist. Ist auch Option -e entsprechend gesetzt, dann wird z.B. ko4s 90 5 ko4 95 244 ko4e 339 5 ausgegeben. Ein leerer Kommentar (ko4 95 0) würde hier nicht ausgegeben, sondern unterdrückt. Dies ist insgesamt ein Hinweis auf die hochgradige Universalität dieses Kommandos findccc. Unter den Titeln Kommentar, Zeilenkommentar und Zeichenkette müssen auch keine Kommentare, Zeilen- kommentare und Zeichenketten gesucht werden, sondern einfach irgendwelche Bereiche mit irgendwelchen Start- und Endsequenzen. Die Zeichen \n \r können auf mehrere Arten in eine Variable eingefügt werden: mz='u8 set nl:10.1 cr:13.1 L mz="u8${nl}L${nl}u${nl}U" u U' mz=u8,L,u,U ; conv "-t,$nl" mz Auch Kommando expr stellt Wege zur Verfügung. --- Im Regelfall können jeweils mehrere Argumente in eine Variable geschrieben werden, um den Argumente-Wust besser zu bewältigen. Anordnungen mit Zeilenverlängerung sind jedoch bereits akzeptabel. Maximal sind über 100 Argumente erforderlich. Das ist keine Übertreibung. Beispielsweise ein Shell-Programm hat die Bereiche: '__________' "__________" `__________` $(__________) ((__________)) $((__________)) Neben diesen Bereichen mit Start- und Endsequenz gibt es viele weitere. So können Bereiche in größeren Bereichen enthalten sein und dort bestimmte Unterschiede zugeteilt erhalten. findcs [-SAcp1rdwRDW0o_l_L_H_T_,-] quelle zeichenfolgen ausgabe Findet in einer Datenquelle Zeichenfolgen, die in bis zu 99 Gruppen eingeteilt werden können. Es sind maximal 25000 Zeichenfolgen angebbar. Eine Zeichenfolge darf maximal 255 Zeichen enthalten. Eine Gruppe hat eine maximale Größe von 65535 Zeichen inklusive Trennzeichen. Es wird nach feststehenden Zeichenfolgen gesucht, wie beispielsweise Schlüsselwörtern. Eine Vorstufe von Regulären Ausdrücken ist allerdings auch implementiert. -S Ausgabe von nur der festgestellten Ausgabelänge. -A Ausgabe hinter die vorliegende Länge ${#ausgabe}. -c Invertiert die contained-Funktion bei der Konfiguration für eine Gruppe. Der Modus-Buchstabe c ist nun eine Abschaltung. -p Ausgabe aller Zeichenfolgen. Diese können durch eine aktive contained-Funktion umgeordnet sein. -1 Die Quelle wird pauschal mit einer Schrittweite von einem Zeichen durchlaufen. Es wird angenommen, daß kein Rasen vorhanden ist. Dies ist kaum sinnvoll bei den Optionen -dwDW. -r Modus 'raw', bei dem die Übergänge zur gefundenen Folge unbeachtet bleiben. -d Modus 'wort+zwrm', bei dem zweimal vier Übergänge berücksichtigt werden. -w Modus 'wort', bei dem zweimal zwei Übergänge berücksichtigt werden. -R Wie -r. -D Wie -d, aber Übergangsgleichheit wird verlangt. -W Wie -w, aber Übergangsgleichheit wird verlangt. -0 Der Offset (-o#) wird _nicht_ zur jeweiligen Startposition (s.u.) hinzuaddiert. -o# Angabe eines Offsetwertes für den Quelltext. Voreingestellt ist 0. -l# Angabe einer Länge für den Quelltext ab Offset. Voreingestellt ist Länge = Ende - Offset. -Labc Der Bezeichner 'dat' wird hiermit überschrieben. Länge maximal 10 Wort-Zeichen. -Habc Bezeichnervorsatz (Head). Länge maximal 10 Wort-Zeichen. -Tabc Bezeichneranhang (Tail). Länge maximal 10 Wort-Zeichen. , - Füll-/Trennzeichen in der Optionskette. Beispiel: -Latyp,o23657-l243,1 Die Optionen müssen als ein einziges Argument angegeben werden. Bei Option -p wird Argument 'quelle' nicht benutzt: Das Argument muß vorhanden sein, aber in beliebiger Form. Bei Option -S muß die 'ausgabe' 290 (-p) bzw. 30 Zeichen Platz bieten. Drei Argumente, die jeweils einen frei wählbaren Variablennamen enthalten: quelle Variable, die die Quelldaten enthält. zeichenfolgen Variable, die bis zu 99 Variablennamen enthält. Diese enthaltenen Namen bezeichnen Variablen, die die Zeichenfolgen jeweils einer Gruppe enthalten. ausgabe Variable, in die Daten geschrieben werden. Siehe Option -S. Kommando findcs vergrößert Variable 'ausgabe' NICHT! Das Management extrem großer Variablen ist besser von außen zu überblicken. (Siehe set, local, unset) Es wird maximal bis zur Länge ${:ausgabe} geschrieben und danach die Länge ${#ausgabe} angepaßt. --- Die bis zu 99 Namen in 'zeichenfolgen' können im Rahmen der Namenskonventionen prinzipiell beliebig gebildet werden, unter Beachtung der nachfolgend beschriebenen Bedeutungen. Es können ein Bezeichner und ein Modus per Namensteil für jede Gruppe definiert werden: __nnnn_bbb_mm Die Unterstrichlöcher n_b und b_m identifizieren Bezeichner (b) und Modus (m). Führende _n gelten nicht als Unterstrichloch. Es können jeweils mehr als ein _ hintereinander angegeben werden. Die Längen für Bezeichner und Modus betragen jeweils 1 bis maximal 10 Zeichen. Fünf Modus-Zeichen(mengen) sind festgelegt: Modus Modus-Variation Schalter r l k i c d r K I 0 w L 0 w R R W D 0 0 W 0 Das Zeichen 0 ist ein Auslassungszeichen. Bei fehlendem Modus wird eine der Optionen -rdwRDW verwendet oder letztlich der Modus d eingesetzt. Die Zeichen l r sind Abkürzungen von links und rechts und bedeuten, daß nur links oder nur rechts ein Übergang geprüft wird (Anfang und Ende der Zeichenfolgen). Normalerweise werden beide Übergänge geprüft. Bei L R werden links bzw. rechts die Übergänge normal geprüft; Zusätzlich werden die Übergänge rechts bzw. links auf Gleichheit geprüft, wie bei den Modi D W generell. Das dritte Zeichen wählt eine Zeichenklassen-Funktion. Das vierte Zeichen wählt die Wort-Zeichenklasse (s.u.): iI: ISO8859-15, wW: ASCII. Für Modus d ist i voreingestellt, ansonsten w. Bei I und W wird zusätzlich zwischen Klein- und Großschreibung nicht unterschieden, gemäß ISO8859-15. Ein fünftes Zeichen c schaltet die contained-Funktion selektiv nur für die Gruppe ein. Durch Option -c wird diese Einschaltung invertiert und zu einer Abschaltung. Der Modus R und lrLR für die Modi rR sind nur aus Symmetriegründen vorhanden. --- Bei fehlendem Bezeichner wird ein Bezeichner generiert: s01 .. s99 Der Bezeichner dat wird für alle Bereiche in der Quelle verwendet, die nicht mit einer gefundenen Zeichenfolge zusammenfallen. Modus-Angaben in der Gruppe per Namensteil haben Vorrang vor den globalen Optionen -rdwRDW. --- Bei Modus r wird eine in der Quelle passende Zeichenfolge unmittelbar als Fund anerkannt. Bei den Modi dwDW erfolgt jeweils eine weitere Prüfung: Es werden die Übergänge vom ersten Zeichen der Folge zum Zeichen davor und vom letzten Zeichen der Folge zum Zeichen dahinter geprüft: d ( !wort <- wort | wort <- !wort | !zwrm <- zwrm | zwrm <- !zwrm ) & ( !wort -> wort | wort -> !wort | !zwrm -> zwrm | zwrm -> !zwrm ) D ( wort <- wort | !wort <- !wort | zwrm <- zwrm | !zwrm <- !zwrm ) & ( wort -> wort | !wort -> !wort | zwrm -> zwrm | !zwrm -> !zwrm ) w ( !wort <- wort | wort <- !wort ) & ( !wort -> wort | wort -> !wort ) W ( wort <- wort | !wort <- !wort ) & ( wort -> wort | !wort -> !wort ) Wort-Zeichen: A..Z a..z _ 0..9 Zwrm-Zeichen: blank \t \r \n \f \v (Rasen) Für Modus d gelten alle Wort-Zeichen des ISO8859-15. Am Anfang und Ende der Datenquelle kann kein Übergang geprüft werden: Der Übergang ist stets zutreffend. Die Funktionen k K sind jeweils eine Vorstufe eines Regulären Ausdrucks: k 4,3;cccc76543210 K kn4,3;cccc76543210 K .cn4,3;cccc76543210 Es wird durch eine Dezimalzahl (4) angegeben, wie viele Zeichen nachfolgend als feststehende Zeichenfolge (cccc) verglichen werden sollen (Präfix). Nach cccc folgt eine beliebige Zeichenmenge, zu der Zeichen aus der Quelle passen können. Es muß also in der Quelle cccc passen, und nachfolgend passen Zeichen, die in der angegebenen Menge (nach cccc) enthalten sind. Die Dezimalzahl ,3 ist optional und gibt die maximale Anzahl der zu den Zeichenklassen passenden Zeichen an. Das Trennzeichen ; muß vorhanden sein; Es wird pauschal übersprungen. Beispiel: 2;0x0123456789ABCDEFabcdefuU Bei 0;01 gibt es keinen Präfix. Bei 2;0x gibt es nur den Präfix. Ignorieren von Groß- und Kleinschreibung bezieht sich auf den Präfix und die Einzeichenzeichenklasse (.c). Bei Funktion K ist kn ein Zeichenpaar aus Klassen- bezeichner (k) und Anzahlangabe (n). In der Folge .c ist der Punkt eine Anzeige, daß ein Einzelzeichen folgt - eine Einzeichenzeichenklasse (c). Es sind bis zu 50 Folgen kn und/oder .cn möglich! Für die Angabe der Anzahl (n) steht die Zeichenmenge ? + * 0 1 2 3 4 5 6 7 8 9 bereit: ? 0 oder 1 Zeichen + 1 Zeichen mindestens * beliebig viele Zeichen 0-9 absolute Anzahl (nur eine Ziffer!) Die Klassen-Bezeichner (k): w A-Z a-z 0-9 _ B A-Z a-z 0-9 h A-Z a-z _ k A-Z 0-9 _ a A-Z a-z u A-Z l a-z x 0-9 A-F a-f d 0-9 o 0-7 s [ \t\r\n\f\v] b [ \t] g [!-~] p . , v + - Die Bezeichner W H A U L X D O S für inverse Klassen sind zusätzlich wählbar. Beispiel: h1w*0; für gewöhnliche Namen, die nicht mit Ziffern beginnen dürfen. Kein Präfix, keine Suffixzeichenklasse. Für die Suffixzeichen (s.o. 76543210) gilt implizit die Anzahl '*'. Bei Funktion K werden nacheinander Präfix, die Klassen, und die selbstdefinierte Klasse (Suffix) auf ein Passen getestet, soweit vorhanden. Beispiel: float_FLT_d0KW=' d*..1d+.e1v?d+0;flFL d+..1d*.e1v?d+0;flFL d+.e1v?d+0;flFL d*..1d+0;flFL d+..1d*0;flFL' Für Floating-Point-Konstanten in C: Von 123.456e-11L bis 123. und .123f --- Modus r ist günstig, weil absolut alles gefunden werden kann, das paßt. Fast egal, welche Zeichen beteiligt sind. Außerdem entfällt bei r die Prüfung der Übergänge. Begünstigt wird Modus r durch die contained-Funktion: Diese sorgt dafür, daß keine zu suchende Zeichenfolge Bestandteil einer nachfolgenden Zeichenfolge sein kann! Dies geschieht nötigenfalls durch Positionsänderungen intern innerhalb einer jeweiligen Gruppe. Die Reihenfolge der Folgengruppen kann ebenfalls entscheidend sein. Nachfolgend eine Ausgabe dieses Kommandos findcs: uvb 11588 1 uvb 11596 1 uvb 11606 1 dat 11589 1 dat 11597 1 dat 11607 1 uvb 11590 2 uvb 11598 2 uvb 11608 1 dat 11592 4 dat 11600 6 dat 11609 9 Das Kommando findccc erzeugt die gleiche Ausgabe: bezeichner startposition länge Dieses Kommando findcs kann typischerweise nachfolgen, indem eine Ausgabe dat 23766 243 weiter bearbeitet wird: findcs -o23766-l243 ... Die Arbeit von findcs kann Kommando expr fortsetzen, das ebenfalls expr 23766:243variable ... Offset und Länge entgegennehmen kann. Alle diese Kommandos verarbeiten dieselbe Quelle readonly. Exit-Code: 1 Argumente 2 Variablen 3 Variablennamen 4 Unerwartetes null-Zeichen 5 Modus-Angabe 6 Limits 7 Funktionen k K 9 Ausgabe-Variable zu klein Exit-Werte >0 werden von Fehlermeldungen begleitet. Es gibt jedoch nur einen Abbruch des Kommandos. --- Nachfolgend ein Test-Skript mit Ausgaben: set -fB [ $# -eq 0 ] && exit set src:' 1000000' out:' 100000' oper_uvb_d='( ) [ ] -> . ++ -- (typ) ! ~ sizeof _Alignof (typ){} * / % + - { } << >> < <= > >= == != & ^ | && || ? : .* = += -= *= /= %= &= ^= |= <<= >>= , ??= ??( ??/ ??) ??'' ??< ??! ??> ??- # ## ; ... <: :> <% %> %: %:%:' typ_war_r='int32_t uint32_t' str='oper_uvb_d typ_war_r' catv 0 =src: <./modules/grase.c findcs -p src str out ec=$? echo $ec ${:src} ${#src} ${:out} ${#out} [ $ec -eq 0 ] && catv out /:\n Die erste Ausgabe gehört zu den Optionen -pc : oper_uvb_d='( ) [ ] -> . ++ -- (typ) ! ~ sizeof _Alignof (typ){} * / % + - { } << >> < <= > >= == != & ^ | && || ? : .* = += -= *= /= %= &= ^= |= <<= >>= , ??= ??( ??/ ??) ??' ??< ??! ??> ??- # ## ; ... <: :> <% %> %: %:%:' typ_war_r='int32_t uint32_t' Die zweite Ausgabe gehört zu der Option -p : oper_uvb_d='(typ){} (typ) [ ] -> .* ++ -- ??( != ~ sizeof _Alignof ??) *= /= %= += -= { } <<= >>= <= << >= >> == ??! && ^= || &= |= ??= <: ... = + ??- * ??/ <% & ^ | ??< ??> , ??' ( / ) ? < ! :> - ## # ; . %:%: %> %: > : %' typ_war_r='uint32_t int32_t' Hier wurden einige Zeichenfolgen durch die aktive contained-Funktion umgeordnet, damit keine Folge in einer nachfolgenden Folge enthalten ist. Dies ist gewöhnlich nur bei Modus r notwendig. Natürlich geschieht eine Umordnung nur intern! Vorstehend wird das Zeichen ' in einer Folge verwendet. Siehe oben, erst ??'' dann ??' In Shell-Skripten muß '.....'.....' in geeigneter Weise repariert werden, abhängig vom Shell-Programm. remove [-RcsvV] datei|dir ... (-Z-) Löscht Dateien, Verzeichnisse, Verzeichnisinhalte und Verzeichnisbäume - und Links. -R Löscht rekursiv. -c Löscht alle Dateien aus einem Verzeichnis. Kann mit -R kombiniert werden. -s Unterdrückt Fehlermeldungen. -v Zeigt alle Aktivitäten. -V Zeigt alle Aktivitäten, jedoch ohne eine konkrete Dateioperation vorzunehmen. Die Optionen müssen als ein einziges Argument angegeben werden. Exit-Code: 1 Bei harmloseren Fehlern. 2,4 Bei Fehler von System-Funktion und anderen Fehlerhaftigkeiten. Fehler führen meist zu einem Abbruch. Fehlgeschlagenes Löschen wird z.B. toleriert. (Siehe auch 'link') move [-svVc] datei|dir ... (-Z-) Umbenennt Dateien oder Verzeichnisse oder bewegt Dateien und/oder Verzeichnisse in ein Zielverzeichnis hinein. -c Verschiebt nur alle Dateien aus einem Verzeichnis in ein anderes. (Content) Andernfalls werden Quellverzeichnisse rekursiv bearbeitet. Optionen -svV: siehe remove-Kommando. Bei Nichtexistenz des Zieles wird umbenannt, wobei daraus auch eine Verschiebung resultieren darf. Basisnamen der Quellobjekte werden an den Pfadnamen eines existenten Zielverzeichnisses angehängt. Bei mehr als zwei Dateiargumenten muß das letzte ein Verzeichnis sein. Wann immer es möglich ist, werden die Objekte umgelinkt, das heißt es werden nur die Verzeichniseinträge umgeschrieben, nicht aber die Inhalte kopiert und anschließend gelöscht. Das geht sehr schnell und vermeidet Fragmentierung, ist aber laufwerkübergreifend nicht möglich. Unter DOS können Verzeichnisse nicht umgelinkt werden, wohl aber Dateien einzeln. Unter Unix können Spezialdateien (c,b,p,m,s,l) nicht filesystem-übergreifend behandelt werden. Optionen -svV und Exit-Code: siehe remove-Kommando. Besonderheiten (SubPfad): move /a/b /a/b/c move /a/b/c /a/b Relative Pfade ( ./ppp ../ppp ppp ) werden komplettiert, jedoch nicht vollständig bei mehrfachem relativen Bezug: ../../../ppp/./qqq/../rrr Falls so etwas angegeben wird, dann bitte genau gleichsinnig, damit Pfad-Gleichheit und Sub-Pfade erkannt werden können. Bei mehreren Quellen dürfen unterschiedliche Dateitypen vorliegen. Dabei muß jedoch mit unvermutetem Verhalten gerechnet werden. Am besten gibt man in solchen Fällen zunächst einmal die Option -V an, um sich das Verhalten zu betrachten. copy [-RmosvV] datei|dir ... (-Z-) Kopiert Dateien und/oder Verzeichnisse. Ein Zielverzeichnis wird nötigenfalls erzeugt. -R Kopiert rekursiv. Andernfalls werden nur die Dateien eines Quellverzeichnisses berücksichtigt. -m Die Dateizeit wird 'mitkopiert', andernfalls erhält das Ziel die aktuelle Zeit. -o User- und Gruppen-ID werden 'mitkopiert'. (Nur unter Unix sinnvoll.) Unter Unix können Spezialdateien (c,b,p,m,s,l) nicht behandelt werden. Optionen -svV und Exit-Code: siehe remove-Kommando. Siehe auch move-Kommando. mkdirs [-svV] dir... (-Z-) Erzeugt ein oder mehrere Verzeichnisse pro Argument. Beispielsweise aaa/bbb/ccc/ddd wird auf einmal angelegt, soweit Nichtexistenz vorliegt. Optionen -svV und Exit-Code: siehe remove-Kommando. link [-s] pfad neuer_pfad ... (-Z-) Erzeugt einen oder mehrere Links (Verweisnamen) oder Symbolische Links (Option -s), basierend auf 'pfad'. Neue Pfade dürfen nicht bereits existieren. (nur Unix) Es werden nur Verzeichniseinträge hergestellt, die auf die richtige Datei (mit Inhalt) verweisen. Symbolische Links sind winzige Spezialdateien, die auch auf Verzeichnisse und dateisystem- -übergreifend verweisen können. seek [:][+-][zahl] [handle [name]] (-Z-) Ändert die Position eines Datei-Zeigers oder zeigt eine Position an. Verwendet wird eine Dateinummer (handle) einer geöffneten Datei. Voreingestellt ist 0. Die Dateinummer sollte nicht mit einem Gerät verknüpft sein, da diese nicht 'seekable' sind. --- Verknüpfungen können mit globalen Umlenkungen hergestellt werden, die in etwa einer Dateiöffnung mittels 'open()' entsprechen. --- Wenn keine 'zahl' angegeben wird, erfolgt nur eine Positionsmeldung auf die Standard-Ausgabe oder aber in die Variable 'name'. Eine angegebene Variable 'name' wird stets auf (abschließende oder temporäre) Ist-Position gesetzt. --- Bei Angabe von '+' oder '-' wird relativ zur aktuellen Position bewegt. Der Doppelpunkt ':' symbolisiert das Dateiende als Referenzpunkt. Ohne ':+-' ist der Dateianfang der Bezugspunkt. Mit dem ':' allein kann übrigens die Dateigröße festgestellt werden: seek : <datei; seek : 0 p <datei 'handle' wird ggf. als zweites Argument erwartet, bei 'name' muß auch ein handle-Argument vorhanden sein. Exit ist FALSE bei fehlgeschlagenem seek. WARNUNG: Anstelle von pos=`seek + 1` oder pos=$(seek arg 1) unbedingt seek + 1 pos verwenden! (wegen: handle 1 und `...`) --- Wurde das Handle mit BlockMode geöffnet (s.o. Umlenkungen: B<...), so bedeutet beispielsweise '+ 1', daß der Filepointer nicht um ein Byte, sondern um einen Sektor (512 Byte) bewegt wurde. Auf diese Weise können bis 1 TeraByte erfaßt werden. Dabei: Lesen und Schreiben nur mit n=x*512 ! --- bish64 arbeitet direkt mit 64Bit breiten Zahlen. catv [quelle(n) ...] [=ziel] (-Z-) [[offset,]max,]objekt ... objekt=name|handle [:+-][offset][:+-] [:.]objekt[:.] /konstante /abc%x%255xyz .konstante , ,. ,r Dieses Kommando ist neben 'expr' und 'grep' mit ihren 'regular expressions', das mächtigste interne Kommando der bish! Seit dem Auftritt der Kommandos findccc und findcs gilt dies allerdings nicht mehr. catv ist als Bestandteil von bish64 64-bit-fähig. --- catv ist prinzipiell wie cat konzeptioniert, jedoch werden als Datenquellen Konstanten und/oder Variablen und/oder Dateinummern(=offene Datei) und als Datenziel Variablen oder Dateinummern akzeptiert! Zusätzlich können zu jeder Quelle und dem Ziel ein Offset und/oder eine MaxBytes-Anzahl angegeben werden! Noch weiter zusätzlich können die Offsets und Objekte mit mehreren Attributen versehen werden, die die Positionierungsausgangsbasis wählen, und anderes! Die Konstanten werden fast genau so wie die Argumente zum echo-Kommando bearbeitet: %c gibt es nicht, %n ist nur \n und nicht \r\n, aber %j erzeugt \r\n, und %123 können ein bis drei Dezimal-Digits sein. Bei einer Konstanten mit '.' anstatt '/' als Startzeichen werden Prozent-Sequenzen nicht umgewandelt --> raw input. --- catv schreibt die Inhalte aller Quellen in das Zielobjekt hinein. Dabei kann für jedes Objekt die maximale Anzahl Bytes, die gelesen bzw. geschrieben werden, gesetzt werden. Außerdem können Anfangspositionen gewählt werden, ab denen gelesen bzw. geschrieben werden soll. Das Ende des Objektinhalts wird durch einen Doppelpunkt (:) symbolisiert, der Anfang durch fehlende(!) Zeichen ":+-", und die aktuelle Position durch + oder -, wobei durch - gleichzeitig der Offset negativ gemacht wird. Variablen haben natürlich keine 'aktuelle Position'! --- Ein Punkt (.) bewirkt, daß zum Schluß zur am Anfang festgestellten Dateiposition zurückgestellt wird - der Dateizeiger bewegt sich nämlich aufgrund von Lesen oder Schreiben. In diesem Zusammenhang wird darauf hingewiesen, daß man ein und dieselbe Datei einmal zum Lesen und einmal zum Schreiben öffnen kann, wodurch man zwei voneinander unabhängige Dateizeiger erhält. --- Ein Doppelpunkt (:) am Objekt-Bezeichner führt zu einem Abschneiden des Inhalts des Zielobjektes hinter der letzten Schreibposition - es wird also gekürzt, falls die letzte Position vor dem Objektende liegt. Dies jedoch nicht bei gegebener Punkt-Anweisung! --- Die drei Steuerzeichen dürfen beliebig um die Offset-Zahl bzw. den Objektbezeichner herum gesetzt werden. Bei fehlender Offset-Zahl wird 0 angenommen. Die Steuer- und Startzeichen haben für die Shell keine Spezialbedeutung und dürfen nicht maskiert werden. --- Es können ein bis drei Argumentteile -durch Kommata getrennt- angegeben werden: offset,max,objekt Bei einem Teil wird dieser als Handle oder Name interpretiert, bei zwei Teilen gilt der erste Teil als Max-Zahl, und bei drei Teilen wird der erste Teil als Offset angesehen. Deshalb muß man nötigenfalls offset,,objekt setzen, um einen Offset aber keine Max-Zahl anzugeben. --- Als offset und max können direkt Digits (123..), $name als auch name ohne $ (Inhalt=123..) angegeben werden. --- Ein einziges Argument Komma "," oder ",." oder ",r" veranlaßt die Ausgabe der bei der letzten Aktivität gelesenen Byte-Anzahl: Auf die Standard-Ausgabe oder in $. oder $? . --- catv liest beliebig angebbare Teile aus Datenquellen und schreibt diese Datenkette in einen beliebigen Abschnitt eines Zielobjektes hinein. Ein Zielobjekt wird natürlich nötigenfalls vergrößert. Auch ein Offset über das Objektende hinaus ist möglich! Bei letzterem wird mit Nullen aufgefüllt, bei Dateien jedoch nur, wenn ab dem Offset mindestens ein Byte geschrieben wird. --- Falls eine Variable das Ziel ist, galt eine Grenze von maximal 32 KByte - dies jedoch nur, wenn diese Variable vergrößert werden mußte. Dieser Punkt wurde geändert: catv kann nun bis zum realen Speicherende ${:name} einer Variablen schreiben (s.u.). Eine 0 wird nur hinter das letzte geschriebene Byte geschrieben, wenn die Syntax 'name:' verwendet wird. Variableninhalte in weiten Grenzen können mit den Kommandos set und local hergestellt werden. Hinsichtlich der Speichergröße gilt das Limit von 32 KB für eine Vergrößerung nach wie vor. catv kann nun auch bis zum Ende der Speichergröße lesen. Voraussetzung ist, daß 'max' explizit angegeben wird, der 'offset' nicht negativ ist und 'max>0' ist. Siehe auch oben: 'Shell-Variablen und Speicher'. --- Man kann ein und dieselbe Variable mehrmals als Quelle und gleichzeitig als Ziel angeben! Mit catv können Variablen als binäre Speicherflächen benutzt werden! Bei der normalen Argumentbildung wird nämlich das Null-Zeichen als Argument-Ende verwendet. Spezielle Beispiele: Datei mit 50 Nullen: catv /%0 =49,,1 >datei Variable mit 50 Nullen: catv 0,0 =50,,V catv isnichda =50,,V catv 0,isda =50,,V Variable mit 48 Nullen und \r\n: catv =48,,V --- Voreingestellt ist: catv 0 =1 Bei mit Geräten verknüpften Handles wird nur ein positiver Offset ab aktueller Position berücksichtigt. Ein i-Attribut wird gelöscht, falls ungleich long-size Bytes in eine Variable geschrieben werden. Exit=FALSE bei Fehlern oder falls kein Byte gelesen werden konnte. (Siehe auch seek,conv,prints(K)) --- set a:.100000 echo ${:a} ${#a} 100000 100000 catv /aa =500,,a echo ${:a} ${#a} 100000 100000 catv /aa =500,,a: echo ${:a} ${#a} 100000 502 catv /aa =50000,,a: echo ${:a} ${#a} 100000 50002 catv /aa =99998,,a: echo ${:a} ${#a} 100000 100000 catv /aa =99999,,a: echo ${:a} ${#a} 100000 100000 catv /aa =99997,,a: echo ${:a} ${#a} 100000 99999 catv /aa =99990,,a echo ${:a} ${#a} 100000 100000 sumv [-bwllLu#v] [iname] [oname] (-Z-) Addiert die Werte aller gelesenen Bytes, Worte, Longs oder LongLongs und schreibt die Summe zur Standard-Ausgabe. Gelesen wird von der Standard-Eingabe (0) oder u1..u9. Voreingestellt ist '-b' für 'Bytes'. Wird ein Variablenname angegeben, gelangt der Summenwert dort hinein (oname). Bei zwei Variablennamen wird aus einer Variablen (iname) gelesen, statt per Filedescriptor. Optionsbuchstabe v selektiert iname bei nur einem angegebenen Variablennamen. Die Optionsbuchstaben ll entsprechen L. base [-bwl ll][u0] [iname] [+bwl ll][u1] [oname] (-Z-) BWL LL BWL LL basis basis[#] Dieses Kommando ist sehr mächtig und liest, schreibt, umwandelt Zahlen in vielen Darstellungsarten/Basen. Mit 'bwl ll' werden Bytes, Worte, Longs oder LongLongs gelesen bzw. geschrieben. Mit '(B)WL LL' werden Worte, Longs oder LongLongs gelesen bzw. geschrieben, wobei das höchstwertige Byte stets zuerst berücksichtigt wird - wie bei ascii-ZahlenStrings. Dies ist portabel! Beispielsweise werden auf Intel-Prozessoren bei 'base -l +L' alle Bytes in ihrer Reihenfolge genau umgedreht, weil Intel-Prozessoren das nieder= wertigste Byte auf der untersten Adresse haben. --- uDigit kann an die Optionen angehängt werden, um andere Handles als 0 und 1 zu verwenden. (Digit==0...9) Hinter den Optionen kann jeweils ein Variablenname angegeben werden, die dann als Quelle bzw. Ziel benutzt werden. --- Bei Angabe einer 'basis' werden Zahlen-Zeichenketten gelesen bzw. geschrieben. Als Basis sind gültig: 2...36,256 Bei Angabe eines '#' hinter der Ausgabebasis wird den Zeichenketten 2#,...36#,256# kennzeichnend vorangestellt. Bei Angabe einer Quellenbasis von '[-]0' oder '-#' wird erwartet, daß die Eingabe-Zeichenketten jeweils mit 2#,...,36#,256# gekennzeichnet sind. Standardbasis ist immer '10'. Bei Zeichenketten-Eingabe wird erwartet, daß die Ketten durch $IFS-Zeichen getrennt sind. Voreingestellt ist 'base -b +16'. (Bytes in Hex) Quelle und Ziel sind Standard-Eingabe und -Ausgabe. Exit ist FALSE bei Fehlern. alias [Name[=Wert] ...] alias -t [Name ...] Definiert für 'Wert' einen Alias-Namen 'Name'. 'Name=Wert' muß ein Einzelargument sein. Ohne Argument werden alle Alias-Definitionen gezeigt. Werden nur Namen angegeben, werden die Definitionen zu diesen Namen gezeigt (ohne Option -t). Option -t legt für die angegebenen Namen den dazugehörigen vollen Pfadnamen automatisch als Alias-Wert an. (Tracked Alias) (siehe set -h) Das alias-Kommando bewirkt einen reinen Textersatz. Shell-Interpretation findet nur bei der Definition eines Alias-Namens statt. Alias-Namen sind in Dateien und Funktionen standardmäßig lokal! - wenn nicht 'global' benutzt wird. Exit-Code ist ungleich null, falls ein angegebener Name kein Alias-Name ist (beim Lesen ohne '=Wert'). Beispiele: alias cp=COPY e='echo Fehler!' "q=exit $EXVAL" alias ..=exit l=DIR alias -t vi ==> vi=/usr/bin/vi 'Name' darf auch andere als die oben für Namen zugelassenen Zeichen enthalten. Und '=' als allererstes Zeichen eines alias-Argumentes wirkt dort noch nicht als Trennzeichen!: alias ==echo definiert folglich '=' als Alias-Namen für echo. Nach einem als Trenner bewerteten = werden weitere = nicht mehr als Trenner interpretiert. unalias name ... Entdefiniert zuvor definierte Alias-Namen. readonly [name ...] Markiert die angegebenen Namen als 'nur lesbar'. Sie können danach auch nicht per unset gelöscht werden. Auch Aliases und Funktionen können schreibgeschützt werden. Ohne Argument werden alle solchermaßen markierten Namen gezeigt. export [Name ...] Die angegebenen Variablen werden in die Umgebung (environment) exportiert (DOS-set-Kommando) und sind danach für alle Subprozesse erreichbar. Siehe Option -a. Ohne Argument werden alle bisher exportierten Variablen gezeigt. Wenn der Inhalt einer exportierten Variablen durch Zuweisung geändert wird, wird das Environment ebenfalls mitgeändert. Falls nicht alle Namen gefunden werden, ist der Exit FALSE. unexport [Name ...] (-Z-) Die angegebenen Variablen werden aus der Umgebung genommen und als normale Shell-Variablen deklariert. Ein Export wird also rückgängig gemacht. Exit wie bei 'export'. env Entspricht dem UNIX-Kommando env ohne Argumente. Entspricht dem DOS-Kommando set ohne Argumente. Listet alle Environment-Variablen: NAME=inhalt unset [-fse] Name ... (-Z-)(se) Die angegebenen Variablen werden gelöscht. Das gilt auch für einen ggf. exportierten Inhalt. Option -f lenkt auf Funktionsnamen. Mit den Optionen -s und -e kann die Löschung selektiv nur für Shell- oder exportierte Shell-Variablen erfolgen. Es kann jeweils nur eine der Optionen angegeben werden. Nur wenn alle angegebenen Namen -unter Einbeziehung der Optionen- gefunden werden, ist der Exit=0=TRUE. unsetenv Name ... (-Z-) Wie Kommando 'unset' (s.o.), jedoch es werden außer exportierten auch Variablen aus dem Environment gelöscht, die nicht von der Shell exportiert wurden, sondern beim Aufruf schon existierten. Nicht exportierte Variablen bleiben unberücksichtigt, ebenso die Syntax-Regeln für Namen. local [ Name[=[Wert]] ... ] (siehe auch set) (-Z-) local [ Name:cn Name:d.n ... ] (siehe auch set) (-Z-) local :[[+-]Ziffern] Name ... (siehe auch set) (-Z-) Definiert - und setzt optional - lokale Variablen. Nach Shell-Start und für jedes Shell-Script und jede Shell-Funktion, u.ähnl., steht hierfür eine exklusive Speicherfläche zur Verfügung. Die lokalen Namen verdecken gegebenenfalls gleichlautende globale Namen und lokale Namen tieferer Ebenen. Sie sind tatsächlich lokal, und nicht, wie in der UNIX-Korn-Shell, in weiteren, verkettet aufgerufenen Funktionen ebenfalls bekannt. Dateilokale Variablen sind in den Funktionen der jeweiligen Datei bekannt. (s.u.'static') Setzen (name=wert) solcher ist jedoch nicht erlaubt. inh:A70 Setzt Variable 'inh' mit 70 'A': "AAAAAAAAAAAAAA..." inh:65.70 Setzt Variable 'inh' mit 70 'A': "AAAAAAAAAAAAAA..." Das Kommando set macht dies für globale Variablen. --- Durch : var wird Länge ${#var} auf ${:var} gesetzt, welche das Maximum ist. Durch :1234 var wird Länge ${#var} auf 1234 gesetzt. Durch :+123 var wird Länge ${#var} um 123 erhöht. Durch :-123 var wird Länge ${#var} um 123 reduziert. Der Inhalt von Variablen wird hierbei nicht verändert. Zu kleine oder zu große Werte werden intern korrigiert. Durch inh:x70 kann ${#inh} immer wieder auf die alte Länge gesetzt werden, nach beispielsweise inh=reste; --- Die 'normalen' globalen Variablen sind natürlich auch nur im aktuellen Shell-Prozeß bekannt. Wenn man also 'bish script' anstelle von '. script' aufruft, ist dieser Vorgang isoliert und in dieser Hinsicht unabhängig. Darüber hinaus gültig sind nur Environment-Variablen, die im aktuellen und in allen Kind-Prozessen bekannt sind. --- Vordefinierte Variablen und Funktionsnamen sind stets global, und lokale Namen können nicht exportiert werden. local ohne Argument setzt ein eventuell gesetztes global-flag zurück (das lokal ist). Auf Namen, die die Shell benutzt, wie PWD, SECONDS, etc., sollte local nicht angewandt werden. static [ Name[=[Wert]] ... ] (-Z-) Definiert statische lokale Variablen, deren Inhalt zwischen Funktions- und Script(. script)-Aufrufen erhalten bleibt. Die Namen sind lokal. Gemäß folgender Reihenfolge wird nach definierten Variablen gesucht (unset,readonly,...): funktions-lokal nicht-statisch datei-lokal nicht-statisch funktions-lokal statisch datei-lokal statisch global Environment Das static-Kommando setzt statische Variablen nur, wenn sie noch nicht existieren. Dieses Kommando sollte nicht unnötig verwendet und nicht auf unnötig viele Namen angewandt werden, weil die Inhalte und die verlängerten(!) Namen den globalen Speicher belegen. Namensbildung: script_name@funktions_name@variablen_name Die ersten beiden Namen können fehlen. global [+] Sperrt den Zugriff auf lokale und -statische Namen, bis local ohne Argument aufgerufen wird. (-Z-) Option + wirkt wie 'local'. Die Sperre gilt nicht für die Kommandos local und static. global ist lokal innerhalb von Funktionen und Scripts. Eine Sperre ist nützlich bei eventueller Namensgleichheit. localset Wie set ohne Argumente. Zeigt lokale Inhalte. (-Z-) array [a [b]] NAME [ arg ... ] (-Z-) array Name=NAME index NAME$i=wert Die erste Variante dieses Kommando erzeugt ein Array, indem für jedes Element ein Name 'NAMEindex' gebildet und diese Variable dann gesetzt wird. Mit a und b ist ein Zahlenbereich für 'index' wählbar, wobei a auch größer als b sein darf. Standardwerte sind a=1 und b=a+anzahl_args-1. Elementnamen außerhalb a-b werden nicht erzeugt; überzählige args werden dann ignoriert. Überzählige Elementnamen werden leer ("") gesetzt. Wenn nur ein Array-NAME angegeben ist, wird dieses Array gelöscht. Innerhalb von Funktionen werden lokale Arrays erzeugt, falls 'global' nicht gesetzt ist. (s.u. set -A ...) Die zweite Variante liest den Elementinhalt NAMEindex und schreibt ihn in die Variable Name. Als index können eine dezimale Konstante oder ein Variablenname eingesetzt werden, wobei typeset-i-Namen ebenfalls berücksichtigt werden. Wenn NAMEindex undefiniert ist, wird Exit=1 gesetzt. Diese Art des Umgangs mit Arrays hat den Vorteil, daß sämtliche Argumente durch Shell-Interpretation entstanden sein können! Die dritte Variante ist für Einzelzuweisungen und hat mit diesem array-Kommando eigentlich nichts zu tun. shift [n] Die positionalen Parameter werden nach unten geschoben. $n+1 wird zu $n, usw. Voreinstellung von n ist 1. (siehe $#) ifdef [-seEf] Name ... (-Z-) Antwortet mit einem TRUE-Exit-Code (0), wenn alle angegebenen Variablen-Namen definiert wurden. Andernfalls ist der Exit-Code=1. Gesucht wird nach Shell- und Environment-Variablen. Ohne Argument werden alle undefinierten Variablennamen angezeigt, was sehr viele sein können. Die Optionen -seE sind implizit voreingestellt und bedeuten, daß nach Shell-, dann exportierten Shell- und zuletzt nach Umgebungs-Variablen gesucht wird. Option -f hat Vorrang und zielt auf Shell-Funktionen. ifset [-seEf] Name ... (-Z-) Wie ifdef, jedoch zusätzlich muß jede angegebene Variable mindestens ein Zeichen enthalten. ifenv Name ... (-Z-) Wie ifdef, jedoch wird nur die Umgebung untersucht, ohne die Namen-Syntax zu prüfen. (s.o. 'env') Entspricht fast 'ifdef -E'. conv -eriluLUnSd_D_f_F_h_H_t__T__c_o#O_#a#x#s_ Name ... (-Z-) Konvertiert den Inhalt der angegebenen Variablen: -l Zu Kleinbuchstaben (lower case) (-L) -u Zu Großbuchstaben (upper case) (-U) -dc Löscht angegebene Zeichen c. -Dc Löscht das erste vorkommende Zeichen c. -fc Löscht angegebene Zeichen c. Jedoch zwischen Gruppen von Zeichen ungleich c wird ein Zeichen c belassen: ///a///b/// ==> a/b -Fc Wie -fc, jedoch wird zusätzlich vorne ein Zeichen c belassen: ///a///b/// ==> /a/b ; /// ==> / ; / ==> / -hc Ersetzt alle Folgen cHH durch den Hex-Wert. -Hc Wie -hc; ersetzt nur das erste Vorkommnis. -tab Ersetzt alle Zeichen a durch b. -Tab Ersetzt das erste vorkommende Zeichen a durch b. -cc Liefert die Anzahl gefundener c in $. hinein. -a# Addiert den Wert # (+/-) zu allen Zeichen. -x# Der Inhalt wird mit dem Wert # per XOR verknüpft. -o# Angabe eines Offset # (+). -Oc# Stellt auf den Offset des #-ten Zeichens c. Liefert diesen Offset in $. hinein. -sc Füllt Zeichen c in die Variable(n). Länge ${#var}-Offs. -S Der Inhalt wird zeichenweise sortiert: Shakersort+ Die Anzahl Vertauschungen wird in $. gespeichert. Diese Anzahl ist für Analysezwecke bestimmt. Eine Zufalls-Zeichenkette[64] hat z.B. 677 Vertauschungen zur Folge, in 10 Runden. -r Der Variableninhalt wird zeichenweise umgedreht. -i Der Inhalt wird zeichenweise überschrieben mit den Ziffern 0|1 für gerade|ungerade. -n Der Inhalt wird nach der längsten aus gleichen Zeichen bestehenden Zeichenfolge durchsucht. "hfyweetwegfffehgegl" liefert 3 in $. hinein. Diese Option ist für Analysezwecke bestimmt. -e Es gilt nun -tba -Tba, Exchange/Austausch. Diese Option toggle-t sich. Wertangaben # werden dezimal vorausgesetzt. Die Optionen müssen als eine Zeichenkette -ooooooo angegeben werden. Readonly- und Environment-Variablen werden nicht verarbeitet! Auf jeden Variableninhalt werden alle Optionen in der angegebenen Reihenfolge angewendet. Jede Option kann beliebig oft angegeben werden. Falls nach einer Option ein oder zwei Zeichen (c,ab) stehen sollen, werden diese unbedingt gelesen, ggf. auch Null-Zeichen!: conv -t b vname Ersetzt alle \0-Bytes in der Variablen vname durch 'b', weil der Argumentspeicher folgendermaßen aussieht: "conv\000-t\000b\000vname\000" Die Optionen -etb vname sind hier alternativ (e): "conv\000-etb\000vname\000" Wird ein Zeichen c oder a entdeckt, wird jeweils(!) nach der Gleichheitsprüfung dessen Offset in $. gespeichert. Dies wird durch eine erfolgreiche Option O unterdrückt. Bei den Optionen O und c wird der Exit gesetzt: auf 1, falls das Zeichen nicht gefunden wurde, auf 2, falls es wegen zu großem Offset (o#) gar nicht gefunden werden konnte. Der Offset in $. ist -1 bei Nichtfinden. Bei den Optionen c,n,S wird der Exit auf 1 gesetzt, falls der Zähler==0 ist. Der Exit wird auf 3 gesetzt, falls die Funktionen S,r,n einen zu kurzen Inhalt entdeckten, sodaß sie nicht mit ihrer Arbeit beginnen konnten. Die Ressourcen $. und Exit ($?) sind nur einmal vorhanden, weshalb eine mehr als einmalige Verwendung pro Kommando unlogisch ist und berücksichtigt werden muß. Environment-Variablen werden nicht berücksichtigt. Siehe auch tr(K), set, local. Anstelle von conv -sc var ... kann mit den Kommandos set und local die Syntax var:c${#var} var:#.${#var} bei bereits bestehenden Variablen verwendet werden. cmpv [-i] name1 name2 (-Z-) Vergleicht Variableninhalte. Durch Option -i werden {a-z} = {A-Z} und alle weiteren Buchstaben des ISO8859-15 in diesem Sinne gleichgesetzt. Bei Ungleichheit ist der Exit 1 oder 2. Bei ungleicher Variablenlänge ist der Exit 4 oder 8 plus gegebenenfalls 1 oder 2. Bei undefinierter Variable ist der Exit=16. $. enthält den Offset derjenigen Zeichenstelle bis zu der geprüft werden konnte, also den der Ungleichstelle oder aber die (kürzere) Inhaltslänge. Der Exit ist nur bei Gleichheit beider Inhalte TRUE (0). Bei -i wird bei Ungleichheit stets 1 zum Exit addiert und $. wird nicht bedient. copy1v? quelle ziel1 ziel2 (-Z-) copy2v? quelle1 quelle2 ziel (-Z-) Kopieren in Abhängigkeit vom Exit-Code entweder den Inhalt einer Quell-Variable in eines von zwei Zielen, oder aber den Inhalt einer von zwei Quellen in die Zielvariable. Bei vorliegendem Exit=TRUE gilt ziel1 bzw. quelle1. Diese Kommandos selbst verändern nicht den Exit-Code. Die Kommandos vergrößern nötigenfalls eine Zielvariable oder legen eine solche neu an. xchgv name1 name2 (-Z-) Tauscht die Inhalte beider Variablen gegeneinander aus. Die Variablen müssen groß genug sein für den Inhalt der jeweils anderen Variable: ${#name} -> ${:name} Das Kommando legt keine temporäre Variable an, sondern tauscht byte-weise aus. Die Inhalte können somit beliebig groß sein, ohne daß ein Variablen-Management erforderlich ist. Das Kommando verändert nicht den Exit-Code. eval [Arg ...] Die Shell wertet die Argumente aus und führt das Ergebnis sich selbst als Eingabe (erneut) zu. Beispiel: A=aaaaa B='test $A %> AAA && echo $A' eval $B schreibt aaaaa auf den Bildschirm. Siehe Kommando 'run?'. trap Kommando-Arg signal ... Mit dem Kommando trap können unter UNIX den über dreißig vorhandenen Signalen (0...>30) Kommandos zugeordnet werden, die dann bei Eintritt des entsprechenden Signals ausgeführt werden. Unter DOS gibt es nur <Ctrl><C> als verwertbares Signal. Deshalb wurden drei Signalnummern folgendermaßen zugeordnet: 0 exit-Kommando 1 Bei Fehlermeldung 2 Bei <Ctrl><C> Das Kommando-Arg muß ein einzelnes Argument sein. Beispiel: trap '. ~\logout; echo $NKDO:Shell-ENDE' 0 Man beachte: bei dieser Maskierung ('') werden $NKDO und ~ erst bei der späteren Ausführung interpretiert. trap-Argumente werden als Funktionen abgespeichert. Achtung!: Trap-'Funktionen' können sich nicht selbst und auch nicht gegenseitig aufrufen. Beispielsweise per trap eine Funktion aufrufen, die das exit-Kommando aufruft und gleichzeitig die exit-Signalnummer 0 angeben. (Indirekte Rekursion!) Achtung! Unter DOS darf man nicht mit einer stets einwandfreien Funktion der <Ctrl><C>-Unterbrechung rechnen. Es ist wohl so, daß man eine laufende nichtinteraktive Shell dadurch abbrechen kann, jedoch die Aktionen, die per trap '...' 2 ausgeführt werden sollen, werden zumeist nur ausgeführt, wenn die Shell zum Unterbrechungszeitpunkt gerade auf eine Eingabe von der Standard-Eingabe wartet. Wenn man komplexere Aktionen per trap '...' 2 definiert, muß man mit regelmäßigen Problemen mit gleichzeitigem Dateizugriff (share) rechnen - trotz entsprechender Maßnahmen, und auch, wenn solche Dateizugriffe offensichtlich nicht vorliegen. exec [Kdo [Arg ...]] Das durch die Argumente angegebene Kommando wird anstelle der aktuellen Shell ausgeführt. Es gibt keine Rückkehr von einem fehlerfreien exec-Aufruf mit Argument(en). Ohne Argument ist exec ein Null-Kommando ohne Effekt. extern Kdo [Arg ...] (-Z-) Kdo wird als externes Kommando ausgeführt. Hilfreich bei Namensgleichheit. system Kdo [Arg ...] (-Z-) Die Argumente werden an die System-Funktion 'system(char *);' übergeben. (DOS: COMSPEC/command.com) Das ist auch -automatisch- der Fall, wenn ein Kommandoname nur aus zwei oder mehr Großbuchstaben A...Z besteht oder mit .bat oder .BAT erweitert ist. Laufwerkbezeichner (X:) gelten hier auch. Man beachte: DIR \verz /s/b/a:d > datei Umlenkung wird von bish durchgeführt. DIR "\verz /s/b/a:d > datei" Umlenkung wird von "system" durchgeführt. Der Exit-Code des angesprochenen Kommando-Interpreters wird übernommen: Exit=system(); fork Arg ... Entsprechend der Anzahl der Argumente werden ein oder mehr Hintergrund-Prozesse gestartet. Bei interaktiver Shell werden die PIDs zur Standardausgabe geschrieben. Der Parameter $! enthält den jeweils letzten PID. Für jedes Argument wird bish -c 'Arg' im Hintergrund gestartet. Das ermöglicht die Verwendbarkeit der bish-Syntax innerhalb von jedem 'Arg'. bg-kdo & Das abschließende Zeichen '&' startet das externe Kommando 'bg-kdo' als Hintergrund-Prozeß. bg-kdo & kdo ; kdo ... ist ebenfalls möglich, da '&' auch wie ';' wirkt. (Siehe set -U) wait [pid ...] Wartet auf die jeweilige Beendigung (exit) der Kind-Prozesse des Aufrufers. Ohne pid-Argumente wird auf alle CHILDs gewartet, mit pid-Argumenten auf die CHILDs mit den angegebenen PIDs. Bei interaktiver Shell werden die PIDs jeweils nach CHILD-exit zur Standardausgabe geschrieben. Der Exit-Kode ($?) wird nach jedem exit eines CHILDs mit dessen Exit-Kode gesetzt. kill [-signo] pid ... Beendet Prozesse, die den angegebenen PID haben. Standard-Signalnummer ist 15 (SIGTERM). [SIGINT==2, SIGKILL==9] Exit wird gesetzt. Bei TRUE-Exit (0) und interaktiver Shell wird der jeweilige PID zur Standardausgabe geschrieben. prompt (-Z-) Öffnet eine interaktive Shell mit Kommandozeile (und mit Prompt) innerhalb(!) des aktuellen Shell-Prozesses. Dies ist beispielsweise sinnvoll aus einem Skript heraus. Verlassen kann man diese Sitzung mit 'return'. autoexec.bish wird hier nicht abgearbeitet, und das Verzeichnis wird nicht auf das Startverzeichnis zurück= gestellt, sofern gewechselt wurde. set [ Name[=[Wert]] ... ] (siehe local) (-Z-) set [ Name:cn Name:d.n ... ] (siehe local) (-Z-) set :[[+-]Ziffern] Name ... (siehe local) (-Z-) set [{-+}afhnpuvxBCEINOPSUX9! - --] [ -/+A array_name [arg ...] ] - setzt Optionen, + setzt Optionen zurück. Die meisten dieser Optionen können auch beim Aufruf der Shell angegeben werden. echo $- zeigt die aktuell gesetzten Optionen. Ohne Argumente zeigt set sämtliche definierten Variablen und Shell-Funktionen. Spezial-Variablen, wie RANDOM und SECONDS, werden dabei nicht aktualisiert. Optionen: -A Erzeugt ein Array, beginnend mit Element 0, in Abhängigkeit von der arg-Anzahl. Das angegebene Array wird zuvor pauschal gelöscht, jedoch nicht bei +A anstelle von -A. Für lokale Arrays siehe oben 'array'. -a Alle folgenden Variablen werden bei Definition automatisch exportiert. -f Schaltet Dateinamen-Expansion ab. $] wird bei -f/+f auf 0 gesetzt. -h Jeder Kommandoname, zu dem erfolgreich ein Pfadname gefunden wurde, wird automatisch als entsprechendes Alias angelegt. Das gilt nicht, wenn der Kommandoname länger als 31 Zeichen ist. -n Liest Kommandos und überprüft auf Syntaxfehler, führt sie aber nicht aus. Wird von interaktiven Shells ignoriert. -p Ausführung von $HOME\autoexec.bish wird unterbunden. -u Zugriff auf undefinierte Variablen ist ein Fehler. -v Schreibt Eingabezeilen aus wie gelesen. -x Schreibt Kommandos mit Argumenten bei Ausführung aus. Per dieser Option ausgegebenen Zeilen wird "+ " vorangestellt. Die Standard-Fehlerausgabe wird benutzt. Es werden nur Zuweisungen und klassische Kommandos ausgegeben, nicht jedoch ((...)), while..., etc. -B Wählt den Backslash (\) als Maskierzeichen, oder das Prozentzeichen (%) per +B . Voreingestellt ist '%'. Der Backslash kann unter DOS sehr stören: echo "C:\\\\DOS\\\\XCOPY.exe : $FLG" -C Bei einigen Fehlern wird fortgefahren. (Continue) Funktion nur bei nichtinteraktiver Shell, innerhalb von Dateien und Funktionen und während des Prompt- -Kommandos. Diese Option kann bei unbedachter Verwendung gefährlich werden! Man sollte erst testen und dann gezielt Kommando(s) mit set -C; ...; set +C umrahmen. Ein besserer Weg ist, potentielle Fehler vorher festzustellen, um dann individuelle Maßnahmen und Fehlermeldungen vorzunehmen. -E Aktiviert den Kommandozeilen-Editor. -I Die Shell kann von der Tastatur normalerweise weise durch Eingabe von ^D oder ^Z beendet werden. Option -I verhindert dies. (ignoreeof) -N Verhindert (unabsichtliche) Veränderung bestehender Dateiinhalte durch Umlenkung >Datei . -O Gestattet, daß das Lesen von $. seinen Index inkrementiert, also auf seinen nächsten Wert stellt. (Siehe insbesondere das expr-Kommando.) -P Ruft eine permanente interaktive Shell auf, die nicht per 'exit' oder EOF (^D), sondern nur per exit -P verlassen werden kann. (s.o.: exit) -S Schaltet den internen ANSI-Treiber ein. Voreinstellung ist EIN. Nur bei Win32 (bish32.exe). Siehe ansi®. -U Für Pipelines (|) werden pipe()-Calls verwendet. Bis auf das letzte werden alle Kommandos in den Hintergrund gesetzt (bg-Kommandos). Nur das letzte Kommando kann ein bish-Buildin sein. echo aBc | tr B Q | tr Q Y /bin/echo, /usr/bin/tr, tr-Buildin. echo aBc | tr B Q | tr Q Y & /bin/echo, /usr/bin/tr, /usr/bin/tr Es kann natürlich bish -p -c '...; catv Z' | ... verwendet werden, denn bish ist ein externes Kommando. Expandierte Kommandozeilen können meist nur 32K lang sein: echo /usr/*/*/* | wc funktioniert nicht mit echten U-Pipes in der bish. (Siehe bg-kdo &) -X Die Kommandos 'grep' und 'expr' verwenden hierdurch XRA (eXtra erweiterte Reguläre Ausdrücke). Die Kommandos besitzen eigene Optionen -XB bzw. xb mit Vorrang vor der bish-Option. (Siehe xregexp®) -XRE Siehe xregexp®. -9 CloseOnExec-Flag bei fd>9 statt fd>2. -o sid setsid() close Schließt Handles 1,2,0 close# Schließt Handle # (Auch mehrstellig) -! Bewirkt ein Ignorieren von SIGTERM. - Schaltet -v und -x ab und stoppt die Suche nach -- weiteren angegebenen Optionen. Beim Aufruf der Shell können so Dateiargumente angegeben werden, die mit - anfangen. -nvx Diese Optionen wurden nur als Randfunktionen implementiert und weisen manchmal ein vielleicht unerwartetes Verhalten auf. Siehe auch 'conv -sc'. typeset [ -+i[4|8]ISfF{s[obase]|obase} ] [Name[=wert]]... Dieses Kommando ist in Verbindung mit arithmetischen Ausdrücken besonders interessant. Option -f markiert Gleitkomma-Variablen als binär-float. Option -i markiert Variablen als binär-integer. Sie werden solchermaßen besetzt binär gespeichert und nicht als dezimale ascii-Zeichenkette. Optional kann -i4 oder -i8 angegeben werden, was die Breite in Byte festlegt. Ohne die Breitenangabe wird diejenige Breite verwendet, die durch Option -S oder -I (s.u.) angezeigt wird. In Verbindung damit kann eine Ausgabebasis festgelegt werden, die bei Substitution ($name) und 'set' zum Tragen kommt. Bei Wertzuweisung kann eine (Eingabe-)Basis (base#) angegeben werden, wie weiter oben erklärt, die nur benutzt wird, um die 'obase' zu setzen, wenn 'obase' nicht gegeben oder Null ist. Mit einer Eingabebasis können Variablen NICHT belegt werden, diese dient nur als Wegweiser zum Zeitpunkt der Konstantenumwandlung! --- Der Sinn von if-Attributierung ist der Wegfall von unablässigen Konvertierungen zwischen lesbarer ascii-Zeichenkette und binär. if-Variablen können auch außerhalb von arithmetischen Ausdrücken gesetzt und einander zugewiesen werden; falls eine Darstellung anders als dezimal gewählt wird, muß aber diese Basis explizit angeben werden: Name=base#const Optionen +i oder +f entfernen if-Attribute. Wenn nur obase gegeben ist, wird nur diese neu gesetzt, falls es sich um eine i-Variable handelt. Ohne Namenargumente werden alle if-Variablen gelistet. Namen werden in Dateien und Funktionen standardmäßig lokal angelegt! - wenn nicht 'global' benutzt wird. --- Option -s[obase] setzt die Basis für die Substitution eines arithmetischen Ausdrucks $((...)). (-Z-) Dies kann auch ausdruck-lokal vorgenommen werden. (s.o.) Ohne 'obase' wird die aktuelle Basis gezeigt. Die Basis von f-Float ist nicht einstellbar. --- Option -S oder -I zeigt die Länge eines i-Integer in #Byte. Dies gilt nicht für -i4 und -i8. (-Z-) Option -F zeigt die Länge eines f-Float in #Byte. (-Z-) Diese Längen sind wichtig u.a. zum Anlegen binärer Arrays. ${#name} zeigt hier nicht die wirkliche Länge, sondern die Länge als konvertierte Zeichenkette. --- Die Interoperabilität zwischen Objekten mit binärem Inhalt und ungleichem Typ ist weitgehend gegeben. Ändernd können Zuweisungen sein, besonders zwischen Integer und Float. Es können leicht Versuche mit Kontrolle danach vorgenommen werden: typeset a=123.0:f16 b=7637.0:f16 c=0.0:f16 i8=0#567:i8 i4=0#89:i4 --- Weitere Optionen, die die Original-ksh hat, sind hier unnötig, weil sie von mehreren anderen Kommandos erledigt werden können. type Name ... whence [-pev-] [vname] Name ... Für jeden Namen wird angezeigt, wie er interpretiert würde bei Verwendung als Kommandoname oder Name. Gegebenenfalls wird ein Pfadname gebildet. Nur das erste Argument wird auf Optionen geprüft. Option -- hat nur Isolationswirkung. Option -v verlangt 'vname' als Variablenname, die mit einem Pfadnamen (-p) oder 'Name' gesetzt wird. Option -v setzt den Exit==FALSE bei Mißerfolg. Bei -v und mehreren 'Namen' würde 'vname' immer wieder überschrieben. Option -p schaltet die Nur-Pfadsuche ein. Option -e unterdrückt die Ausgabe und setzt stattdessen den Exit-Code folgendermaßen: (-Z-) nicht_alle_angegebenen_namen_gefunden Exit=0 Internes Kommando oder Schlüsselwort Exit=1 Alias-Name Exit=2 Internes Kommando Exit=3 Shell-Funktion Exit=4 Shell-Variable Exit=5 Environment-Variable Exit=6 Kommando für 'system()' Exit=7 -p: Batch-Datei Exit=8 Shell-Script für: 'shell-pfad' Exit=9 Externes Kommando Exit=10 Bei mehr als einem Namen ist der Exit dem letzten zugeordnet. Achtung! Ein 'Fehler' ist hier ausnahmsweise Exit=0. sleep [-m] [n] (-Z-) Bewirkt einen Stop mit einer Länge von n Sekunden. Voreingestellt ist n=1. Option -m stellt auf n Millisekunden um, wobei die Auflösung in der Regel 10 ms beträgt. Hier gibt es keine Voreinstellung. times Schreibt die bisher aufgelaufene Zeitdauer [sec] seit Start der Shell aus. systime [-t] [name|wert] (-Z-) Setzt oder ermittelt die Systemzeit (Datum+Uhrzeit). Ein angegebener Zahlenwert setzt die Systemzeit. Andernfalls gelangt die Systemzeit in eine Variable, falls ein Name angegeben wurde, oder wird zur Standardausgabe geschrieben. Der Zeitwert ist eine dezimale Zahl, die die Anzahl Sekunden seit 1.1.1970 00:00:00 darstellt: 912345678 Option -t schaltet ein aufgeschlüsseltes Wertformat ein: [CC]YYMMDDhhmm[.ss] Linear vom Jahrhundert bis zum Sekundenwert. Dieses Format wird neuerdings von vielen Kommandos einheitlich beherrscht. Option -t ist entbehrlich, falls der Punkt (.) im Wert enthalten ist. Mindestens Jahrhundert und Sekunden sind optional. Bei diesem Kommando reicht sogar ".", wodurch die Sekunden zu 00 und die anderen Werte aus der aktuellen Zeit ergänzt werden. Siehe auch: tz ctime fstat tz [{[-]stunden|sekunden}|set] (-Z-) Setzt einen Zeitzonenwert (timezone), die Differenz zwischen GMT-Zeit (GreenwichMeanTime) und lokaler Zeit. Für MEZ(CET)-Zeit beträgt dieser Wert -1 Stunde bzw. -3600 Sekunden. Ein angegebener Wert, der nicht ohne Rest durch 60 teilbar ist, wird als Stundenwert aufgefaßt, andernfalls als Sekundenwert interpretiert. -- Option 'set' ruft tzset() [$TZ] auf und setzt dann in Abhängigkeit von 'daylight' entweder mit 'alttime' oder mit 'timezone'. -- Ohne Argument wird die aktuelle Einstellung -stets in Sekunden- zur Standardausgabe geschrieben. Voreingestellt ist 0. Dieses Kommando beeinflußt die Kommandos systime und fstat (a-,m-,ctime), und ist unter Unix immer von Bedeutung. Während der Sommerzeit kann man -2 setzen. ctime [-t] name... wert... | wert... name... (-Z-) Konvertiert die beiden Zeitwertformate, die bei den Kommandos fstat und systime verwendet werden. Dieses Kommando bemerkt fast vollautomatisch anhand der Argumentart und -häufigkeit, was wie umgewandelt werden soll. Alles außer 88888888 --> 88888888 ist möglich. Ohne Namenangabe wird zur Standardausgabe geschrieben. Ein Name '-' gilt zwar als solcher, jedoch wird zum Schluß keine Variablenzuweisung vorgenommen. Dies ist ein Auslassungsname, der nur positioniert. Ganz ohne 'echten' Namen wird immer zur StdAusgabe geschrieben. Mehr als ein Name erzeugt stets das -t-Format. Sonderfall: Bei Angabe von .ss und trotzdem Option -t ist das Ausgabeformat ebenfalls vom -t-Typ - auch bei nur einem(!) Namen. Beispiele: ctime 888888888 ctime name 888888888 ctime 888888888 name ctime name - name 888888888 ctime name [CC]YYMMDDhhmm[.ss] ctime name [CC] YY MM DD hh mm [.ss] ctime name [CC]YY MM DD hh mm [.ss] ctime -t name [CC]YYMMDDhhmm ctime -t YYMMDDhhmm.ss ctime -t - - YYMMDDhhmm.ss ctime ... Das Beste ist, man probiert das in der Kommandozeile mit aktiviertem Kommandozeilen-Editor mal aus. Dieses Kommando wandelt NUR um, es werden keinerlei Zeiten GESETZT. fstat [-|+FitfplugJNsamcbnhTv] [name...|wert...] file...|handle... (-Z-) Dieses Kommando liefert sämtliche Daten, die im Dateisystem für eine Datei vorhanden sind. Alle Daten, die in diesem Zusammenhang überhaupt gesetzt werden können, kann dies Kommando auch setzen. --- Die Optionen werden nachfolgend mehrmals erklärt: -F Dateisystem-Nummer (Gerät/device) -i Inode-Nummer (DOS-) -t Datei-Typ (Dual-Zahl) -f Datei-Flags (Dual-Zahl) -p Zugriffs-Erlaubnis (permission/mode) (Oktal-Zahl) -l Anzahl Links (link count) -u Besitzer-ID (user-id/uid) (DOS-) -g Gruppen -ID (grp -id/gid) (DOS-) -J Major-Nummer (Gerät/device) -N Minor-Nummer (Gerät/device) -s Datei-Größe (size: 32/64Bit) -a Zugriffs-Zeit (access) (DOS-) -m Änderungs-Zeit (modification) -c Status-Änderung (creation) (DOS-) -b Kreations-Zeit (inode-creation) (DOS-) -n Datei-Name -h Zeigt an, daß Nummern (handle/file_descriptor) geöffneter Dateien angegeben werden, anstelle von Dateinamen. Beim Setzen (+) können Nummern größer als 9 nicht verwendet werden. -T Aufgeschlüsseltes Zeitformat eingeschaltet: CCYYMMDDhhmm.ss statt 912345678 (s. systime) Von links her weggelassene Angaben werden aus der bisherigen Dateizeit ergänzt. -v Variablen sollen gesetzt werden, anstelle eines Schreibens zur Standardausgabe. Die Anzahl muß mit den Optionen korrespondieren. Die Optionen müssen als ein einzelnes Argument angegeben werden. Die Optionen -h,-T,-v dienen der Steuerung dieses Kommandos, die anderen bezeichnen Dateiparameter. Ein vorangestelltes Pluszeichen (+) anstelle des üblichen Minus (-) zeigt an, daß Dateiparameter gesetzt werden sollen. Gesetzt werden können: +fpsam wobei zwischen +a und +m kein Unterschied besteht. Es kann tatsächlich die Dateigröße (+s) gesetzt werden; logischerweise verliert man bei Verkleinerung Daten. Achtung: Die Reihenfolge der Dateiparameter-Optionen wird bei der Ausgabe und beim Setzen von Variablen berücksichtigt! --- Falls keine Parameter-Option -F...-n gegeben wurde, werden automatisch die folgenden gesetzt: -tfpsmn DOS: Fit f p lugJN s amc n hTv typ flags mode size time name 1111 111 777 0000000000 9999999999 nnnnnnnn file arch dir hidden cdev system label UNIX: Fit f p lugJN s amc n hTv typ flags mode size time name 1111 111 777 0000000000 9999999999 nnnnnnnn file suid dir sgid/lock cdev sticky fifo bdev bdev (symlink) (symlink) Symbolische Links: siehe test-Kommando Dieses Kommando ist nicht dafür da, um schöne, formatierte Listen zu erzeugen, sondern um Daten komfortabel verarbeiten zu können - ähnlich wie das list-Kommando. --- Falls Dual-/Oktal-Zahlen in Variablen gespeichert werden, kann man nur quasi-direkt damit Berechnungen vornehmen: let "typ=2#$typ, flags=2#$flags, mode=8#$mode" Hier wurde umgeformt; erst hiernach kann man in allen Syntaxformen rechnen: (( typ2=typ&2#11, mode&=~8#200 )) (( typ2=typ&3 , mode&=~128 )) (( typ2=typ&10#3, mode&=~10#128)) Der Arithmetik/Logik-Modul erwartet nämlich dezimale Zeichenketten in den Variablen. Auch Compiler können verschiedene Zahlenbasen nur an Konstanten erkennen (789 0567 0xfc8a). --- Beispiele: fstat (zeigt Aufrufzeile) fstat aaa abc ccc *.txt fstat -T aaa abc ccc *.txt fstat -psmnT nul aux prn con fstat -Th 0 1 2 10 11 fstat -smTv agröße azeit a fstat -msTv azeit agröße a fstat +mT $azeit bbb ccc fstat -mT bbb ccc fstat +p 400 bbb ccc (DOS-Schreibschutz) fstat +fp 111 400 bbb ccc (DOS-attrib AHSR) Am besten probiert man das mal in der Kommandozeile aus, bei aktiviertem KdoZeilen-Editor (bish -E/set -E). Warnung: Aufpassen bei +s ! Unter DOS kann der Zeitstempel von Verzeichnissen nicht geändert werden. Indirekt geht das, indem man mittels systime die Systemzeit vorübergehend ändert und währenddessen ein Verzeichnis erzeugt. --- Exit==FALSE falls Dateien nicht geöffnet werden konnten beim Lesebetrieb. Alle anderen Fehler werden 'laut' quittiert. (siehe tz-Kommando) fsize datei ... (-Z-) Dieses Kommando ist ein Auslaufmodell ! ! ! Entspricht: fstat -s datei... fmode datei ... (-Z-) Dieses Kommando ist ein Auslaufmodell ! ! ! Entspricht: fstat -p datei... mtime datei ... (-Z-) Dieses Kommando ist ein Auslaufmodell ! ! ! Entspricht: fstat -m datei... stime time datei ... (-Z-) Dieses Kommando ist ein Auslaufmodell ! ! ! Entspricht: fstat +m time datei... mktemp [name [dir]] (-Z-) Erzeugt eine temporäre Datei. Die Datei hat danach die Größe 0. Eine angegebene Variable wird mit dem Namen dieser Datei gesetzt, andernfalls wird der Dateiname zur Standardausgabe geschrieben. Ohne Angabe eines Verzeichnisses wird das TEMP-/BISHTEMP-Verzeichnis verwendet. Der generierte Pfadname, mit dem die Datei erzeugt wird, ist garantiert konfliktfrei. Die Datei wird nach Erzeugung sofort wieder geschlossen. dirname Pfadname (-Z-) Die letzte Pfadnamenkomponente wird entfernt und der verbleibende Vorderteil wird zur Standard-Ausgabe geschrieben. Der Basisname wird auch entfernt, wenn dieser ein Directory repräsentiert. Exit-Code ist 1, wenn Pfadname leer oder nicht angegeben ist. basename Pfadname (-Z-) Die letzte Pfadnamenkomponente wird selektiert und zur Standard-Ausgabe geschrieben. Exit-Code ist 1, wenn Pfadname leer oder nicht angegeben ist. fullname [-v-] [vname] Name ... (-Z-) Jeder 'Name' wird nötigenfalls mit dem Namen des aktuellen Verzeichnisses ergänzt, so daß stets ein voller Pfadname entsteht. Der erzeugte Pfad wird zur Standardausgabe geschrieben, falls Option -v nicht angegeben wurde. Nur das erste Argument wird auf Optionen geprüft. Option -- hat nur Isolationswirkung. Option -v verlangt 'vname' als Variablenname, die mit dem vollen Pfad gesetzt wird. Bei -v machen mehrere 'Namen' keinen rechten Sinn, da 'vname' immer wieder überschrieben würde. Dies ist ein reines Zeichenketten-Kommando, das den erzeugten Namen nicht auf Existenz prüft! umask [ddd] Setzt oder zeigt die Bit-Löschmaske für die Dateierzeugungsmechanismen. Gesetzt wird bei Angabe einer Zahl in Oktalnotation. Die Bits, die hier angegeben werden, löschen gegebenenfalls im Ursprungsmodus gesetzte Bits. Der (interne) Ursprungsmodus der bish ist 666 / 600(DOS), und 777 / - beim Kommando mkdirs. umask ist voreingestellt: 077 / 177(DOS) wodurch '600' resultiert für Dateierzeugungen und '700' für Verzeichniserzeugungen. Aus '377' resultierte '400' für schreibgeschützte Dateien. Bedeutung: rwx rwx rwx = 9 Bits Eigner Gruppe Alle Unter DOS sind nur die beiden linken rw-Bits bedeutsam; es gibt nur die Modi '600' und '400'. Unter DOS wird Schreibschutz (0400) bei Dateierzeugung durch dieses Kommando ignoriert: siehe fstat sane [q] Stellt die ursprünglichen Verknüpfungen der (-Z-) Datei-Handles wieder her, wobei Handles auch geschlossen werden. sane sollte nur auf Grundebene der Shell aufgerufen werden, also beispielsweise nicht innerhalb einer Pipeline. Option q schaltet die Informationsausgabe ab. ver [oswntil] Zeigt die Version des Shell-Programms bish. (-Z-) o System s System w Ware n Versionsnummer (hat Vorrang) t Zeit der Kompilierung i Informationen l Limits autor Zeigt genaue Anschrift des bish-Autors. (-Z-) hash Reservierter Kommandoname. mkpath Reservierter Kommandoname. reset Reservierter Kommandoname. function Reserviertes Schlüsselwort. Prompt Eine interaktive Shell gibt vor jeder Eingabe einen Prompt-String aus. Siehe oben: Shell-Variablen PS1, PS2. Das sekundäre Prompt wird ausgegeben, wenn man <Enter> betätigt hat, ein Kommando jedoch noch nicht vollständig ist. Besonders häufig kommt es vor, daß man Zeilenvorschübe als Bestandteil eines Kommando-Argumentes eingeben will: # ABC="aaaaaa > bbbbbb > cccccc > " # _ Oder lange Eingaben: # kommando arg arg arg arg > datei && > kommando arg arg # _ # echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa% > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > datei # _ Schleifen, if-elif-else-fi und case-esac sind bei solcher Zeilen= verteilung problematisch, da dies nicht implementiert ist. Im Kommandozeilen-Editor ist diese Eingabeart jedoch unsinnig. Standardwerte für PS1 und PS2 sind "# " und "> ". Der Inhalt wird interpretiert und ggf. expandiert. Nur die Zeichen $ % und ! haben Spezialbedeutung, wobei für ! eine fortlaufende Kommandonummer eingesetzt wird. Beispiel: PS1='!:$PWD: ' --- Neuere Versionen der bish können in den Variablen PS1 und PS2 die komplette Syntax benutzen! Die Inhalte werden quasi wie eine Shell-Funktion gelesen. Die Länge für die Prompts ist allerdings begrenzt, und zwar auf <512 Bytes und 55 Kommando-Argumente. Anstelle von '!' muß man hier '$:' angeben. Die Voreinstellungen sind: PS1=' print -nu2 "$:# "' PS2=' print -nu2 "$:> "' Das set-Kommando zeigt u.a. diese Inhalte. In 'autoexec.bish' bzw. '.bishrc' können abweichende Einstellungen vorgenommen werden, z.B.: PS1='print -nu2 "%e[s%r%e[53C%e[40;36m"; prints su2-26- $PWD print -nu2 "%e[u%e[40;37m$:%e[1m#%e[0m "' Oder man definiert eine Funktion, und dann: PS1=fname (Siehe auch Kommando 'prompt'.) Eingabe von der Tastatur Die Shell liest von der Standard-Eingabe und überschreibt keine eventuellen Tastenprogrammierungen. Das Verhalten ist genau so, wie in der Kommandozeile außerhalb der bish! Das gilt sehr weitgehend auch bei aktiviertem Kommandozeilen-Editor. Aufruf der bish Ohne Argument ist bish interaktiv. Nach Aufruf wird $HOME\autoexec.bish ausgeführt. Falls HOME undefiniert ist, wird \autoexec.bish probiert. (s. Option -p) Die Ausführung von autoexec.bish entspricht dem Punkt-Kommando '. autoexec.bish'. Darin vorgenommene Definitionen bleiben also erhalten. Wenn Argumente vorhanden sind, die keine Optionen (-o) sind, werden diese als Shell-Script mit zugehörigen Argumenten aufgefaßt und ausgeführt; die Shell ist dann nicht interaktiv. Das gilt nicht, wenn eine der Optionen -isct gegeben ist. In diesen Fällen werden die Argumente zu positionalen Parametern. Das Shell-Script wird gemäß $PATH gesucht, und nach Abarbeitung von 'autoexec.bish' wird geprüft, ob darin PATH geändert wurde. Falls ja, wird nochmals der Pfad gesucht. -c String Den Inhalt von String liest die Shell als Eingabe. Für String gilt ein Längenlimit von 2 KB. Es gibt hier eine Trennzeichen-Problematik bezüglich "string" und sehr eigentümlichen Verhaltens der in DOS-Entwicklungsumgebungen anzutreffenden Library-Funktionen. (siehe bish(I)) (Nur, wenn man innerhalb bish bish -c ... aufruft.) -s Mit dieser Option oder ohne Rest-Argumente liest die Shell von der Standard-Eingabe. Rest-Argumente bilden positionale Parameter. Shell-Ausgabe erfolgt auf die Standard-Fehler= ausgabe. -i Die Shell ist interaktiv per dieser Option oder wenn Shell-Ein- und -Ausgabe mit einem Terminal verknüpft sind. -t Exit nach Ausführung eines einzelnen Kommandos. Sinnvoll bei Aufruf innerhalb eines C-Programms. Weitere Optionen: siehe set-Kommando. Signale/Interrupt(Ctrl-C)/Fehlerbehandlung bish fängt Signale ab. Eine nichtinteraktive Shell wird in diesen Fällen beendet. Eine interaktive Shell wird in Grundstellung gebracht und es wird ein Prompt ausgegeben. Gleiches gilt bei Fehlermeldungen. bish hat annähernd 100 Fehlermeldungen; die zugehörige Datei-Zeilennummer [n] wird ggf. ausgegeben. Bei Fehlern innerhalb von Funktionen wird der Funktionsname() und die betreffende Zeilennummer des Funktionskörpers ausgegeben. (auch bei trap- und eval-Expansionen.) Die Zeilennummer kann mitunter um 1 zu hoch sein, weil manche Fehler erst nach einer abgeschlossenen Zeile erkannt werden. Mittels 'set -C; ...; set +C;' (siehe oben) kann man einige Fehler auf eine Fehlermeldung reduzieren. Dies ist für Fälle gedacht, bei denen man einen nachfolgenden Shell-Exit nicht haben will. Allerdings kann ignorieren von Fehlern durchaus im weiteren Verlauf einer Abarbeitung großen Schaden anrichten! Denn in der Regel soll ein Kommando -das dann beispielsweise nicht gefunden werden kann- Arbeiten verrichten, die nachfolgend von Bedeutung sind! KOMMANDOZEILEN-EDITOR Wird durch set -E bzw. set +E ein- bzw. ausgeschaltet. Zur Verwendung muß die Shell natürlich interaktiv sein. Außerdem muß ein ANSI-Treiber für Escape-Sequenzen geladen sein! Editier-Tasten: <Esc> Eingabezeile löschen. <Backspace> Cursor nach links und Zeichen ab Cursor löschen. <Delete> Zeichen löschen. Plus <Backspace>-Funktion. <BackTab> Zeichen löschen. <Left> Cursor nach links. <Right> Cursor nach rechts. <Home> Cursor zum Zeilenanfang. <End> Cursor zum Zeilenende. <Insert> Wechselt vom Überschreib- zum Einfügemodus, und umgekehrt. Der Überschreibmodus wird durch ein helleres aktuelles Zeichen angezeigt. <Ctrl+V> Nach Betätigung gilt ein Steuerzeichen als normales Textzeichen. Ebenso können Zeichen per Dezimalwert eingegeben werden. (s.u.) <Insert> hier wechselt die optische Anzeige des Überschreibmodus zum Einfügemodus - und zurück. History-Tasten: <Up> Holt ehemalige Eingabezeile(n) zurück. <Down> Geht wieder in Richtung aktuelle Zeile. <PgUp> Wie <Up>, jedoch mehrere Zeilen auf einmal. <PgDown> Wie <Down>, jedoch mehrere Zeilen auf einmal. <Enter> Aktuelle Zeile wird abgespeichert und der Shell als Input übergeben. Cursor-Position ist bei <Enter> unerheblich. History-Funktionen: ,x... Es wird in der Liste der ehemaligen Eingabezeilen nach einer Zeile gesucht, die mit x... beginnt. Gesucht wird in Richtung der ältesten Zeile. ?x... Es wird eine Zeile gesucht, die irgendwo x... enthält. Es werden hier die Ersatzzeichen (?*[) wie bei der Dateinamen-Expansion verarbeitet. Diese Zeichen (,?) haben nur als erstes Zeichen Spezialbedeutung. Voranstellung eines Trennzeichens hebt die Spezialbedeutung auf. Ebenso, wenn sie ganz allein stehen. Steuer-Tasten: <Ctrl+C> Interrupt. <Ctrl+Z> <Ctrl+D> Beendet die Shell, wenn nicht Option -I gesetzt ist. Wenn bei Aufnahmeabsicht einer neuen Zeile in der History-Liste eine identische Zeile entdeckt wird, rückt diese Zeile an die aktuelle Position. Die neue Zeile wird dann gar nicht erst aufgenommen. Die Cursor-Position bei horizontaler Bewegung wird abgespeichert und bei vertikaler Bewegung wird Bezug darauf genommen. Durch <End> wird diese Bezugnahme (temporär) unterbunden. Es können die Zeichen ^A bis ^Z (1-26) eingegeben werden. Für Esc, ^C, ^D und andere Steuerzeichen muß zuvor ^V gedrückt werden. Sie werden teilweise durch @ dargestellt. Ein TAB wird per ^ gekennzeichnet. Ebenfalls können nach ^V ein bis drei Digits eingegeben werden, um Zeichen mittels ihrem Dezimalwert zu schreiben. Diese Sequenz wird beendet mit Eingabe des dritten Digits oder sobald ein Nicht-Digit auftritt. Die History-Liste faßt maximal 128 Zeilen, wobei alle darüber hinaus die jeweils älteste überschreiben. (Ringspeicher) Eine Zeile kann maximal 126 Zeichen lang sein. Wenn allerdings über den rechten Bildschirmrand hinaus geschrieben wird, ist die Editierbarkeit eingeschränkt. Die Eingabezeilen werden in der Datei $HOME\history.bish abgespeichert. Der Dateiinhalt bleibt erhalten und wächst von Sitzung zu Sitzung. Eine Sitzung wird nur explizit per 'set +E' oder Beenden der Shell gelöscht, jedoch nicht durch Unterbrechungen (Fehler,Ctrl+C). Während der Eingabe in der Kommandozeile des Zeilen-Editors wird ein Abbruch per <Ctrl+C> nicht vom System generiert, sondern vom Editor selbst. Dies deshalb, weil der Editor nicht von der Standard-Eingabe liest. Der Original-Break funktioniert hier nicht. HINWEISE Diese Manual-Datei ist in der Regel die aktuellste aller Manuals zur bish. Für die meisten gilt: Copyright © 1995-1997 Vieles -z.B. Limits- bezieht sich auf die DOS16-Version, gilt aber nicht für unix-bish, bish32 oder bish64. Auch manche Beispiel-Scripts nehmen nicht Bezug zu neueren Leistungsmerkmalen der bish. Es erfolgt eine automatische Pfadnamen-Korrektur bezüglich der trennenden Schrägstriche '/' <---> '\'. Man kann also auch mit der DOS-Version z.B. /aaa/bbb/ccc angeben. Dies ist jedoch beim Aufruf externer Kommandos, bei Verwendung von 'system' und 'extern' und bei impliziter Verwendung von 'system' (z.B. DIR ...), alle Argumente betreffend, nicht möglich! Unter Unix ist diese Umwandlung nicht aktiv, da dort sämtliche Zeichen außer '\0', also 1...255, in Pfadnamen vorkommen dürfen. Jedes aufrufende Programm -beispielsweise command.com, das die bish aufruft- hat eine Umgebung (Environment), die aus Variablennamen und deren Inhalten besteht. Diese Variablen sind im aufgerufenen Programm zugänglich, da die Adressen dorthinein kopiert wurden. Man kann dies als Prozeßkommunikation bezeichnen, die jedoch nur in einer Richtung funktioniert, da das aufgerufene Programm dem Aufrufer nichts mitteilen kann, sondern nur seinen Kind-Prozessen. Die bish hat einen eigenen Speicher für Shell-Variablen. Hierhinein kann man Inhalte speichern, die von der Umgebung isoliert sind (global,lokal,lokal-statisch,...). Man kann aber globale Variablen exportieren, die dann aufgerufenen Programmen wiederum als Umgebung bekannt werden. Den Speicherplatz stellt der Exporteur zur Verfügung. Die Adressen darauf werden in das nächste Programm kopiert. Man kann auch Umgebungsvariablen verändern oder löschen. Das wirkt aber niemals rückwärts zum Aufrufer! Man hat nämlich nur Adressen bekommen, die ggf. von Adressen aus dem eigenen Speicher überdeckt werden können. Man muß also unterscheiden zwischen reinen Umgebungs-Variablen, aus denen nur gelesen wurde, Shell-Variablen, und exportierten Shell-Variablen! Die vorletzten können weiter unterteilt werden! Die temporären Dateien der bish werden hinsichtlich ihrer Handles auf Werte größer 9 justiert, so daß es garantiert keine unerwarteten Konflikte mit programmierten Umlenkungen geben kann. WARNUNGEN Die Shell unterscheidet grundsätzlich Groß- und Kleinschreibung! Notwendige Umwandlungen werden automatisch vorgenommen. Laufwerkangaben müssen vom nachfolgenden Namen mittels \ getrennt werden: c:\name... Lokal-statische Namen werden folgendermaßen gebildet: script_name@funktions_name@variablen_name Man kann erkennen, daß es hier eine Eindeutigkeits-Lücke gibt, wenn auch die Wahrscheinlichkeit für einen Fehlzugriff sehr gering ist. Wenn ein und dasselbe Script einmal mit dem einfachen Namen und ein anderes Mal mit dem vollen Pfadnamen aufgerufen wird, werden jeweils unterschiedliche Namen zusammengesetzt! Andererseits kann man genau das absichtlich ausnutzen! Oder wenn man das Directory wechselt und dort gleiche Namen vorkommen, kann unbeabsichtigter Bezug stattfinden. Das läßt sich durch Angabe von vollen Pfadnamen vermeiden; der Vorderteil eines Pfadnamens wird abgeschnitten, falls der Pfadname länger als die Hälfte der maximalen Pfadnamenlänge (DOS:64-128; UNIX:>=1024) ist. Umlenkungen, die ein Vorauslesen erfordern, über die Argumente eines 'normalen' Kommandos hinaus, kann die bish nicht. Schleifen (...done | ...), Blöcke ({...} | ...), Subshells (...), können nicht in eine Pipeline hinein schreiben! Auch andere Umlenkungen direkt hinter solchen Konstrukten sind nicht möglich - eine flexiblere Alternative sind globale Umlenkungen. Hinter: done fi esac dürfen TAB und/oder Leerzeichen stehen. Es muß ein Zeilenvorschub, Semikolon (;), Kommentar (#) oder EOF folgen. LIMITS Siehe Kommando ver l Die folgenden Limits gelten nur fuer DOS-Versionen. 31 Zeichen für Namen von Variablen und Funktionen. 1020 Argumente -insgesamt- im internen Bereich. 4 KByte -insgesamt- für die Argumentwerte im internen Bereich. 127 Byte für die Argumentwerte zu externen Kommandos (DOS). 128 Globale Namen (Variablen, Funktionen, Aliases, static-Namen). 64 Funktionsdefinitionen. 5 KByte für globale Inhalte und -namen. 16 Lokale Namen pro lokaler Ebene. (-Z-) 2 KByte -insgesamt- für lokale Variableninhalte und -namen. (-Z-) 12...18 -fache Verschachtelung bei Funktionen (auch trap,eval). 30...70 -fache Verschachtelung bei Syntax-Konstruktionen. 127 Zeichen für Pfadnamen. 12 Ein-/Ausgabe-Umlenkungen gleichzeitig-verschachtelt. 15 Unäre Operatoren vor einem Wert (Arithmetik). 22 ODER-| beim case-Kommando: pattern[|pattern]...) . 8 Sprungmarken pro lokaler Ebene. (-Z-) 7 Länge goto-Label-Name. (-Z-) 2 GByte bish-Scripts dürfen praktisch beliebig groß sein. Das gilt auch für Funktionskörper, Schleifenkörper, etc., für arithmetische Ausdrücke der Formen ((...)) und $((...)), und überall für 'Liste'. EXIT-CODE Derjenige des letzten ausgeführten Kommandos. Bei Fehlern größer 0. DATEIEN [$HOME]\autoexec.bish Shell-Script, wird nach Aufruf ausgeführt. $BISHTEMP\... Temporäre Dateien. [$HOME]\history.bish History-Liste des Kommandozeilen-Editors. SIEHE AUCH bish(A...Z), echo(K), test(K), cat(K), tr(K), wc(K), cut(K), regexp®, expr(K), grep(K), tee(K), crc(K), line(K), rel(K), bgrep(K), calc(K), timex(K), dd(K), hx(K), cmp(K), comx(K), touch(K), dat(K), readc(K), l(K), pg(K), man(K), ansi®. VERSION bish(.exe), Version 7.33 AUTOR bish wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1995-2022 |
cat(K) cat(K) NAME cat.exe - Schreibt Dateiinhalte bzw. die Eingabe zur Standard-Ausgabe. cat (intern bish(K)) SYNTAX cat [-svtemnBT] [-] [ datei ... ] BESCHREIBUNG Das Kommando cat liest Dateiinhalte oder, wenn keine Dateien angegeben sind oder wenn ein - angegeben ist, von der Standard-Eingabe. Ausgabe erfolgt auf die Standard-Ausgabe. cat wird häufig dazu benutzt, mehrere Dateiinhalte hintereinander verkettet auszugeben, um eine Sammeldatei zu erzeugen. Daneben besitzt cat einige Filterfunktionen. Kommandozeilen-Optionen: -B Dateien werden im Binär-Modus geöffnet. (Standard) -T Dateien werden im Text-Modus geöffnet. -s Unterdrückt Fehlermeldungen, wenn eine Datei nicht geöffnet werden konnte. -v Nichtabdruckbare Zeichen werden in sichtbare Zeichenfolgen, bestehend aus zwei Zeichen, umgesetzt. Die Zeichen mit den Dezimalwerten 1-26 (Ctrl-A bis Ctrl-Z), mit Ausnahme von Tabulator, Seiten- und Zeilenvorschub, werden in ^A bis ^Z umgesetzt. Aus den Werten 27-31 entsteht: ^[ ^\ ^] ^^ ^_ Die Werte 127, 155 und 255 werden in eine Dezimalform gewandelt: \127, \155, \255 Die folgenden vier Optionen (-temn) werden ignoriert, wenn diese Option -v nicht aktiviert ist. -t TAB wird umgesetzt in ^I FF wird umgesetzt in ^L -e Vor einen Zeilenvorschub wird $ gesetzt. -m Alle Zeichen >=128 werden in Dezimalform umgesetzt: \ddd -n Das Null-Zeichen wird per \0 dargestellt. Die Optionen können in beliebiger Kombination und mittels einem oder mehrerer Argumente angegeben werden. Unbekannte Optionen werden ignoriert. Beim Lesen von der Standard-Eingabe, wenn die Tastatur damit verknüpft ist, kann die Eingabe mit <Ctrl>+<D> oder +<Z> beendet werden. BEISPIELE cat d1 d2 d3 ... > Sammeldatei cat d1 ... >> datei cat datei cat > datei EXIT-CODE 0 Keine Fehler. 1 Bei fehlgeschlagenem Dateiöffnen. 2 Bei sonstigen Fehlern. SIEHE AUCH bish(K) AUTOR Dieses Kommando cat wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
crc(K) crc(K) NAME crc.exe - Errechnet eine CRC-Prüfsumme crc (Intern bish(K)) SYNTAX crc [ datei ... ] crc < datei kdo | crc BESCHREIBUNG Das Kommando crc erzeugt eine CRC-Prüfsumme in Abhängigkeit von einer gelesenen Byte-Folge. (CRC = Cyclic Redundancy Check) Die Prüfsumme ist mit sehr hoher Wahrscheinlichkeit für jede Byte-Folge individuell verschieden, wenn die Byte-Folgen in irgendeiner Art Unterschiede aufweisen. Das Vertauschen zweier beliebiger Bytes untereinander in einer Datenmenge hat bereits eine andere Prüfsumme zur Folge. Die Prüfsumme ist eine 32-Bit-Zahl (bis 4.294.967.295) und wird als Dezimalzahl zur Standard-Ausgabe geschrieben. Bei Angabe von zwei oder mehr Dateien werden die Dateinamen vorangestellt. Ist keine Datei angegeben, liest crc von der Standard-Eingabe. Falls dabei die Eingabe mit einem Gerät verknüpft ist, kann der Lesevorgang durch Eingabe von ^D oder ^Z beendet werden. Bei dieser letztgenannten Eingabeart werden anhängende NL-Zeichen (Zeilenvorschübe) entfernt. EXIT-CODE 0 Kein Fehler. 2 Bei Fehlern von System-Funktionen. SIEHE AUCH bish(K), cmp(K). AUTOR Dieses Kommando crc wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
cut(K) cut(K) NAME cut.exe - Schneidet Zeichenbereiche/Spalten/Worte aus Zeilen heraus. cut (intern bish(K)) SYNTAX cut -cListe [-BT] [ datei ... ] cut -fListe [-d'char'] [-s] [-BT] [ datei ... ] cut -fListe [-d'char...'] [-s] [-BT] [ datei ... ] cut -lListe BESCHREIBUNG Das Kommando cut liest Dateiinhalte oder, wenn keine Dateien angegeben sind, von der Standard-Eingabe. Ausgabe erfolgt auf die Standard-Ausgabe. cut selektiert beliebige Zeichenbereiche innerhalb von Zeilen. Für diese Aufgabe bietet cut drei verschiedene Arbeitsweisen. Kommandozeilen-Optionen: -cListe Die in Liste angegebenen Zeichen werden ausgegeben. (Listen-Syntax siehe unten.) Diese Arbeitsweise ist zu vergleichen mit dem Ausschneiden eines rechteckigen Längsstreifens aus einem Blatt Papier. -fListe Die angegebenen Felder werden ausgegeben. -d'c' Trennzeichen zur Bildung der Felder ist 'c'. Standardmäßig wird TAB eingesetzt. Eine Zeile wird in 'anzahl_trennzeichen+1' Felder aufgeteilt, wobei auch leere Felder gelten. Wenn die Eingabe beispielsweise nur aus drei Trennzeichen besteht, werden vier leere Felder und die drei Trennzeichen ausgegeben. Trennzeichen darf auch NL sein, womit eine Zeile ein Feld bildet. -d'c...' Wenn mehr als ein Trennzeichen angegeben wird, ändert sich die Arbeitsweise dahingehend, daß nur zusammenhängende Zeichenbereiche, bestehend aus Nicht-Trennzeichen, als Felder aufgefaßt werden. Für diesen Effekt können auch zwei gleiche Zeichen angegeben werden: -d' ' Trennzeichen darf auch NL sein. Bei mehr als einem Wort in der Ausgabe wird das erste Zeichen im Trennzeichen-String als Worttrenner eingefügt. -s Unterdrückt Zeilen, die keine Trennzeichen enthalten. Dies funktioniert nicht korrekt, wenn eine Zeile mehr als 510 Zeichen hat. -lListe Eine sortierte und möglicherweise minimierte Form der Liste wird ausgegeben. -B Dateien werden im Binär-Modus geöffnet. (Standard) -T Dateien werden im Text-Modus geöffnet. Listen-Syntax: Um Zeichenbereiche zu definieren, muß eine Zahlenliste angegeben werden, gemäß folgender Syntax: a,b,c-d,e-f,g-,-j,-,m,n-o[,...] Die Liste muß dem jeweiligen Optionsbuchstaben direkt folgen. Eine Zahl rechts vom Bindestrich darf nicht kleiner als die linke Zahl sein. Zahlen vor und/oder nach dem Bindestrich können weggelassen werden, sie werden dann als 1 bzw. als MAX angenommen. MAX ist der größte positive Wert eines Maschinenwortes. Die Listenausdrücke -durch Kommata getrennt- dürfen bezüglich ihrer Zahlenwerte völlig unsortiert sein. Beliebige Zahlenbereichs-Überlappungen sind erlaubt. (ODER-Fktn.) Maximal 128 Listenausdrücke sind möglich. Die Zeilenlänge ist praktisch unbegrenzt; cut kann ohne weiteres das dreißigtausendste Feld aus einer Dateneinheit selektieren. Ein Zeilenvorschub (NL) oder Input-Ende beendet eine Dateneinheit. Bei Option -f kann ein NL-Zeichen auch als Trennzeichen definiert werden. Eine Spezial-Syntax für die Angabe von solchen Zeichen gibt es nicht. Möglichkeiten: nl="`echo`"; cut -f... -d"$nl$nl" ... nl=" " cut -f... -d"$nl" ... Beim Lesen von der Standard-Eingabe, wenn die Tastatur damit verknüpft ist, kann die Eingabe mit <Ctrl>+<D> oder +<Z> beendet werden. BEISPIELE cut -c4-23,29,51-62 datei cut -f4-8 -d' ' datei # 4.-8. Wort aus allen Zeilen. cut -f4-8 -d"$NL" datei # 4.-8. Zeile aus datei. cut -f4-8 -d"$NL$NL" datei # 4.-8. nichtleere Zeile aus datei. cut -l1-3,5-11,4-7 # Ausgabe: '1-11' DIAGNOSE Fehlermeldung bei Syntax-Fehler. EXIT-CODE 0 Keine Fehler. 1 Bei fehlgeschlagenem Dateiöffnen. 2 Bei sonstigen Fehlern. SIEHE AUCH bish(K) AUTOR Dieses Kommando cut wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
echo(K) echo(K) NAME echo.exe - Liest Zeichenketten-Argumente und schreibt sie aus. echo (intern bish(K)) SYNTAX echo [ argument ... ] BESCHREIBUNG Das Kommando echo schreibt die erhaltenen Argumente jeweils durch ein Leerzeichen getrennt zur Standardausgabe. Zum Abschluß wird ein Zeilenvorschub zusätzlich ausgegeben. Die Argumente werden als Zeichenketten interpretiert. echo berücksichtigt die folgenden Spezial-Zeichenfolgen, wie sie in der Sprache C üblich sind, und noch weitere: (Jedoch wird \ durch % ersetzt.) %c Unterdrückt den abschließenden Zeilenvorschub und bewirkt gleichzeitig einen Ausgabeabbruch. %e <Escape> %z <Control><Z> %s " %t Tab %r Carriage return %n Newline (Unter DOS: \r\n) %f Form feed %b Backspace %v Vertikal-Tab %a Beep %% Prozent-Zeichen %'ZV' Nach dem Zeilenvorschub (\n oder \r\n) folgende Leerzeichen und Tabs werden ignoriert. %0377 Octal-Zahl von 0 bis 0377, also aus 1 bis 4 Digits bestehend. Das erste Digit muß stets 0 sein. Hiermit können sämtliche Zeichen des Zeichensatzes dargestellt werden. Mit Hilfe dieses Kommandos kann man bekannte Daten ausgeben; Datenumlenkung (< > |) erweitert das Anwendungsspektrum. echo ist hilfreich bei der Fehlersuche und praktisch bei der Erzeugung kleiner Dateien. BEISPIELE echo " Eine 3½%"-1440K-Diskette hat $(([(80*2*18-33)*512]/BSZ)) Blöcke" echo "set HOME=c:\user\thorolf" >> c:\autoexec.bat Ausgabe für ein Menü: echo "%r%n Zu testendes Verzeichnis: '$1' %tListendatei zur Liegenschaft : l %tLiegenschaft zur Listendatei : a %tHinweise : ? %tDieses Menü verlassen : v %tBeenden : e %t : %c" Man beachte, daß das Argument für echo ("...") sich über mehrere Zeilen erstreckt, inklusive Zeilenvorschübe. Eingerücktes Schreiben: echo "aaa% bbb% ccc" Ausgabe: aaa bbb ccc _ Die Leerzeichen/Tabs vor bbb und ccc werden ignoriert. Mit %r oder %b kann man 'folgenlos' dieses Ignorieren wieder abschalten. EXIT-CODE 0 Kein Fehler aufgetreten. 2 Wenn eine Systemfunktion einen Fehler meldete. SIEHE AUCH print(bish(K)), bish(I,...). AUTOR Dieses Kommando echo wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
expr(K) expr(K) NAME expr.exe - Vergleicht Zeichenketten mit einem Vergleichsmuster. expr.exe - Ersetzt Zeichenkettenteile durch einen Ersatztext. expr (intern bish(K)) SYNTAX expr zeichenkette [xbvc=]: RA [[+=] ersatztext] expr zeichenkette [xbvc=]:: RA [[+=] ersatztext] expr zeichenkette [xbvc=]:Name RA [[+=] ersatztext] expr [offset[:länge]]variablenname ... RA: Regulärer Ausdruck (Suchmuster) BESCHREIBUNG Dieses Kommando expr vergleicht Zeichenfolgen mit einem Suchmuster. Als Resultat dieser Bewertung reagiert expr mit einem entsprechenden Exit-Code und mit einer Ausgabe auf die Standard-Ausgabe oder einer Zuweisung an eine Shell-Variable. Wenn im zweiten Argument zwei Doppelpunkte (::) enthalten sind, erfolgt keine Ausgabe auf die Standard-Ausgabe. x bewirkt die Verwendung von XRA (eXtra erweiterte RA; xregexp®). b bewirkt die Verwendung von BRA (Basis RA). Diese Option hat Vorrang vor der Option -X der bish(K). v ermöglicht die Angabe eines Variablennamens anstelle einer Zeichenkette 'zeichenkette' (Daten, s.o.). Direkt vor dem Namen können ein Offset-Wert und eine Länge plaziert werden, die sich auf den Inhalt der Variablen beziehen. c Schaltet den internen Compilations-Cache ab. Bei Angabe von vier Argumenten ändert sich die Arbeitsweise, indem ein Ersatztext anstelle des zum Regulären Ausdruck passenden Zeichenkettenteils eingesetzt wird. Vor dem Ersatztext kann ein Steuerargument stehen: + Es werden alle Vorkommnisse ersetzt. Ohne diesen Schalter nur ein erstes. = Spezialzeichen(folgen) im Ersatztext gelten als gewöhnliche Zeichen. += Schalter + und = sind beide aktiv. Standard-Ausgabe unterbleibt bei Angabe von :: anstelle von : und ebenso bei der Zuweisung an 'Name'. Hinsichtlich der Syntax im Ersatztext (Substitution) siehe insbesondere xregexp®, und regexp®. Falls das zweite Argument vor : ein '=' enthält (=:), wird Groß- und Kleinschreibung nicht unterschieden, was jedoch bezogen auf Zeichenklasseninhalte ([...]) im RA nicht wirkt. Als Vergleichsmuster verarbeitet expr die von UNIX-Systemen her bekannten Regulären Ausdrücke (RA, siehe regexp®). Anstelle des Zeichens \ hat jedoch das Zeichen % die entsprechende Spezialbedeutung! (Mittels bish-Option -B oder 'set -B' kann \ geschaltet werden.) Ausgegeben wird die Anzahl derjenigen Zeichen aus der Zeichenkette, die zum RA passen - also die Länge einer Sub-Zeichenkette. Paßt keins, wird 0 ausgegeben, wobei der Exit trotzdem TRUE sein kann(!), wenn man beispielsweise als Anzahl >=0 ('c*') angibt und die Zeichenkette dadurch zum RA durchaus nicht unpassend ist. Der Exit hat Priorität und bewertet, ob der RA paßt oder nicht! Die Spezialvariable $. (Offset) wird bei passender Zeichenkette gesetzt, und zwar auf das erste passende Zeichen und gleichzeitig auf die Passenslänge. 0123456789 expr aaaabbbcc :: 'bbb' && echo $. $. $. $. 4 3 -1 -1 expr aaaabbbcc :: 'a%(ab%)bb' && echo $. $. $. $. 2 5 3 2 expr aaaabbbcc x:: 'a(ab)bb' && echo $. $. $. $. 2 5 3 2 | | | +------- Länge Einfassung | | +--------- Offset Einfassungsbeginn | +----------- Länge match +------------- Offset match-Beginn Offset und Länge werden durch zweimaliges Lesen erlangt. Die Werte einer Einfassung werden anschließend geliefert. Weiteres Lesen liefert zunächst zwei weitere hier ungesetzte Werte und dann erneut die vier Werte. Shell-Option -O muß für diesen Wertedurchlauf gesetzt sein! Andernfalls wird immer nur der match-Beginn geliefert. Die Offset-Werte (und der Offset der Offset-Werte) werden nur bei vorliegendem match und dadurch Exit=0=true gesetzt. Der Argument-offset wird zum jeweiligen Offset hinzuaddiert! Diese Dokumentation beschreibt ansatzweise die BRA; die neuen XRA werden gar nicht erklärt. Siehe daher insbesondere xregexp®. Die Funktionsprinzipien dieses Kommandos expr sind allerdings nicht unterschiedlich zwischen BRA und XRA. Die Zeichenfolgen %< und %> passen zum Anfang bzw. zum Ende eines Wortes, mit der Zeichenmenge: a-zA-Z_0-9 Vor und nach dem Wort müssen Zeichen stehen, die nicht aus der angegebenen Zeichenmenge stammen. Diese beiden Zeichenfolgen repräsentieren keine Zeichen, sondern justieren auf eine Position, wie ^ und $ . Folgende Zeichenfolgen sind speziell: %a %A Paßt / Paßt nicht zu A-Za-z %l %L Paßt / Paßt nicht zu a-z %u %U Paßt / Paßt nicht zu A-Z %d %D Paßt / Paßt nicht zu 0-9 %w %W Paßt / Paßt nicht zu A-Za-z_0-9 %! Invertiert -vorangestellt- die vorstehenden Zeichenmengen. Die Häufigkeit kann mit * und %{a,b%} (nachfolgend) festgelegt werden. Bei einer Folge %!%D setzt %! auf Invertierung, und %D invertiert diese Invertierung, wobei %d diese nicht invertieren würde. Die Folge %!%d entspricht folglich %D, und %!%D entspricht %d. Mittels der Operatoren %( und %) kann ein Teil des RA oder auch der ganze RA eingefaßt werden. In diesem Fall wird nicht die Anzahl der passenden Zeichen, sondern die Zeichen selbst ausgegeben. Und zwar diejenigen Zeichen der Zeichenkette, die zu der Einfassung beim RA passen - wenn der RA auch als ganzes paßt. Ein RA darf maximal neun solche Einfassungen %(...%) enthalten, nebeneinander und/oder verschachtelt. Mittels der Zeichenfolgen %1 bis %9 kann Bezug auf diese Einfassungen genommen werden, und zwar innerhalb des RA wie auch innerhalb des Ersatztextes. Bei einem zweiten Argument :: erfolgt keine Ausgabe. Im Ersatztext ist das Zeichen '&' speziell, welches den zum RA passenden Zeichenkettenteil einsetzt. Maskierzeichen ist '%'. Im Ersatztext sind weiterhin die Zeichenfolgen %U %L %E speziell, die auf Uppercase und Lowercase schalten, sowie diese Modi abschalten (%E). Beispiel: "%U&%Ea$vx%L%2$kh" Bei Operator ':Name' wird in die benannte Shell-Variable geschrieben. Hinsichtlich der Syntax im Ersatztext (Substitution) siehe insbesondere xregexp®, und regexp®. Ein Zeilenvorschub wird nur angehängt, wenn Handle 1 mit dem Bildschirm verknüpft ist und wenn überhaupt (zuvor) ein Zeichen ausgegeben wurde. WARNUNG Reguläre Ausdrücke sollten standardmäßig maskiert ('RA') werden, damit unerwünschte Interpretation des Shell-Programms unterbleibt. BEISPIELE expr $NAME : '.*' Liefert die Länge der Zeichenkette in der Shellvariablen NAME. (Einschließlich Zeilenvorschub.) expr $NAME : '[^%r%n]*' Wie zuvor, jedoch ohne die Zeilenvorschub-Zeichen. expr $PFAD : '.*\%(.*%)\.*' expr $PFAD : '.*\%([^\]%{1,12%}%)\[^\]%{1,12%}$' expr $PFAD : '.*\%([A-Za-z.]%{1,12%}%)\[A-Za-z.]%{1,12%}$' expr $PFAD : '.*\%([A-Z]%{1,8%}%.[A-Z]%{1,3%}%)\[A-Z.]%{1,12%}$' Geben den letzten Verzeichnisnamen eines Pfadnamens aus. Unterschiedlicher Eingrenzungsgrad. NOTA Das bish-interne expr-Kommando hat erhebliche Geschwindigkeitsvorteile. Häufiges Aufrufen hat diesbezüglich nicht die Nachteile von expr.exe. Das von UNIX-Systemen her bekannte externe Kommando expr hat zusätzliche Funktionalitäten, wie Berechnung und Vergleiche von arithmetischen Ausdrücken und Test von leeren/nichtleeren Strings. Diese Funktionalitäten werden von anderen bish-internen Kommandos (let, test) in besserer Form zur Verfügung gestellt, weshalb bei dem hier beschriebenen expr-Kommando darauf verzichtet wurde. Das Fixierzeichen ^ ist NICHT implizit im RA enthalten ('^...'). EXIT-CODE 0 Der Vergleich beider Ausdrücke ergab Übereinstimmung. (Auch wenn aus %(...%) nichts ausgegeben wurde.) 1 Die Ausdrücke passen nicht zueinander. 2 Fehler bei Offset oder Datenlänge (v). 3 Bei (Syntax-)Fehlern. SIEHE AUCH bish(K), regexp®, xregexp®, grep(K), test(K). AUTOR Dieses Kommando expr wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1995-2018 |
grep(K) grep(K) NAME grep.exe - Prüft Zeilen auf Übereinstimmung mit einem Suchmuster grep (intern bish(K)) SYNTAX grep [ -BXFSVAchlm[n]nsviyLxq1 ] [Vname] [-e] RA [ datei ... ] grep [ -BXFSVAchlm[n]nsviyLxq1 ] [Vname] { -e RA }... [ datei ... ] RA: Regulärer Ausdruck (Suchmuster) BESCHREIBUNG Das Kommando grep durchsucht Dateien nach Zeilen, die mit einem Suchmuster übereinstimmen und schreibt diese Zeilen zur Standard-Ausgabe. Wenn keine Dateien angegeben werden, liest grep von der Standard-Eingabe, sofern diese nicht mit einem Terminal (tty) verknüpft ist. Bei mehr als einer Datei wird jeder Zeile der zugehörige Dateiname vorangestellt. Als Suchmuster verarbeitet grep die von UNIX-Systemen her bekannten Regulären Ausdrücke (RA, siehe regexp®). Anstelle des Zeichens \ hat jedoch das Zeichen % die entsprechende Spezialbedeutung! Innerhalb der bish(K) kann per 'set -B' das Zeichen \ gewählt werden. Mittels 'set +B' kann wieder auf % zurückgestellt werden. Und innerhalb eines RAs können neben %n auch %r, %t und %z als Ersatz für die Zeichen NL, CR, TAB und ^Z verwendet werden (auch zwischen []). Diese Dokumentation beschreibt ansatzweise die BRE, die neuen XRE jedoch gar nicht; siehe dazu xregexp®. grep berücksichtigt folgende Kommandozeilen-Optionen: -B Es werden BRA (Basis-RA) verwendet (Default). Dies hat Vorrang vor der bish-Option '-X'. -X Es werden XRA (eXtra erweiterte Reguläre Ausdrücke) anstelle der BRA (Basis RA) verwendet. -F Kein Zeichen des Suchmusters hat spezielle Bedeutung. Das Suchmuster wird nicht als RA interpretiert. Die Funktion entspricht dem Kommando 'fgrep'. -S Die Vergleichsrichtung bei den Zeichenketten wird umgedreht (Swap: a in b <--> b in a). Ist nur bei -F wirksam. -V Ausgabe erfolgt in eine Variable 'Vname'. Es wird die Anzahl der passenden Zeilen eingetragen. Bei mehreren Dateien wird nur der Wert der letzten Datei eingetragen. Insofern ist diese Option nur bei einer einzigen angegebenen Datei oder beim Lesen von der Standard-Eingabe sinnvoll. -x Zeile und Suchmuster müssen komplett gleich sein. (Option -F wird als gesetzt angenommen.) -e Falls ein RA mit dem Minuszeichen (-) beginnt. (Konflikt mit der Optionen-Schreibweise!) Oder falls mehrere RA angegeben werden. Es können maximal 8 '-e RA' angegeben werden. Bei zwei oder mehr angegebenen RA wird jede Zeile entsprechend oft untersucht, bis ein eventuelles Passen (match) auftritt. Es handelt sich um eine Oder-Funktion. Eine Und-Funktion ist wählbar (-A). -A Es können bis zu 8 '-e RA' angegeben werden, für die nun jedoch eine Und-Funktion gilt. -c Anstelle des Inhalts passender Zeilen wird deren Anzahl (pro Datei) ausgegeben. -h Verhindert die Ausgabe von Dateinamen. -l Es werden nur Dateinamen ausgegeben, und zwar ggf. auch bei nur einem angegebenen Namen. Die Optionen -c und -h sind hierbei unwirksam. -m[n] Es werden maximal n passende Zeilen ausgegeben. Voreingestellt ist n=1. (Diese Option hat Vorrang über -c) -L Nur die letzte passende Zeile wird ausgegeben. Diese Option ordnet sich den anderen unter und unterdrückt -mit Ausnahme der letzten- die Ausgabe aller Zeilen. Bei dieser Option wird eine Zeile mit mehr als 32 KB auf diese Länge gekürzt. -n Passenden Zeilen wird deren Nummer vorangestellt. -s Unterdrückt Fehlermeldungen über Dateien, die nicht geöffnet werden konnten. -v Invertiert die Arbeitsweise; nicht-passende Zeilen gelten als übereinstimmend. -i -y Groß-/Kleinschreibung wird ignoriert. Das gilt nicht für äöü(ÄÖÜ); hier muß man gegebenenfalls Zeichenklassen ([Ää]) angeben. -q (=quiet) -1 Standard-Ausgabe wird unterdrückt. WARNUNG grep unterstützt eine maximale Zeilenlänge von 1 MB. grep arbeitet zeilenorientiert; es wird ein Datenstrom mit Zeilenvorschüben verlangt. Reguläre Ausdrücke sollten standardmäßig maskiert ('RA') werden, damit unerwünschte Interpretation des Shell-Programms unterbleibt. BEISPIELE grep '^ [A-Z].*[A-Z0-9]$' grep.mnk Liefert die Gliederungsüberschriften dieser Datei: NAME SYNTAX BESCHREIBUNG ... AUTOR grep -l 'N[oO][lL][aA][hH]%{0,1%} %{1,2%}GmbH' *.txt Liefert die Namen derjenigen Dateien im aktuellen Verzeichnis, die den Firmennamen 'Nolah GmbH' enthalten, und zwar klein- oder großgeschrieben, mit oder ohne 'h' am Ende, und mit ein oder zwei Leerzeichen zwischen den beiden Worten. In der Praxis braucht man meistens nicht so stark eingrenzen; folgender Ausdruck führt auch zum Ziel: 'N[oO][lL][aA]..*GmbH' edit ` grep -l '\[A-Z]%{1,%}\CERA\[A-Z]%{1,%}' *.LST *.TXT ` Ruft einen Editor auf, mit allen Dateien im Verzeichnis als Argumente, die mit LST oder TXT enden und die gleichzeitig mindestens einen dreigliederigen Pfadnamen enthalten, dessen zweite Komponente CERA lautet und dessen andere Komponenten mindestens einen Großbuchstaben A-Z enthalten. NOTA Das bish-interne grep-Kommando hat Geschwindigkeitsvorteile. Häufiges Aufrufen hat diesbezüglich kaum Nachteile gegenüber einem Aufruf mit vielen Dateinamen. Es kann eine außerordentlich lange Dateinamenliste angegeben werden. In der bish können Kommandos in eine Oder-Kette gestellt werden: In etwa 20 Jahren wurde einmal grep &| grep &| grep und etwa 5-mal grep &| grep programmiert. Daraus ist ersichtlich, daß 8-mal '-e RA' ausreichen sollte. EXIT-CODE 0 Mindestens eine Zeile wurde als zutreffend bewertet. 1 Keine Zeile wurde als zutreffend bewertet. 2 Bei (Syntax-)Fehlern. SIEHE AUCH bish(K), xregexp®, regexp®, expr(K) AUTOR Dieses Kommando grep wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1995-2016 |
bgrep(K) bgrep(K) NAME bgrep.exe - Durchsucht Dateien nach einer Byte-Folge bgrep (intern bish(K)) SYNTAX bgrep [-gclihstvqM] [name] [-oN|-ON] [-nN] [-f]Folge datei ... bgrep [-gclihstvqM] [name] [-oN|-ON] [-nN] -Fdatei datei ... bgrep [-gclihstvqM] [name] [-oN|-ON] [-nN] -Vname datei ... N: #[{b|k|w|l}][{x|+}#[{b|k|w|l}]]...[{x|+|-}#[{b|k|w|l}]] #: [0]...{1-9}...[0-9]... BESCHREIBUNG Das Kommando bgrep liest eine oder mehrere Dateien und sucht dabei nach Vorkommnissen einer Folge von Bytes. Die Byte-Folge kann in der Kommandozeile angegeben werden oder wird aus einer Datei gelesen, wobei alle Werte von 0 bis 255 gültig sind und nötigenfalls per '\ddd' oder '\xhh' geschrieben werden können. Wenn keine Datei angegeben wurde, liest bgrep von der Standard= eingabe, falls diese nicht mit einer Tastatur verknüpft ist, wobei dann die Optionen -oO ignoriert werden. Standardmäßig wird die Byte-Nummer (>=0) der ersten Fundstelle zur Standardausgabe geschrieben. Bei mehr als einer angegebenen Datei wird der Dateiname jeweils vorangestellt: 'name: nummer' bgrep (binary grep) verarbeitet keine 'regulären Ausdrücke', und ähnelt damit 'fgrep'. bgrep berücksichtigt die folgenden Kommandozeilen-Optionen: -g Es werden alle Vorkommnisse gemeldet, anstatt nur des (jeweils) ersten. -c Anstelle der Byte-Nummer(n) wird die Anzahl der Fundstellen (>=0) ausgegeben. -l Es werden die Namen nur derjenigen Dateien mit mindestens einer Fundstelle ausgegeben. -i Wirkt mit vorstehender Option -l zusammen: Es werden die Namen nur derjenigen Dateien ohne Fundstelle ausgegeben. -h Das Voranstellen der Dateinamen(:) wird abgeschaltet. -s Fehlermeldungen (+Exit), bezüglich von Dateien, die nicht geöffnet werden konnten, unterbleiben. -v Es muß ein Variablenname 'name' angegeben werden. Dorthinein wird die Byte-Nummer der Fundstelle oder die Anzahl der Fundstellen geschrieben. Nach einem Schreiben wird nochmaliges Schreiben gesperrt. -q Mittels dieser Option wird jeder Schreibvorgang zur Standardausgabe unterdrückt. Es verbleibt der Exit-Wert zur Auswertung, und die Ausgabe in eine Variable. -M Es wird Memory-Mapping mmap() benutzt. Diese UNIX-Lesemethode ist um etwa 20% schneller. -o Diese Optionen dienen zur Angabe eines Offsets. -O Bei -O werden die Byte-Nummern ab Offset gezählt, während bei -o die absoluten Dateiadressen ausgegeben werden. Es kann eine Dezimalzahl in einfacher Form oder ein arithmetischer Ausdruck angegeben werden (s.unten). -n Es werden nicht mehr Bytes durchsucht als mit dieser Option angegeben wurden. -t Konversionen für die Optionen -F -V -f . -F Die Byte-Folge, nach der gesucht werden soll, wird einer angegebenen Datei entnommen. Durch -t wird eine Konversion (\ddd\xhh) vorgenommen. Anhängende \r\n^Z werden entfernt - man kann ggf. stattdessen \13\10\26 schreiben. -V Die Byte-Folge, nach der gesucht werden soll, wird einer angegebenen Variable 'name' entnommen. Durch -t wird eine Konversion (\ddd\xhh) vorgenommen. -f Muß verwendet werden, falls die Byte-Folge mit einem Minus-Zeichen (-) beginnt. Durch -t wird die Konversion (\ddd\xhh) abgeschaltet; auch ohne -f . Optionswerte müssen dem Optionsbuchstaben ohne Zwischenraum folgen. Die Optionen können in beliebiger Reihenfolge angegeben werden; oOnfFnNe dürfen aber nicht mit den anderen kombiniert werden. Optionen -c und -l löschen sich gegenseitig, -l löscht -g . Arithmetischer Ausdruck für 'n': Beispiel: -o33bx4x15+1200+25-3l entspricht -o1014973 x ist ein Multiplikations-Operator. b entspricht x512 k entspricht x1024 w entspricht x2 l entspricht x4 Spezielle Umwandlungen bei der Byte-Folge: Nach einem Zeichen '\' wird eine Dezimalzahl aus ein bis drei Digits 0-9 in ein Byte mit dem entsprechenden Wert umgewandelt. Nach den Zeichen '\x' wird eine Hexadezimal-Zahl aus ein bis zwei Hex-Zeichen 0-9a-fA-F in ein Byte umgewandelt. Jedes erste Zeichen '\' wird entfernt, woraus folgt, daß zwei dieser Zeichen (\\) geschrieben werden müssen, damit eins resultiert. '\x' wird ebenfalls grundsätzlich entfernt. bgrep berücksichtigt die folgenden Umgebungsvariablen (Environment): BGREPAUTOR Um die Autorenmeldung abzuschalten: BGREPAUTOR=H.Schellong,Vlotho BGREPPROGRAM Um die Freeware-Meldung zu unterdrücken: BGREPPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (BGREPAUTOR muß hierfür auch gesetzt sein.) Dies gilt nicht für das bish-interne bgrep. WARNUNGEN Bei arithmetischen Ausdrücken sollte ein Minuszeichen gegebenenfalls nur vor der letzten Zahl stehen. Sonst gibt es unerwartete Resultate. bgrep benutzt lseek() bei Offset-Angabe >0. Dies sei gesagt im Hinblick auf Dateien, die nicht seek-bar sind. bgrep ist hier nicht so vielseitig ausgestattet wie dd(K). HINWEISE Die maximale Länge für die (resultierende) Byte-Folge beträgt 4096. Das Kommando arbeitet äußerst schnell und benötigt auf einem Pentium60 unter Unix nur etwa 0.07 Sekunden user-/sys-time pro MB. bgrep -c .text 360k-Datei 27 msec fgrep -c .text 360k-Datei 160 msec grep -c .text 360k-Datei 3340 msec grep -c .text 360k-Datei 390 msec (bish-intern-grep) (170 Vorkommnisse ".text") DIAGNOSE Fehlermeldungen zur Standard-Fehlerausgabe. EXIT-CODE 0 Byte-Folge mindestens einmal gefunden. 1 Byte-Folge nicht gefunden. 2 Fehlerhafte Argumentliste. 3 Dateiöffnen fehlgeschlagen. 4 Fehler beim Dateilesen. SIEHE AUCH grep(K), bish(K), hx(K), dd(K), cmp(K). AUTOR Dieses Kommando bgrep wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1995-2016 |
line(K) line(K) NAME line.exe - Gibt selektierte Zeilen aus line (intern bish(K)) SYNTAX line [ {-|+}a[-[e]] ] [ datei ... ] BESCHREIBUNG Das Kommando line liest Dateiinhalte und schreibt selektierte Zeilen auf die Standard-Ausgabe. Sind keine Dateien angegeben, liest line von der Standard-Eingabe. Sind keinerlei Argumente angegeben und ist die Standard-Eingabe mit der Tastatur verknüpft, liest line eine einzelne Zeile (-1). Mit der Kommandozeilenoption a-e kann eine Zeile oder ein Zeilenbereich ausgewählt werden: -n z.B. -4 -a-e z.B. -5-45 -a- a - 2^31-1 +a alle Zeilen außer a +a-e alle Zeilen außer a-e Voreingestellt ist -1-10 . Bei einem vorangestellten Pluszeichen wird die Arbeitsweise invertiert: nicht angegebene Zeilen werden ausgegeben. Bei fehlendem Endwert ([e]) wird 'quasi-unendlich' eingesetzt. Die Listen-Syntax des Kommandos cut(K) ist wesentlich komfortabler. Dies sei gesagt, weil man mit cut ähnliche Aufgaben lösen kann. Zeilen mit mehr als 1536 Zeichen werden zerstückelt. BEISPIEL zeile="`line`" Liest eine Zeile 'raw' - anders als 'read'. EXIT-CODE 0 Kein Fehler. 2 Fehler von Systemfunktion. SIEHE AUCH bish(K), cut(K), rel(K), readc(K), read(bish(K)). AUTOR Dieses Kommando line wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
wc(K) wc(K) NAME wc.exe - Zählt Zeilen, Worte und/oder Zeichen, oder Längen. wc (intern bish(K)) SYNTAX wc [-lwcm] [ datei ... ] BESCHREIBUNG Das Kommando wc liest Dateiinhalte oder, wenn keine Dateien angegeben sind, von der Standard-Eingabe. Ausgabe der gezählten Werte erfolgt auf die Standard-Ausgabe. Zugehörige Dateinamen werden nach den Zahlen ausgegeben, falls mehr als eine Datei angegeben wurde. Bei zwei oder mehr Dateien werden abschließend die Summenwerte ausgegeben. Tastatur-Eingabe kann mit ^D oder ^Z beendet werden. Kommandozeilen-Optionen: -l Anzahl Zeilen wird ausgegeben. -w Anzahl Worte wird ausgegeben. -c Anzahl Zeichen wird ausgegeben. -m Maximale Längen von Zeilen und/oder Worten werden ausgegeben. Zeilenendezeichen werden mitgezählt. Option -c bewirkt hier die Ausgabe der Anzahl von verschiedenen Zeichen. Die Optionen können in beliebiger Kombination und mittels ein bis vier Argumenten angegeben werden; unbekannte werden ignoriert. Standard-Einstellung ist -lwc . Die der Wortisolierung zugrunde liegenden Trennzeichen sind: Leerzeichen, Tab und Zeilenvorschub. Bei der bish-internen Version ist dies der Inhalt von IFS. Eine unvollständige Zeile am Dateiende (ohne Zeilenvorschub) wird berücksichtigt. Zeilenvorschübe werden also als Zeilentrenner bewertet. BEISPIELE ANZAHLWORTE=`echo $ARRAY | wc -w` ARRAYGRÖßE=`echo "$ARRAY%c" | wc -c` DATEIGRÖßE=`cat $DATEI | wc -c` DATEIGRÖßE=`wc -c $DATEI` wc -l datei EXIT-CODE Ungleich 0 bei Fehlern. AUTOR Dieses Kommando wc wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
cmp(K) cmp(K) NAME cmp.exe - Vergleicht Dateiinhalte byte-weise cmpf (intern bish(K)) SYNTAX cmpf [-q] datei1 datei2 [offs1 [offs2]] BESCHREIBUNG Das Kommando cmpf vergleicht byte-weise die Inhalte zweier Dateien. Bei Ungleichheit wird die entsprechende (erste) byte-Adresse als Dezimalzahl zur Standard-Ausgabe geschrieben. Bei Gleichheit aber unterschiedlichen Dateigrößen wird das Wort "SIZE" ausgegeben. Die Kommandozeilen-Option -q unterdrückt Ausgaben auf die Standard-Ausgabe. In diesem Fall verbleibt nur der Exit-Code (s.u.) zur Auswertung. Bei Angabe von Offset-Werten (offs1,offs2) werden die zugehörigen Dateien nicht auf Anwendbarkeit geprüft; die Systemfunktion lseek() wird etwaige Fehler melden. Eine Prüfung per Kommando 'test|[..]' ist die bessere Lösung. cmpf berücksichtigt die folgenden Umgebungsvariablen (Environment): BSHAUTOR Um die Autoren-Meldung zu unterdrücken: BSHAUTOR=H.Schellong,Vlotho CMPPROGRAM Um die Freeware-Meldung zu unterdrücken: CMPPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (BSHAUTOR muß hierfür auch gesetzt sein.) Nicht gültig bish-intern. BEISPIELE cmpf datei1 datei2 cmpf -q vers vers_ || { cmp_status=$?; goto NOTEQ; } DIAGNOSE Fehler-Beschreibungen zur Standard-Fehlerausgabe. EXIT-CODE 0 Bei Gleichheit der Dateien. 1 Bei Ungleichheit der Dateien. 2 Bei Fehlern von System-Funktionen. 5 Bei Gleichheit aber unterschiedlichen Dateigrößen. 8 Bei fehlerhafter Argumentliste. SIEHE AUCH bish(K), fstat, test(K), crc(K), sha256(K), sha512(K). AUTOR Dieses Kommando cmpf wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1995-2016 |
rel(K) rel(K) NAME rel.exe - Entfernt gleiche Zeilen (remove equal lines) rel (intern bish(K)) SYNTAX rel [ arg ... ] [ < datei1 ] [ > datei2 ] ... | rel [ arg ... ] | ... BESCHREIBUNG Das Kommando rel ist ein typisches Filter-Kommando, das von der Standard-Eingabe liest und auf die Standard-Ausgabe schreibt. Aufeinanderfolgende gleiche Zeilen werden -bis auf eine- entfernt. Das gilt auch für Leerzeilen. Falls Argumente angegeben sind, werden auch Zeilen entfernt, die damit gleich sind - und zwar alle solche Zeilen. Tastatur-Eingabe kann mit ^D oder ^Z beendet werden. EXIT-CODE 0 Kein Fehler. 2 Fehler von Systemfunktion, u.a. SIEHE AUCH bish(K), cut(K), line(K). AUTOR Dieses Kommando rel wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1996-2016 |
tr(K) tr(K) NAME tr.exe - Umsetzen, Löschen und Reduzieren von Zeichen(folgen). tr (intern bish(K)) SYNTAX tr [-cds] [ string1 [ string2 ] ] BESCHREIBUNG Das Kommando tr ist ein typisches Filterkommando. tr liest von der Standard-Eingabe und schreibt auf die Standard-Ausgabe. Häufigste Verwendung ist die Umsetzung der Zeichen in string1 in die korrespondierenden Zeichen in string2. Die Möglichkeiten gehen allerdings insgesamt weit über diese einfache Funktion hinaus. Tastatur-Eingabe kann mit ^D oder ^Z beendet werden. Kommandozeilen-Optionen: -c Die Zeichenmenge in string1 wird komplementiert. Es werden diejenigen Zeichen als in string1 angegeben angenommen, die NICHT angegeben wurden. Grundlage dafür ist der gesamte Zeichensatz. tr verarbeitet sämtliche Zeichen von dezimal 0 bis 255. -d Aus dem Eingabestrom werden diejenigen Zeichen entfernt, die in string1 angegeben sind. Option -c wirkt vorher. -s Mit Wirkung auf den Ausgabestrom wird von den in string2 angegebenen Zeichen eine Folge von gleichen Zeichen auf ein einzelnes Zeichen reduziert. In der Ausgabe können also nicht zwei oder mehr gleiche Zeichen hintereinander auftauchen, die in string2 angegeben wurden. Die Optionen können nur per folgender Formen angegeben werden: -c -d -s -cd -cs -ds oder -cds Und zwar, damit keine besonderen Maßnahmen nötig sind, falls ein string mit - beginnt. Beispielsweise -dcs und -cdss werden als string interpretiert. String-Syntax: Innerhalb der strings werden folgende Sequenzen verarbeitet: [a-z][A-Z][z-a] Kurzform für Zeichenbereiche. Umdrehungen sind also auch hier möglich. [c*n] Die Anzahl des Zeichens c wird durch n angegeben. Sinnvoll in string2. Bei n=0 oder fehlendem n wird eine maximale Anzahl angenommen. n wird dezimal bewertet. \d \dd \ddd Außerhalb der [...] und innerhalb an den Positionen a, z und c können nach \ ein bis drei Digits als Dezimalzahl angegeben werden. Ein Nicht-Digit beendet; nötigenfalls kann mit führenden Nullen erweitert werden. \ Maskierzeichen. Hebt die Spezialbedeutung von \ und [ auf. Die Zeichen - * ] sind allein durch ihre Position nach [ speziell. Die resultierenden string-Längen dürfen unterschiedlich sein. Bei Länge 256 wird gekappt. Bei Option -c ist die Position der Komplement-Zeichen natürlich nicht explizit angebbar. BEISPIELE Kleinbuchstaben in Großbuchstaben umwandeln: tr "[a-z]äöü" "[A-Z]ÄÖÜ" <datei1 >datei2 Soviel Punkte werden ausgegeben, wie Zeilen in der Datei sind: tr -cd \10 <datei | tr \10 . Entfernt alle Leerzeilen, außer einer ersten: tr -s '' \10 <datei tr -s \13 \10 b<datei (DOS: \r werden allerdings gelöscht.) tr -s '' \10 t<d1 t>d2 (DOS) Beläßt nur alphanumerische, deutsche Worte in den Zeilen; die entstehenden Zeilen können weiterverarbeitet werden: tr -cs '[a-z]äöüß[A-Z]ÄÖÜ[0-9]\13\10' '[ *]' <datei Alle Zeichen werden in '\0' umgesetzt (demonstriert -c ''): kdo1 | tr -c '' '[\0*]' | kdo3 Alle $-Zeichen aus datei werden in @-Zeichen umgesetzt und dann alle '\0'-Zeichen in $-Zeichen und Ausgabe zum Bildschirm: tr '$' '@' <datei | tr '\0' '$' Ein Wort pro Zeile: tr -cs '[a-z][A-Z][0-9]' '[\10*]' <datei1 >datei2 Aus dem beliebigen Inhalt von datei1 werden alle alphanumerischen Zeichenfolgen extrahiert und ein Wort pro Zeile an datei2 ausgegeben. Alle nicht-alphanumerischen Zeichen werden in Zeilenvorschübe umgewandelt. Durch Option -s wird maximal ein NL hintereinander ausgegeben. So kann man bespielsweise aus einer Binär-Datei alle lesbaren Zeichenfolgen gewinnen. Von Nachteil ist dabei, daß nach diesem einen Verarbeitungsschritt auch Worte aus nur ein bis zwei Zeichen ausgegeben werden. DIAGNOSE Fehlermeldung bei string-Syntaxfehlern. EXIT-CODE 0 Kein Fehler aufgetreten. 2 Bei Fehler einer Systemfunktion. AUTOR Dieses Kommando tr wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
test(K) test(K) NAME test.exe - Bewertet Ausdrücke und reagiert mit dem Exit-Code [.exe test, [, [[ (intern bish(K)) SYNTAX test ausdruck [ ausdruck ] [[ ausdruck ]] BESCHREIBUNG Das Kommando test wertet die erhaltenen Argumente aus und reagiert mit einem entsprechenden Exit-Code. Die Argumente bilden insgesamt einen Ausdruck, bestehend aus Zeichenketten und Operatoren und müssen durch Leerzeichen oder Tabs voneinander getrennt werden, was auch bei einem Aufruf per Spezialsyntax-Zeichen ( [ ] , [[ ]] ) für diese gilt. Die Abschlußargumente ] bzw. ]] müssen in diesen Fällen vorhanden sein. Ohne Argument liefert test einen FALSE Exit-Code. Achtung, TRUE = 0 und FALSE = 1 ! test verarbeitet die folgenden Elementar-Ausdrücke, die mittels der weiter unten beschriebenen Operatoren beliebig zu einem Gesamtausdruck zusammengestellt werden können: -e datei TRUE wenn datei existiert. -r datei TRUE wenn datei () lesbar ist. -w datei TRUE wenn datei () beschreibbar ist. -x datei TRUE wenn datei () ausführbar ist. -f datei TRUE wenn datei () eine normale Datei ist. -d datei TRUE wenn datei () ein Verzeichnis ist. -c datei TRUE wenn datei () ein Zeichen-Gerät ist. -s datei TRUE wenn datei () nicht leer ist. -t handle TRUE wenn handle mit einem Gerät verbunden ist. Die Klammern () stehen für "existiert und". UNIX: -b datei TRUE wenn datei () ein Block-Gerät ist. -p datei TRUE wenn datei () eine FIFO(named pipe) ist. -h datei TRUE wenn datei () ein symbolischer Link ist. -L datei TRUE wenn datei () ein symbolischer Link ist. -u datei TRUE wenn datei () set_uid gesetzt hat. -g datei TRUE wenn datei () set_gid gesetzt hat. -k datei TRUE wenn datei () sticky-bit gesetzt hat. -H datei TRUE wenn datei () ein semaphore ist. -M datei TRUE wenn datei () shared memory ist. -S datei TRUE wenn datei () ein Socket ist. -O datei TRUE wenn datei () uid gleich eff. process-uid ist. -G datei TRUE wenn datei () gid gleich eff. process-gid ist. datei1 -nt datei2 TRUE wenn datei1 neuer ist als datei2. datei1 -ot datei2 TRUE wenn datei1 älter ist als datei2. datei1 -ef datei2 TRUE wenn beide dateien auf dem selben Laufwerk sind. -z string TRUE wenn string ein Leerstring ist. -n string TRUE wenn string kein Leerstring ist. string TRUE wenn string kein Leerstring ist. str1 = str2 TRUE wenn die Zeichenketten gleich sind. str1 == str2 TRUE wenn die Zeichenketten gleich sind. str1 != str2 TRUE wenn die Zeichenketten ungleich sind. str1 = pattern TRUE wenn str1 zum pattern paßt. (nur bei [[ ]]) str1 == pattern TRUE wenn str1 zum pattern paßt. (nur bei [[ ]]) str1 != pattern TRUE wenn str1 nicht zum pattern paßt. (nur bei [[ ]]) str1 > str2 TRUE wenn str1 größer als str2 ist. str1 < str2 TRUE wenn str1 kleiner als str2 ist. n1 -eq n2 TRUE wenn die Zahlen algebraisch gleich sind. -ne -gt -ge -lt und -le stehen ebenfalls zur Verfügung. (!= > >= < <=) Bei diesen Operatoren für numerische Vergleiche können auch pure Variablennamen -also nicht '$var', sondern 'var'- angegeben werden. Die Variablen müssen hierbei aber existieren. Die vorgenannten Elementar-Ausdrücke können mittels folgender Operatoren verknüpft werden: ! Unärer Negations-Operator -a Binärer AND-Operator (Vorrang vor -o bzw. ||) && Binärer AND-Operator (Vorrang vor -o bzw. ||) [[ ... ]] -o Binärer OR-Operator || Binärer OR-Operator nur bei [[ ... ]] ( ) Klammern, um einen bestimmten Vorrang zu erzwingen. Achtung, manche Operatoren haben Spezialbedeutung für Shell-Programme und müssen ggf. maskiert werden! BEISPIELE [ $STR = absf -a -n "$DAT" -a %( -s "$DAT" -o "$DAT2" %) ] [[ $STR = absf && -n "$DAT" && ( -s "$DAT" || "$DAT2" ) ]] [ $MNT = F -o $MNT = RW -a -z "$2" -o $MNT = R -a -n "$2" ] && echo ... NOTA Gleichnamige Programme sind unter den verschiedenen UNIX-Systemen vorhanden, die dort jedoch oft das Problem haben, Operatoren und String-Argumente auseinanderzuhalten, weil die Operatoren ja auch Strings sind und die als Strings zu bewertenden Argumente einen Operator darstellen können! Es wird dort empfohlen, beispielsweise X auf gleiche Weise hinzuzufügen: X$KVALUE != X-le um Eindeutigkeit zu erzwingen. Bei diesem Programm ist diese Vorgehensweise nicht notwendig! Bei folgendem Ausdruck wird folgendermaßen erkannt: test -o -o -o -a ! -a s o s o o s test -z Führt nicht zu einer Fehlermeldung, sondern zu TRUE, weil '-z' schließlich ein nichtleerer String ist. Ein weiterer Unterschied ist, daß die Operatoren für algebraischen Vergleich bei den Operanden keine anderen Zeichen als die oben angegebenen akzeptieren. Dieses test-Kommando arbeitet von rechts nach links (!) und NICHT mit KO-Logik; alle Teilausdrücke werden bewertet. Da nur einfache Tests und Vergleiche ausgeführt werden, ist das in der Anwendung jedoch kaum von Bedeutung. Wenn eine Reihenfolge erzwungen werden muß, kann man zwei oder mehr Kommando-Aufrufe hintereinanderschalten: test ... && test ... || ... (s. bish(K)) Grundsätzlich sollten Variablen von "" eingeschlossen sein, weil dann bei leerer Variable wenigstens ein Leerargument vorhanden ist: "$VARIABLE" oder auch $VARIABLE"" Gar kein Argument führte zu Mißinterpretation oder Fehlermeldung! EXIT-CODE 0 TRUE Ausdruck wurde als zutreffend bewertet. 1 FALSE Ausdruck wurde als unzutreffend bewertet. 2 Bei Syntaxfehlern. SIEHE AUCH bish(K), bish(I,...), regexp®. AUTOR Dieses Kommando test wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
tee(K) tee(K) NAME tee.exe - Bildet ein T-Stück innerhalb einer Pipeline tee (Intern bish(K)) SYNTAX tee [ [-a] datei ] tee datei < idatei | kdo kdo | tee datei | kdo BESCHREIBUNG Das Kommando tee liest von der Standard-Eingabe und schreibt seine Eingabe unverändert zur Standard-Ausgabe und(!) in eine angegebene Datei. Der Datenstrom in einer Pipeline wird also an der Stelle, wo tee platziert wird, angezapft und in eine Datei kopiert. Tastatur-Eingabe kann mit ^D oder ^Z beendet werden. Bei Angabe einer Datei kann per Option -a ein Anhängen an den bisherigen Dateiinhalt gewählt werden (append). Wird datei nicht angegeben, wird nur zur Standard-Ausgabe geschrieben. BEISPIELE kdo | tee datei | kdo Standard-Verwendung: tee zapft den Datenstrom an und erstellt daraus eine Datei. tee datei < idatei t> odatei datei ist eine Kopie von idatei, und odatei eine TEXT-Modus-Kopie von idatei, mit zusätzlichen CR-Zeichen (\r). EXIT-CODE 0 Kein Fehler. 1 Wenn keine Datei angegeben wurde. 2 Bei Fehlern von System-Funktionen. SIEHE AUCH bish(K) AUTOR Dieses Kommando tee wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1995-2017 |
coder(K) coder(K) NAME coder.exe - Kodiert Dateien in Textformen um, und umgekehrt coder (intern bish(K)) SYNTAX coder -e [-nv] [-c code64] [ quell_vname [ziel_vname]] coder -d [-sv] [-c code64] [[quell_vname] ziel_vname ] coder -e [-n] [-c code64] [ quell_datei [ziel_datei]] coder -d [-s] [-c code64] [[quell_datei] ziel_datei ] coder -ue [ quell_datei ] ziel_datei_eintrag (uuencode) coder -ud [-s] [ quell_datei ] (uudecode) coder -A|-C[#] BESCHREIBUNG Das Kommando coder wandelt jeden beliebigen Dateiinhalt in einen Text um und kann solche Kodierungen wieder dekodieren. Bei der Umwandlung in eine Textform wird ein reduzierter Zeichensatz aus nur 64 verschiedenen Zeichen verwendet - anstatt 256. Daher sind solchermaßen entstandene Text-Dateien um etwa 33-35% größer als die Quelldateien. Die 64 Zeichen werden der aus 95 Zeichen bestehenden Zeichenmenge von ' ' (Space) bis '~' (Tilde) entnommen (ASCII). Voreingestellt sind zwei bestimmte Verteilungen: uuencode/uudecode (UNIX) und eMail-Standard. Bei Auswahl 'Standard' können die 64 Zeichen individuell festgelegt werden, wodurch ein brauchbarer Verschlüsselungs-Effekt entsteht! Der Algorithmus wird 'base64' genannt. Der Zeichensatz ist : "A..Za..z0..9+/" Zeichensatz uuencode: " !.._" Das sind in beiden Fällen 64 Zeichen ('..' entspricht 'bis'). Anhang-Dateien zu eMails sind in den Mail-Ordnern in einer typischen Text-Kodierung gespeichert, wie coder sie verarbeiten kann. coder kann verwendet werden, falls ein Mail-Programm eine bestimmte Kodierung nicht beherrscht oder aus irgendwelchen Gründen nicht vornimmt. coder kann auch dabei helfen, Mail-Ordner auf ein anderes Mail-Programm zu transferieren. coder berücksichtigt die folgenden Kommandozeilen-Optionen: ------------------------------------------------------------ -e Es wird kodiert (encode). -d Es wird dekodiert (decode). Entweder -e oder aber -d muß angegeben werden. -u Arbeitsweise und Zeichensatz wie bei den Unix-Kommandos uuencode bzw. uudecode. -s Ausgabe erfolgt (explizit) auf die Standard-Ausgabe (Handle 1). Nur bei -d (decode) verwendbar. -n Ausgabe von Zeilenvorschüben wird unterdrückt. Dies kann bei Verschlüsselung sinnvoll sein. (Bei -e, nicht bei -u, wirkt nicht bei Bildschirm-Ausgabe) -v Anstelle von Dateinamen werden Variablennamen angegeben. Nicht gemeinsam mit -u verwendbar. Variableninhalte dürfen bis zu nnn MB groß sein. -c Das Argument nach dieser Option muß eine Zeichenkette aus 64 Zeichen sein. Damit wird ein selbstgewählter Zeichensatz für den Algorithmus angegeben. -A Die Zeichenmenge 'Space bis Tilde' wird angezeigt (außer '='). -C# Es werden 16 Zeichenketten, je 64 Zeichen, ausgegeben, die zur Verwendung als 'code64' (Schlüssel) geeignet sind. Niemals wird eine Zeichenkette wiederholt. Wird eine Dezimalzahl # angegeben, gilt diese Anzahl statt 16. Die Optionen (außer -c) dürfen beliebig angeordnet werden. Ohne Option -u: Bei Funktionswahl 'Standard' werden zwei angegebene Dateien als Quelle und Ziel verwendet. Bei einer angebenen Datei gibt es einen unterschiedlichen Vorzug, je nach Option -e oder -d. Und zwar gilt bei -e die Datei als Quelle, bei -d als Ziel; weil binäre Daten vorzugsweise in eine Datei gelangen sollten und nicht auf den Bildschirm (oder von der Tastatur). Ohne Dateiangabe gelten i.d.R. Handle 0/1 als Ein-/Ausgabe, man sollte dabei nötigenfalls Umlenkungen (<>|) anwenden. Mit Option -u: uuencode/uudecode lesen von der Standard-Eingabe (Handle 0), falls quell_datei fehlt. Ausgabe uuencode erfolgt immer auf Handle 1. Ausgabe uudecode erfolgt nur per -s auf Handle 1, andernfalls: siehe unten. uuencode erzeugt einen Text folgendermaßen: begin file_mode ziel_datei_eintrag ............................................... ............................................... ............................................... ................................ _ end | Der Datei-Eintrag wird von uudecode verwendet, wenn Option -s nicht angegeben wird. uudecode verlangt diese Form mit Kopf- und Fußzeile. Vor der Kopfzeile darf beliebiger Text (ohne Kopfzeile) und nach der Fußzeile dürfen beliebige Daten stehen. coder ohne Option -u erzeugt einen Text folgendermaßen: ............................................... ............................................... ............................................... ................................ | Leerzeilen werden beim Dekodieren ignoriert. Bei Eingabe von der Tastatur (z.B. 'coder -e') kann mit <Ctrl+Z> beendet werden. (Unix: ^D) Falls dabei <Enter> vor ^Z eingegeben wird, werden die zwei (Unix: eins) Zeichen des Zeilenvorschubs (\r\n) auch kodiert. coder als Verschlüsselungs-Programm: ------------------------------------ Per Option -c müssen 64 Zeichen angegeben werden. Die 64 Zeichen dürfen und sollen natürlich in völlig beliebiger Reihenfolge angegeben werden, also: Verteilung UND Vertauschung. Wichtig ist eine möglichst vielfache VERTAUSCHUNG! Jede verschiedene Angabe erzeugt eine verschiedene Kodierung. Es können mehrere Stufen hintereinandergeschaltet werden, was die Datenmenge jedesmal vergrößert. Option -A zeigt die erlaubte Zeichenmenge. Kein Zeichen darf doppelt vorkommen. Das Zeichen '=' darf nicht vorkommen. Beispiele: Telefonnummer vierfach kodiert: 0522284540 MDUyMjI4NDU0MA== TURVeU1qSTRORFUwTUE9PQ== VFVSVmVVMXFTVFJPUkZVd1RVRTlQUT09 VkZWU1ZtVlZNWEZUVkZKUFVrWlZkMVJWUlRsUVVUMDk= Dies wurde allerdings mit -immer dem gleichen- eingebauten Zeichensatz (mit -n) gemacht! 0522284540 #b5A#}"D1b5s#w== zLz{*%@oz-*,jk4bzWcoi*== va\;vZ-(+C~;}.-^Q2^UR$y|R@~yA]U~ Q.OH8($"hMfK>(&!<M&Vp,g%p,4M#@,n62:/76OQ4p&= 815n12<4}*}4;^VPn%<o6;9(}LV.P_|L|*.\;1(AP_RX/v4a(QVn8;:.}v\= Bei vorstehender Kodierung wurden nacheinander fünf verschiedene Schlüssel von Option -C her verwendet. 11111111111111111111111 5+I}5+I}5+I}5+I}5+I}5+I}5+I}5+I= [hu0U+b-h1tCBtL`[hu0U+b-h1tCBtL`[hu0U+b-h+t= S|WC5Fb-k.CT51\(fn\5kFuTV+;vB|xuA(Ftft0t+@;EAgb~vhu.^SJ-V(t= Vorstehend ist erkennbar, daß trotz Verwendung des immer gleichen Schlüssels, die Gleichartigkeit durch die dritte Stufe beseitigt ist. a a P^== `m== ?t<TZb== bGv`q*== rsvSZV*3r\p= 6d826)+H~Lu= ntUGJv3"%5U8eEVi 9A(V4tw+aLgeW6Oy *fP+Pb}0c>SD{+kA#k+Q~\== :e@D0;E8qJuBC&q>0W~.FP== a a i~== 6A== 78I}%n== 4X|+U-== Iej%?G>}k|o= ]Wn3t+*p^@`= /2>]n3e.x_HBrj%e (P[?H_oLJ#I*o\~$ E:46xCf:7(%fx$"S!cwe7V== YW#p:~P@p~qYy~3Bp-qRb.== Vier Verschlüsselungen von 'a' mit jeweils verschiedenen Schlüsseln. Das Anhängen von '=' wird vorgenommen, damit die Länge der kodierten Daten ohne Rest durch 4 teilbar ist. Eine Ausgabe per Option -C: w$>b!QBG"gje#16%VTRJ5-pq[K\O;r_H4o]}7@NMyl:{nfh~(/AYsvPCD,.x)m&t Z]l+B(OYzt&1s@vi*K%er4M>j.R~cV`H?uqk-g)Dd5!JU}y[T,"bQ{LW_m69aoNf 8Tn:/DC0YEA}zOFS+c.*B3_|R9Q&#XvGkI>]a(2$-yfW^pVbN\Z1U?@L6t;eq~,u D:s~gO_@R#1hiX83>\Mb64rp5$"GHQ7<fBUN2,.}|W9KxVm?E*%TSFy(&wc!n`/P AN*2{k_)6}BP/([nC:1;8m^]"V?,|U`O<Z%vjLoe4q+Fc-#a.9HQ\lX&R5@GEiIu eI0bjQ4rX,&%w^pZq)cW]+9u*D:56y@Gls[Jxv$>"_B7k?#m~Y!{;`PK1LAS}T-F L.Y}5?/Vt[EJq2#a"4UOwc\s%0v9x3pI~^PhkTeGRCAzyjBM<>@*:1HbD`d8)n!K <vIWYtxBasc*Pzuw>_-eA)o9l~4y!nFE6$(.DS\mph"{1VqLM]J2}+Zr`[GKikb; XP)S},83/l^inAs2O%+;{EBqygL\[7jFeh$Qp"M|]9<U@w*IrbC>61z!?~#uVt&a 0[E5]HC92uYjB<s&RZlv6Uzk\/ct*,)g-4M`xya^InQd1~p+7}e$T8A#hr%3iD:X }tV/k1fH_w,S7Eu@U4o#ih\)Tp2gI"B*ARynMZ{Cje[.c?zs>30Fl`^WQd5ND$aL D;](IF@gx0B^5[iQf\h+bvS1k:AEdV{UJW.paLrnTN$-lu6s~}H/tC|q,y4)j`2M vcW/m^>*Llk7\JU.!syN|C%1Ep[VP#,qaz`ifA{do3XgB&$I)n69-Q0H_tu;+F]5 ]Lxz`3t0~jN<XlDe!4K,JvU?IG%W{pr&:ZH86V5@>1kTSnPds/2Bb(;"C#.oAiwQ 1V\&ERnU.,@~KM#(i3pz|4y5o_xlT%[jPYb/w9ACJXH<?h}vL^6De8;r)t!c2kWB [+Y9Z7zE`$T]m^eru%1O&#CnVliqN(g6WP!oUG:>sh?*MSX}DaA~8cy0_\KJ<j54 Leerzeichen, = und ' werden ausgefiltert. Es wird niemals eine Zeichenkette wiederholt werden, da diese Schlüssel durch den 'Spritz'-Random-Algorithmus generiert werden. Diese Kodierung mit dem bekannten Algorithmus base64 ist natürlich ohne Angabe von '-c schlüssel64' keine wirksame Verschlüsselung! Wenn sich in der Quelle hinten ein Zeichen ändert, ändert sich meistens auch nur ein Zeichen hinten bei der verschlüsselten Ausgabe. Aber durch Hintereinanderschaltung mit jeweils verschiedenen Schlüsseln wird es doch eine wirksame Verschlüsselung: o Außer den abgesprochenen Anwendern kennt niemand die Schlüssel. o Niemand sonst kennt die Quelle und deren Länge. o Niemand sonst kennt die Anzahl der Verschlüsselungsschritte. o Bis auf die letzte Rückwandlung ergibt sich stets unlesbarer Text. o Eine Dekodierung mit anderen als den originalen Schlüsseln in der richtigen Reihenfolge führt oft zum Abbruch des 'coder', weil oft illegale Werte außerhalb des korrekten Zeichensatzes entstehen. Der Schlüssel paßt dann nicht zum zu dekodierenden Text. Der 'coder' kann also zum Codebrechen nicht benutzt werden. o Falls ein Schlüssel gefunden wurde, der zum Text paßt, dann ist die richtige Reihenfolge der Zeichen noch gar nicht bekannt. o Falls tatsächlich ein verwendeter Schlüssel herausgefunden wird, so ist es nicht erkennbar, daß dies so ist. Mit einem Kommunikationspartner können auch verschlüsselte Schlüssel ausgetauscht werden. Nur ganz zu Anfang muß eine sichere Übergabe stattfinden. WARNUNGEN Bei Angabe von Code-Zeichen per Option -c sollte kein Zeichen (später intern) doppelt vorhanden sein, es kann sonst nicht eindeutig zurück-dekodiert werden! In einem solchen Fall erfolgt ein Warnhinweis. Bei Kodierung/Dekodierung muß natürlich der gleiche Schlüssel verwendet werden. HINWEISE coder als Verschlüsselungs-Programm: Der coder sollte keinesfalls als einzige Stufe verschlüsseln! Mindestens eine starke Verschlüsselung oder zwei coder-Stufen sollten unter einer abschließenden coder-Stufe liegen. Der stärkste Verschlüsselungseffekt entsteht grundsätzlich durch die Hintereinanderschaltung von unterschiedlichen Algorithmen. Das bildet eine Barriere und vernebelt BruteForce-Versuche. Der offizielle Zeichensatz für 'base64' ist: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ Index 0 bis 63. Da lag es nahe, eigene als Kodierungs-Schlüssel zu verwenden: w='D;](IF@gx0B^5[iQf\h+bvS1k:AEdV{UJW.paLrnTN$-lu6s~}H/tC|q,y4)j`2M' conv -S w; echo "$w" #sortieren $()+,-./012456:;@ABCDEFHIJLMNQSTUVW[\]^`abdfghijklnpqrstuvxy{|}~ Durch hintereinander geschaltete solche Verschlüsselungen entsteht eine sichere, praktisch nicht brechbare Verschlüsselung. .*.***..**.*.***.*.****..***.*.******.*.**.*.**.**.*.***.*.* Der interne Zeichensatz stellt sich wie vorstehend dar. Er wird vom Schlüssel generiert und ist dessen Abbild. Falls beim Dekodieren wegen eines unpassenden Schlüssels ein Zeichen '.' getroffen wird, beendet das Kommando wegen Fehlers. Andernfalls wird meist ein falscher '*' getroffen, wodurch das Kommando stumm unpassend dekodiert. Dieser unpassende Inhalt paßt nun nicht mehr zu einem korrekten nächsten Schlüssel! 1 -------------------------T----L--------------------------------- 2 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 3 -------------------------L----T--------------------------------- 4 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdyg§hijklmnopqrstuvwxyf0123456789+/ ^^^ ^ Zeile 2 wurde nach Verschlüsselung mit 1 mit einem gefälschten Schlüssel (3) entschlüsselt. Das Resultat ist Zeile 4. Das Resultat enthält insgesamt vier verschobene und neue Zeichen. Im Schlüssel wurden nur zwei Zeichen untereinander getauscht. Also nur ein Swap! Zeichen im Wert verändern führte in jedem Fall zu einem Abbruch des Kommandos wegen Fehler. Das neue Zeichen § führt als Dateiinhalt ebenfalls zum Abbruch. Es ist zu beachten, daß es sich nicht nur um ein Zeichen-Mapping handelt, sondern auch um eine Umsetzung von vier Bit-Feldern mit je 6 Bit in drei Byte mit je 8 Bit - beides mit 24 Bit. 64 Zeichen aus einer Gesamtmenge von 95 Zeichen. Kombinationslehre: 'n über k' = (n)(k) ; x! = 'Fakultät von x' (95)(64) = 9,9e24 = 9900000000000000000000000 So oft können also 64 Zeichen verschieden in 95 verteilt werden. Verteilung OHNE Rücksicht auf die Reihenfolge (mit Vertauschungen): [(95)(64)]*64! = 1,256e114 ; 64! = 1,27e89 Durch Hintereinanderschaltung von Kodierungen können (maximal) die Exponenten pro Stufe erhöht (verdoppelt) werden. Obwohl die Verschlüsselungs-Effektivität gering ist, im Vergleich zu z.B. einer kryptologischen Stromverschlüsselung wie Rabbit, muß doch der angegebene Schlüssel korrekt sein, um erfolgreich zu entschlüsseln! Es gibt hier zunächst 95^64 = 3,75e126 verschiedene Schlüssel. Da kein Zeichen doppelt oder häufiger vorkommen darf, gilt der Wert von oben: 1,256e114. Bei drei Verschlüsselungen hintereinander mit drei verschiedenen Schlüsseln sind es 1,256e114^3 = 1,98e342 verschiedene Gesamt-Schlüssel. Bei der Annahme von 30 ns Zeitbedarf pro Schlüsselwort-Versuch dauerte eine BruteForce-Aktion 1,9e327 Jahre, falls der richtige Schlüssel erst ganz zum Schluß gefunden würde. Die Verschlüsselung von coder ist natürlich ein Nebeneffekt! Zum besseren Umgang kann man SET und/oder DOSKEY zu Hilfe nehmen, noch besser ist ein 'richtiges' Shell-Programm, wie 'bish.exe'. Ein Test-Skript: set -f array 0 15 code $(coder -C16) z0=a for n from 0 by 1 to 15 repeat do array C=code n zn=z$((n+1)) coder -env -c "$C" z$n $zn print -r "$n: ${{zn}}" done z16="${{zn}}" for n from 15 by -1 to 0 repeat do array C=code n zn=z$((n+1)) coder -dnv -c "$C" $zn z$n yn=z$n print -r "$n: ${{yn}}" done DIAGNOSE Fehlermeldungen zur Standard-Fehlerausgabe. EXIT-CODE 0 Kein Fehler 1 Fehlerhafte Argumentliste 2 Dateiöffnen fehlgeschlagen 3 Fehler beim Dateilesen 4 Falsche/Fehlposititionierte Zeichen in Code-Datei >0 Sonstige Fehler SIEHE AUCH uuencode(UNIX), uudecode(UNIX), mpack(), munpack(), bish(K). AUTOR Das Kommando coder wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1998-2016 |
man(K) man(K) NAME man.exe - Zeigt Beschreibungen (Manual Pages) SYNTAX man [rubrikbuchstabe] titel BESCHREIBUNG Das Kommando man sucht aus einer Ansammlung von Dateien eine zu den Kommandozeilen-Argumenten bzw. zum Titel-Argument passende heraus und präsentiert deren Inhalt mittels anderer Hilfskommandos. Die Dateinamen haben folgendes Format: <titel>.<mn><rubrikbuchstabe> <titel>.<me><rubrikbuchstabe> (english) Folgende Rubrikbuchstaben (Großbuchstaben!) sind derzeit zugeordnet: A Anfangs zu lesende Übersichten B Beispielhaftes D Datenblatt I Informationen K Kommando-Beschreibungen L Limits/Leistungswerte R Referenz S Kurzbeschreibungen T Tutorial V Vergleiche/Leistungsmerkmale Gültig sind alle Buchstaben von 'A' bis 'Z'. Die Dateien sind komprimiert, weshalb 'man' einen Entpacker einschaltet. Das zweite Hilfskommando ist ein wählbares Pager-Programm wie beispielsweise pg oder more. Dateien, die keinen speziellen Datei-Kopf für den Entpacker besitzen, werden von diesem unverändert durchgeschleust. Rubrikbuchstaben werden verarbeitet, weil damit trotz gleicher Titel eine Unterscheidung getroffen werden kann. Wenn kein Rubrikbuchstabe angegeben wird, durchsucht 'man' alle Rubriken, sonst nur die angegebene. Nur ein gültiger Rubrikbuchstabe wird als solcher interpretiert. Andernfalls wird nach ihm ein Titel gesucht. Ein zweites Argument ist nur erlaubt, wenn das erste eine gültige Rubrik ist. In diesem Fall muß ein zweites Argument als Titel angegeben werden. man berücksichtigt folgende Umgebungsvariablen (Environment): MANTEMP, TEMP, TMP, TEMPDIR und TMPDIR in der angegebenen Reihenfolge, zur Angabe eines Verzeichnisses für temporäre Dateien. Standardverzeichnis ist das aktuelle Verzeichnis. MANFILES Zur Angabe eines Verzeichnisses für die gepackten man-Dateien. Standardverzeichnis ist das aktuelle Verzeichnis. MANRUBRIK Um die Suchreihenfolge festzulegen: MANRUBRIK=KIABCDE... Voreingestellt ist ABCDE...XYZ . MANPAGER, PAGER Zur Angabe des Namens eines Pager-Programms. Optionsargumente können zusätzlich angegeben werden. Standardaufruf ist `pg -n' . Wird das Umlenkungszeichen `<' angegeben, wird dem ausgewählten Pager-Programm kein Dateiname als Argument übergeben, sondern die (temporäre) Datei wird geöffnet und mit der Standardeingabe verknüpft. Um DOS-more zu benutzen, muß eine dieser Env-Variablen auf `"more<"' gesetzt werden, weil dieses Kommando nur per Umlenkung arbeitet und nur von der Standardeingabe lesen kann. MANAUTOR Um die Autoren-Meldung zu unterdrücken: MANAUTOR=H.Schellong,Vlotho MANPROGRAM Um die Freeware-Meldung zu unterdrücken: MANPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (MANAUTOR muß hierfür auch gesetzt sein.) HINWEISE Falls MANRUBRIK auf einen bestimmten Inhalt gesetzt ist, sucht das man-Kommando ausschließlich nach den hier angegebenen Rubriken. Eine beim Kommandoaufruf angegebene Rubrik hat stets Vorrang. Bei Beendigung des Programms erfolgen gegebenenfalls Hinweise auf gleichnamige Manual-Dateien anderer Rubriken. BEISPIELE man man man pg man R regexp > datei EXIT-CODE 0 Kein Fehler aufgetreten. 1 Allgemeiner Fehler (Argumente, falsche Datei, etc.) 2 Wenn eine Systemfunktion einen Fehler meldete. AUTOR Dieses Programm man wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
xregexp® xregexp® NAME xregexp - Definition der Schreibweise sogenannter Regulärer Ausdrücke (regular expressions) BESCHREIBUNG Ein Regulärer Ausdruck ist ein Mechanismus zur Feststellung der Position einer ganz bestimmten Zeichenfolge oder um ein solches Muster gezielt zu manipulieren. Dieser Mechanismus wird von vielen Hilfsprogrammen unterstützt. Zeichenmustervergleich wird von Shell- und anderen Programmen zur Verfügung gestellt, hauptsächlich zur Dateinamen-Expansion. Diese Beschreibung xregexp® umfaßt Reguläre Ausdrücke in einer Ausprägung, die den Gipfelpunkt in diesem Bereich darstellt, nämlich XRE, im Unterschied zu BRE und ERE, die von IEEE/POSIX beschrieben werden. Wildcards(DOS), Wildcards(UNIX), BRE, ERE, XRE sind die bekannten Mechanismen mit aufsteigender Komplexität. Nachfolgend eine kleine Übersicht von speziellen Zeichen und Zeichenfolgen, zur Einordnung der Komplexität: DOS * ? UNIX * ? [! ] BRE . [^ ] * \{ \} \( \) \1 ^ $ ERE . [^ ] * + ? { } ( ) | ^ $ XRE sprengt hier den Rahmen, siehe unten (Etwa 20-fach komplexer als ERE) Es beginnt einfachst mit dem Zeichen *, das für beliebig viele beliebige Zeichen steht, bei der Dateinamen-Expansion. Ab den BRE repräsentiert * keine Zeichen, sondern ist nur noch ein Element, welches eine Anzahl angibt. Es erfolgt eine Trennung: Die Zeichenfolge .* entspricht nun *, wobei . für ein beliebiges Zeichen und * für eine Anzahl zwischen Null und Unendlich steht. Nachfolgend werden die XRE beschrieben. Der 'Reguläre Ausdruck' wird zu RA gekürzt. Die zu untersuchenden Daten, auf die der RA angewendet wird, werden als DATEN bezeichnet. Sogenannte 'Regex Engines' sind: JGsoft .NET Java Perl PCRE PCRE2 PHP Delphi R JavaScript VBScript XRegExp Python Ruby Tcl 'POSIX BRE/ERE IEEE Std 1003.1' 'GNU BRE/ERE' Oracle XML XPath Webseite: http://www.regular-expressions.info/tutorial.html Einige enthalten keine eigenständige Regex-Software, sondern verwenden Funktions-Bibliotheken, beispielsweise die Bibliothek PCRE. Die Syntax der bish-XRE folgt der mehrheitlichen oder optimalsten Syntax der vorstehend genannten RE-Maschinen. Die RE-Maschinen zeigen ein großes Durcheinander hinsichtlich der Syntax, besonders bei der Substitutions-Syntax. Bei den bish-XRE wurde darauf geachtet, zumindest homogene Linien zu verfolgen. BESONDERHEITEN Eindeutigkeit und Sicherheit Es wurden automatisch wechselnde Spezialbedeutungen weitgehend vermieden. Das Maskierzeichen ist nur innerhalb von definierten Zeichenfolgen erlaubt. Es herrscht weitestgehend Striktheit und Eindeutigkeit. Für die XRE sind mehr als 50 Fehlermeldungen implementiert. Rein Binäres Konzept Ein RA darf direkt Zeichen (Bytes) mit den Werten 1 bis 255 enthalten. Indirekt können alle Werte 0 bis 255 durch Umwandlung in den kompilierten RA eingefügt werden. Die DATEN können in einer bish-Variablen enthalten sein, die Millionen von Bytes mit allen Werten von 0 bis 255 enthalten kann. Es gibt kein Zeilenende bei der bish-XRE, sondern nur einen Pufferbeginn und ein Pufferende hinsichtlich der DATEN, die auch nicht null-terminiert sind. Die bish(K) bietet einen sehr guten Rahmen für den Umgang mit RA. Deren interne Kommandos grep(K) und expr(K) verwenden BRE und XRE. Die Programmierbarkeit der bish potenziert noch die Leistung der XRE. Es können binäre Datenstrukturen bis zu einer Größe von mehreren hundert Millionen Bytes untersucht und Ersetzungen darin vorgenommen werden. Solche Strukturen können auch generiert werden. Sophisticated Die RA der bish-XRE können in beiden Richtungen abgearbeitet werden. Das hat beträchtliche Vorteile bei 'Lookbehind'-Konstruktionen. Von den 22 oben genannten RE-Maschinen besitzen nur JGsoft und .NET diese Fähigkeit. Nun gesellt sich die bish-XRE hinzu. Performance Die bish(K) ist das schnellste Shell-Programm. Ebenso werden deren XRE-RA sehr schnell verarbeitet. DATEN RA 01234567890123456789abcggdefgdedeffkz abc(g+(de){1,2}f+){0,2}k abcggdefgdedeffkz abc(g+(de){1,2}f+){0,2}k Der vorstehende RA benötigt 310/270 ns auf einem Core2 Duo 3333 (2007). Matches: abc(ggdefg(dede)ff)k Konfigurierbarkeit Siehe nachfolgend die vollkommene Einstellbarkeit aller Zeichen mit Spezialbedeutung. SAMMLUNG SPEZIELLER ZEICHENFOLGEN % %% \ \\ . [ * + ? { ( ) | < > ^ $ a* a+ a? a{m,n} a*? a+? a?? a{m,n}? a*+ a++ a?+ a{m,n}+ a{m,} a{m} a{0..4294967295,0..4294967295} a:= a . ( ) [ ] # \Q \E \p{Lx} (37) \P{Lx} (37) \Z \z \, \g<name> \g'name' \g{name} \k<name> \k'name' \k{name} \g<zahl> \g'zahl' \g{zahl} \k<zahl> \k'zahl' \k{zahl} \g<-zahl> \g'-zahl' \g{-zahl} \k<+zahl> \k'+zahl' \k{+zahl} \K \G \b \B \0 \1 \2 \3 \4 \5 \6 \7 \8 \9 \cA..\cZ \ca..\cz \c0..\c9 \e \t \r \n \v \f \d{zahl} \o{zahl} \x{zahl} \u{zahl} \s \d \x \o \w \h \a \l \u 82 vordef. Z.k. \S \D \X \O \W \H \A \L \U \N [:alnum:] [:alpha:] [:blank:] [:cntrl:] [:digit:] [:graph:] [:lower:] [:print:] [:punct:] [:space:] [:upper:] [:xdigit:] [:ascii:] [:word:] [a-z-[aeiou]] [^a-z-[a-z-[^xx]]] [0-9&&[0-6&&[4-9]]] (...) (?<name>...) (?:...) (?|...) (?>...) (?=...) (?!...) (?<=...) (?<!...) (?#...) (?imnsxb-inmsxb) (?^inmsxb) (?imn:...) (?R) (?0) (?1) (?-1) (?+1) (?&name) (?(DEFINE)(...)) (?(name)then|else) (?(zahl)then) (?(expr)then|else) (?<name1-name2>expr) (?<-name2>expr) $nummer ${name} ${*abc*123} ${$name} $$ $& $` $' $_ $U $L $E $I $F $t $r $n ------------------------------------------------------------------- Vorstehend eine sehr kompakte Zusammenfassung, die bei vorhandenen Kenntnissen einen sehr schnellen Überblick zu den implementierten Merkmalen erlaubt. Es ist erkennbar, daß dies die hochstehendste Kategorie Regulärer Ausdrücke ist, mit großem Abstand sogar zu den ERE. ZEICHEN MIT SPEZIALBEDEUTUNG Generelles Maskierzeichen Prozentzeichen % Backslash \ Das Maskierzeichen ist wählbar durch die bish-Option '-B' und das bish-Kommando 'set -B' bzw. 'set +B'. Voreingestellt ist '%'. Angabe von '-B' wählt '\' und '+B' selektiert '%'. Das Maskierzeichen kann außerdem im RA selbst mittels Optionen-Syntax (?b) gewählt werden. Ein einem Spezialzeichen vorangestelltes Maskierzeichen hebt die Spezialbedeutung des Spezialzeichens auf und macht es zu einem gewöhnlichen Zeichen. (Falls nicht gegensätzlich definiert.) Das Maskierzeichen 'verbraucht' sich dadurch; eine Folge \* wird zu einem gewöhnlichen Zeichen *. Es ist ein Fehler, wenn das nachfolgende \Zeichen keine Spezialbedeutung hat. Das Maskierzeichen selbst wird durch '\\' oder '%%' zu einem gewöhnlichen Zeichen \ oder %. Die Maske % ist unter DOS/Windows und UNIX unproblematisch. Die Maske \ ist unter DOS/Windows problematisch, allerdings optisch vorteilhafter. Spezialzeichen . [ * + ? { ( ) | < > ^ $ Viele der vorstehenden Zeichen bilden den Beginn einer definierten speziellen Zeichenfolge. Nachfolgende Zeichen, die dadurch Spezialbedeutung erhalten oder bereits haben, sind oft optional. Für jedes der Spezialzeichen ist konfigurierbar, ob es ohne oder mit dem Maskierzeichen (% \) Spezialbedeutung haben soll: set -XRE='<>' < und > sollen als \< und \> speziell sein. set -XRE= kein Zeichen soll mit \ speziell sein; set -XRE= alle Zeichen sollen ohne \ speziell sein. set -XRE zeigt alle Zeichen, mit oder ohne Maskierzeichen. Voreingestellt ist: $()*+.\<\>?[^{| Für alle hinter XRE= angegebenen Zeichen aus der oben definierten Menge wird definiert, daß sie nur gemeinsam mit einem vorangestellten Maskierzeichen speziell sind. Für alle nicht angegebenen Zeichen aus der oben definierten Menge wird definiert, daß sie nur ohne vorangestelltes Maskierzeichen speziell sind. BEDEUTUNGSGRUPPEN Leere Zeichenketten Ein leerer RA '' paßt zu jeglichen DATEN, logischerweise auch zu leeren DATEN ''. '' '^$' '^' '$' passen jeweils zu leeren DATEN ''. Gewöhnliche Zeichen Jedes einzelne Zeichen, das keine Spezialbedeutung hat, ist ein gewöhnliches Zeichen, sofern keine spezielle Bedeutung durch den Kontext entsteht. Ein gewöhnliches Zeichen ist bereits ein RA. Ein Spezialzeichen wird zu einem gewöhnlichen Zeichen durch Voranstellen des Maskierzeichens. Ein Spezialzeichen, das nur durch Voranstellen des Maskierzeichens speziell ist, wird durch Weglassen des Maskierzeichens zu einem gewöhnlichen Zeichen. Die Sequenzen \r \n (beispielsweise) repräsentieren jeweils ein gewöhnliches Zeichen. Ebenso die Zeichenklasse \w. Spezialzeichen Ein Spezialzeichen kann einzeln einen RA bilden. Einige Spezialzeichen sind ohne bestimmte Zeichenfolgen davor oder dahinter ein Fehler. DATEN RA a \< paßt 4 \< paßt nicht 4 * ist ein Fehler 4 \* paßt nicht Spezielle Zeichenfolgen In einer vorstehenden Sektion sind viele Darstellungen enthalten. Ein großer Anteil davon wird durch das Maskierzeichen eingeleitet und von einem unmittelbar folgenden Buchstaben beendet. Ein oder mehr Zeichen hinter dem Maskierzeichen sind im Regelfall einzeln und ohne das führende Maskierzeichen gewöhnliche Zeichen. Im ersten Schritt bildet das Maskierzeichen mit einem direkt folgenden Zeichen eine Folge mit einer ganz bestimmten Bedeutung. Danach können beispielsweise zwanzig weitere Zeichen folgen, die wiederum in diesem Kontext ganz bestimmte Bedeutungen aufweisen. Weitere spezielle Zeichenfolgen werden nicht durch das Maskierzeichen begonnen, sondern durch ein anderes Spezialzeichen, nämlich durch die eigentlichen RA-Symbole. Zeichenrepräsentanten Zeichen und andere Syntaxkonstruktionen, die im RA für ein Zeichen aus den DATEN stehen, sind: a Gewöhnliches Zeichen (s.o.) . Paßt zu jedem Zeichen (Byte) in den DATEN [ ] Zeichenklasse (auch \d \w ...) Es gibt tatsächlich nur diese drei Repräsentanten. Der Punkt paßt im SingleLine-Modus zu jedem Zeichen. Es sind sehr viele vordefinierte Zeichenklassen vorhanden. Gruppen ( ) Standard-Gruppe (speichernd/capturing) (?: ) Gruppe, explizit nicht speichernd Innerhalb der BRE ist ( ) keine Gruppe, sondern die beiden Zeichen sind lediglich Positionsspeicher-Symbole. Letzteres gilt bei den XRE ebenfalls, jedoch können allen oder einigen Elementen zwischen ( ) bestimmte Eigenschaften zugewiesen werden. Insbesondere sind Gruppen quantifizierbar. Innerhalb der Gruppen können beliebig Zeichenrepräsentanten und andere Syntaxelemente angeordnet werden. Quantifizierer SYNTAX MIN MAX BEISPIEL HINWEIS ohne 1 1 a possessiv * 0 unendlich a* + 1 unendlich .+ ? 0 1 [ ]? {m,n} m n a{2,8} {m,} m unendlich ( ){6,} {m} m m ( ){5} possessiv {m,m} m m ( ){5,5} possessiv m,n = 0 .. 4294967295 ; unendlich = 4294967295 Quantifizierer geben an, wie viele Zeichen oder Zeichengruppen aus den DATEN jeweils mindestens und maximal repräsentiert werden sollen. Bei Zeichen gilt N bzw. N*1. Bei Gruppen gilt nicht N*L, sondern L1+L2+L3+..+Ln. Jede Wiederholung einer Gruppe kann folglich eine unterschiedliche Anzahl von Zeichen in den DATEN überspannen! Die possessiv-Kennzeichnung hier zeigt implizite Possessivität. Wiederholungsverhalten (Qualifizierung) SYNTAX BEGRIFF ERKLÄRUNG BEISPIEL greedy (gefräßig) (ohne Syntax) a+ ? lazy (faul) a*? + possessive (possessiv/besitzbeanspruchend) a{4,6}+ Das verhaltenssteuernde Zeichen wird jeweils hinter dem Quantifizierer angegeben. Diese Verhaltensweisen haben viel mit der grundlegenden Arbeitsweise von RA zu tun: Von links nach rechts - und dabei gefräßig. Das Verhalten 'greedy' liegt auch in BRE und ERE vor. 'greedy' und 'lazy' sind Geschwister, während 'possessive' davon abgesetzt ist. Eine RA-Einheit (z.B. a+) versucht 'greedy', so viele Zeichen aus den DATEN zu überspannen, wie möglich. Danach gibt sie im Interesse der nachfolgenden Einheit so viele Zeichen an diese ab, bis sie und auch die nachfolgende Einheit passen, sofern das im gesamten Bereich der abgebbaren Zeichen möglich ist. Dies kann als ziemlich aufwendiges Justieren bezeichnet werden. Eine 'lazy'-Einheit (z.B. a+?) gibt zu Anfang alle ihre abgebbaren Zeichen ab, und justiert nachfolgend aufsteigend, bis beide passen, im Rahmen der abgebbaren Zeichen. RA DATEN MATCH (b+)(b+) abbbbc (bbb)(b) (b+?)(b+) abbbbc (b)(bbb) 2(nd)? a2ndc 2nd 2(nd)?? a2ndc 2 <.+> <b>bold</b> <b>bold</b> <.+?> <b>bold</b> <b> \b.*[\d]{4}\b 1995 2015 1995 2015 \b.*?[\d]{4}\b 1995 2015 1995 Eine 'possessive'-Einheit (z.B. a++) hingegen justiert überhaupt nicht! Sie gibt nichts mehr von ihrem Passenden ab. Das erhöht die Verarbeitungsgeschwindigkeit. MIN,MAX: 1,1 m,m sind implizit possessiv (siehe oben). Verwendung von 'lazy' und 'possessive' kann dazu führen, daß ein RA im Unterschied zu 'greedy' nun paßt oder aber nicht mehr paßt, oder korrekt paßt. Anker SYNTAX ERKLÄRUNG ^ 'RA 'DATEN vorne verkoppelt $ RA' DATEN' hinten verkoppelt \Z RA' DATEN' hinten verkoppelt \z RA' DATEN' hinten verkoppelt ^ $ 'RA' 'DATEN' vorne und hinten verkoppelt Ein Anker bewirkt eine feste Verknüpfung der Anfangspunkte oder der Endpunkte von RA und DATEN. Der Anfang der DATEN muß zum Anfang des RA passen, bei Vorneverknüpfung, andernfalls passen die DATEN nicht zum RA. Vorneverknüpfung steigert die Verarbeitungsgeschwindigkeit: Normalerweise werden die DATEN aufsteigend zeichenweise abgefragt, dem RA jeweils zur Prüfung vorgelegt. Das entfällt bei Vorneverknüpfung. Es sollten die Anker ^ $ verwendet werden. Die weiteren Anker geben im Multiline-Modus ein anderes Verhalten. Dieser Modus ist jedoch nicht implementiert. Die Sequenz \A ist bei den XRE kein Anker, sondern eine Zeichenklasse. Die Anker sollen vorne beziehungsweise hinten positioniert werden. Kommentare können davor und im x-Modus auch dahinter stehen. Unter anderem deshalb haben die Anker nicht nur ganz am Anfang bzw. ganz am Ende Spezialbedeutung, sondern überall. '(?#co)(?x) ^a\,b $ #XC ' -- entspricht '^ab$' Anker können wie vorstehend positioniert werden. Kommentar, Optionsetzen und x-Modus ermöglichen hier eine Position, die normalerweise nicht gestattet ist. ZEICHENKLASSEN Grundlegende Syntax [abc] paßt zu a b c [^abc] paßt zu allen Zeichen, die nicht a b c sind [a-z] paßt zu a bis z, einschließlich [A-Za-z_0-9] paßt zu allen in Wörtern üblichen Zeichen []abc] paßt zu ] a b c []^abc] paßt zu ] a b c ^ [abc-] [-abc] paßt zu - a b c [a-e-z] paßt zu - a b c d e z []-abc] paßt zu ] a b c - [-a-c] paßt zu - a b c Die vorstehende Syntax ist üblich ab den BRE. Zwei Zeichen haben als erstes Zeichen Spezialbedeutung: Die schließende Klammer ] gilt an dieser Position als gewöhnliches Zeichen der Zeichensammlung. Das Circumflex ^ ist dort ein Invertierer. Das Minuszeichen verliert seine Bedeutung als Anzeiger eines Zeichenbereiches: vor und nach einem Zeichenbereich, oder am Anfang und am Ende der Zeichenklasse. Erweiterte Syntax XRE Zeichenklassen-Subtraktion -[ ] [a-z-[aeiou]] Selbstlaute werden subtrahiert (XRE) [b-df-hj-np-tv-z] Selbstlaute werden weggelassen (ERE) [\p{Po}-[\d{128}-\d{255}]] {Po} ohne die Zeichen ab 128 [\d{128}-\d{255}-[äöüßÄÖÜ]] Zeichen ab 128, ohne äöüßÄÖÜ [\w-[\x\l_]] entspricht [G-Z] [^A-Z-[a-z]] Invertierung hat Vorrang [^A-Z-[a-z]] entspricht [^A-Za-z] [^A-Z-[^a-z]] entspricht [a-z] Zeichenklassen-Intersektion && [abcdef&&c-euvx] paßt zu c d e (UND-Funktion) [1234&&23456&&0123] paßt zu 2 3 [abcdef&&[^c-e]] [ ] nur nötig für ^ Invertierung [a-z&&[^aeiou]] entspricht [a-z-[aeiou]] [^A-Z&&[aeiou]] Invertierung hat Vorrang Verschachtelung beliebig [a-z&&wjdh&&[^A-Z-[aeiou]&&hj]] paßt zu h j Das Maskierzeichen ist innerhalb von Zeichenklassen [ ] speziell. Eine Folge von zwei Maskierzeichen (\\ oder %%) resultiert zu einem Maskierzeichen als gewöhnliches Zeichen. Vordefinierte Zeichenklassen Nur innerhalb einer Zeichenklasse: [[:posix:]] Alle anderen vordefinierten Zeichen und shorthand-Zeichenklassen können insbesondere auch außerhalb von [ ] verwendet werden. SYNTAX ENTSPRICHT \s [ \t\r\n\f\v] \S [^ \t\r\n\f\v] \d [0-9] \D [^0-9] \x [0-9A-Fa-f] \X [^0-9A-Fa-f] \o [0-7] \O [^0-7] \w [0-9A-Za-z_] \W [^0-9A-Za-z_] \h [A-Za-z_] \H [^A-Za-z_] \a [A-Za-z] \A [^A-Za-z] \l [a-z] \L [^a-z] \u [A-Z] \U [^A-Z] \N [^\n] POSIX: (nur innerhalb einer Zeichenklasse: [[:posix:]]) [:alnum:] [A-Za-z0-9] [:alpha:] [A-Za-z] [:blank:] [ \t] [:cntrl:] 00-1F 7F [:print:] [ -~] [:graph:] [!-~] [:punct:] [!"#%&'*,./:;?@\_-()[]{}] [:space:] [ \t\r\n\f\v] [:lower:] [a-z] [:upper:] [A-Z] [:digit:] [0-9] [:xdigit:] [0-9A-Fa-f] [:ascii:] 0000-007F [:word:] [0-9A-Za-z_] UNICODE: \p{IsBasicLatin} 0000-007F \p{IsLatin-1Supplement} 0080-00FF \p{Lu} A-Z C0-DE \p{Ll} a-z B5 DF E0-FF \p{Lo} AA BA \p{L} Letter {Lu} {Ll} {Lo} \p{Nd} 0-9 \p{No} B2 B3 B9 BC BD BE \p{N} Number {Nd} {No} \p{Pc} _ \p{Pd} - \p{Ps} ( [ { \p{Pe} ) ] } \p{Pi} AB « \p{Pf} BB » \p{Po} ! " # % & ' * , . / : ; ? @ \ A1 A7 B6 B7 BF \p{P} Punctuation {Pc} {Pd} {Ps} {Pe} {Pi} {Pf} {Po} \p{Sm} + < = > | ~ AC B1 D7 F7 \p{Sc} $ A2-A5 \p{Sk} ^ ` A8 AF B4 B8 \p{So} A6 A9 AE B0 \p{S} Symbol {Sm} {Sc} {Sk} {So} \p{Zs} ' ' A0 \p{Z} Separator {Zs} \p{Cc} 00-1F 7F-9F \p{Cf} AD \p{C} Control {Cc} {Cf} UNICODE invertiert: \P{IsBasicLatin} \P{IsLatin-1Supplement} \P{Lu} ... \P{C} Vordefinierte Zeichen Alle vordefinierten Zeichen können auch außerhalb einer Zeichenklasse [ ] verwendet werden. \t Tab 9 \n NewLine 10 \v VTab 11 \f FormFeed 12 \r CarriageReturn 13 \e Escape 27 \cA \ca Control chars 1 \cB \cb 2 \cC \cc 3 \cD \cd 4 \cE \ce 5 \cF \cf 6 \cG \cg 7 \cH \ch 8 \cI \ci 9 \cJ \cj 10 \cK \ck 11 \cL \cl 12 \cM \cm 13 \cN \cn 14 \cO \co 15 \cP \cp 16 \cQ \cq 17 \cR \cr 18 \cS \cs 19 \cT \ct 20 \cU \cu 21 \cV \cv 22 \cW \cw 23 \cX \cx 24 \cY \cy 25 \cZ \cz Control chars 26 \c0 0 \c1 27 \c2 28 \c3 29 \c4 30 \c5 31 \c6 32 \c7 127 \c9 255 Frei definierbare Zeichenwerte Die nachfolgenden Umwandlungssequenzen können auch außerhalb einer Zeichenklasse [ ] verwendet werden. \d{255} dezimal 0-255 \o{377} oktal 0-255 \x{FF} hexadezimal 0-255 \u{00FF} hexadezimal 0-255 Es liegt hier ein Konflikt mit den vordefinierten Zeichenklassen \d \o \x \u vor. Und zwar innerhalb und außerhalb einer Zeichenklasse [ ]. Außerhalb von Zeichenklassen [ ] gibt es einen Konflikt mit dem Quantifizierer {m} {m,n}. Innerhalb einer Zeichenklasse [ ] ist lediglich eine konfliktfreie Abfolge der betroffenen Zeichen erforderlich, da die Reihenfolge hier fast keine Rolle spielt: {\d} oder }{\d oder ... Es muß nur dafür gesorgt werden, daß direkt nach \d kein { folgt. Außerhalb von Zeichenklassen [ ]: SPEZIELL (Quantifiz.) : { \{ Umwandlung wirksam : \d{123} \d{123} Quantifizierer wirksam: \d\,{123} \d\{123} dito : [\d]{123} [\d]\{123} Gewöhnliche Zeichen : \d\{123} \d\,{123} Die Sequenz \, ist eine Nulloperation (nop, no operation). In den letzten drei Zeilen wirkt \d als Zeichenklasse. Als Gewöhnliche Zeichen sind { 1 2 3 } gemeint. ALTERNATIVEN Alternativen-Listen sind die wichtigste Eigenschaft, die die ERE gegenüber den BRE aufweisen. AK(fold|falg|senti|lokal)_(63|84)s Es ist ein natürlicher Bedarf an diesem Ausstattungsmerkmal erkennbar. Wenn darüber nicht verfügt werden kann, müssen Auswege gesucht werden. Dazu kann die Programmierbarkeit eines Shell-Programms dienen. Das interne grep-Kommando der bish kann bis zu acht RA entgegennehmen, die ODER- oder UND-verknüpft werden können. AK(fold|(yo\w{3,6}|tv)q|senti|[lL]okal)_(63|(?&num))s Eine Alternativen-Liste kann hunderte Zeichenfolgen enthalten. Es gibt keine prinzipiellen Einschränkungen bei der Ausgestaltung der jeweiligen Zeichenfolge. Die erste passende Zeichenfolge von links nach rechts wird verwendet. RA DATEN MATCH (?(DEFINE)(69|70))a(d|(?1))v uxa70v a70v Prüfung von IP-Nummern: ^(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(?1)\.(?1)\.(?1)$ 192.168.64.101 Detailerklärungen siehe unten 'Subroutine Calls'. Parsen RA DATEN HINWEIS "[^"]*" "abc" (?-b)"([^"\]|\\|\")*+" "a\\bc\"" "([^"]|\")*+" "a\\bc\"" fehlerhaft "(\"|[^"])*+" "a\\bc\"" Meistens wird es so einfach gezeigt, wie im ersten Beispiel, jedoch das Parsen selbst einfachster Syntax-Konstruktionen ist selten ganz simpel. Das zweite Beispiel berücksichtigt wenigstens \\ und \" innerhalb einer String-"Konstante" (in C). Aber es gibt noch viel viel mehr. Das Maskierzeichen wurde zu % gewählt, weil in C als Kontrast \ gilt. Ohne diese Maßnahme müßte der RA so: "([^"\\]|\\\\|\\")*+" aussehen. Beim dritten Beispiel stiehlt die erste Alternative der zweiten Alternative das Zeichen \. Das vierte Beispiel ist korrekt, jedoch nicht maximal schnell, da meist die zweite Alternative passen muß. Die Alternativen der bish-XRE wurden auch aus den vorstehend erkennbaren Anlässen so konzipiert, wie sie konzipiert wurden, denn das gibt notwendige Steuerungsmöglichkeiten. GRUPPEN Standard-Gruppe RA DATEN (abcd+e) qqwoabcddddeimttuyy ^ ^ Die korrespondierenden Positionen beider Klammern in den DATEN werden gespeichert, sofern die angegebene Zeichenfolge in den DATEN vorkommt. Das sind hier die Positionen a und i, nicht a und e. Wenn es die erste speichernde Gruppe (capturing) im RA ist, wird die Referenznummer 1 zugewiesen. Von links nach rechts werden aufsteigende Nummern zugewiesen, alle speichernden Gruppen - jeweils die öffnende Klammer - betreffend. Nur diese und die nachfolgend beschriebene Gruppe speichern. Das Speichern dieser Gruppe kann per Option n deaktiviert werden. Mit Ausnahme der vier Lookaround-Gruppen können alle Gruppen der XRE beliebig quantifiziert werden! Bei gleichzeitiger Verschachtelung (abc(kw+){1,4}oi){0,6} ist allerdings eine Speicherung bei eingeschachtelten Gruppen weitgehend sinnlos. Benamte Gruppe (?<name>abcd+e) (?'name'abcd+e) Logischerweise ist dies ebenfalls eine speichernde Gruppe. Namensbildung: [A-Za-z_][A-Za-z_0-9]* Eine Referenznummer wird genau so wie bei der Standard-Gruppe zugewiesen. Zusätzlich kann man sich später durch Angabe des Namens auf eine benamte Gruppe beziehen. Die einleitende Zeichenfolge (? gilt für alle zusätzlichen Gruppen und sonstige Klammer(?konstruktionen) der XRE. Der Beginn (\? startete eine Standard-Gruppe, falls ? ohne Maske speziell ist! Die Zeichen < ' > haben hier nur eine Kontextbedeutung, wobei < und > ihre normale Spezialbedeutung verlieren! Nicht speichernde Gruppe (?:abcd+e) Dieser Gruppe wird keine Referenznummer zugewiesen. Eine weitere Bedeutung hat diese Gruppe nicht. Es ist quasi die Standard-Gruppe ohne Speicherung. Bei den BRE und ERE kann die Speicherung bei ( ) nicht abgewählt werden. Possessive Gruppe (?>abcd+e) possessiver Inhalt (?:abcd+e){2,5}+ nur außen possessiv Die Elemente dieser Gruppe werden possessiv qualifiziert. Diese Gruppe ist eigentlich nur sinnvoll, falls eine RE-Engine individuelle Possessivität nicht bietet. Die Qualifizierung findet in Einschachtelungen ( ) hierin nicht statt. Dieses nicht in die Tiefe gehen bietet Steuerungsmöglichkeiten an. Das letzte Beispiel stellt eine Gruppe dar, deren Inhalt nicht possessiv ist, die sich aber als Ganzes possessiv verhält. Verzweigungs-Rücksetz-Gruppe (?|(abc)|(def)|(ghi)) 1 1 1 Referenznummern (?|(abc)(ABC)|(def)|(ghi)) 1 2 1 1 Referenznummern 2 3 2 2 Referenznummern, mit zuvor ( ) (?|(s)|(f))\1 paßt zu ss und ff Diese Branch Reset Group wird durch (?| eingeleitet und speichert nicht. Falls diese Gruppe sinnvoll verwendet werden soll, sollte sie speichernde Gruppen nach dem vorstehenden Muster enthalten. Jede Alternative | setzt die Referenznummer auf denjenigen Wert zurück, der beim Eintritt in diese Gruppe vorlag. Egal, welche Alternative zutrifft - die Referenznummer ist voraussagbar. Beim letzten Beispiel ist der Referenzbezug \1 zu beachten. Bei benamten Gruppen innerhalb sollte der Name gleich sein für alle Gruppen, die die gleiche Referenznummer haben. Positive Look Ahead Gruppe RA DATEN MATCH (?=abcd+e) qt(?=ykj) abcqtykj qt qt(?=ykj)ykj abcqtykj qtykj Diese Gruppe überspannt keine Zeichen aus den DATEN! Im Englischen gibt es den Begriff 'Zero-Length Assertion' dazu. Die Leseposition in den DATEN wird bei Gruppenende zurückgesetzt, auf denjenigen Punkt, der zu Beginn der Gruppe vorlag. Dadurch wird doppelt gelesen: oben gilt das für ykj im letzten Beispiel. Dies gilt für alle vier Lookaround-Gruppen. Auf das zweite Beispiel bezogen: nach qt muß ykj folgen, ohne daß dann ykj Bestandteil des Passens (Match) ist. Zum vim-Editor gibt es unter vielen anderen die Definition für das Highlighting einer C-Funktion name(args): syn match cFunction "\<[a-zA-Z_][a-zA-Z_0-9]*\>\s*("me=e-1 Am Ende me=e-1 bedeutet: matchend = end-1 Die Klammer ( muß vorhanden sein, soll aber nicht highlighted werden. Beispiel von der oben angegebenen Webseite: Es soll ein Wort gefunden werden, sechs Zeichen lang, welches irgendwo die Zeichenfolge cat enthält: cat\w{3}|\wcat\w{2}|\w{2}cat\w|\w{3}cat Das ist kaum noch realisierbar, wenn das Wort 6-12 Zeichen lang sein und die Zeichenfolgen cat, dog oder mouse enthalten soll. (?=\b\w{6}\b)\w*cat\w* Es wird mit Lookahead ein Wort{6} gesucht. Danach wird nochmals gelesen und die Folge cat darin gesucht. (\b paßt zu Wortgrenzen) \b(?=\w{6,12}\b)\w{0,9}(cat|dog|mouse)\w* Vorstehend die Lösung des zuvor angesprochenen komplexeren Beispiels. Die Mächtigkeit des Lookaround-Konzeptes ist unschwer erkennbar. Negative Look Ahead Gruppe RA DATEN MATCH (?!abcd+e) qt(?!ykj) abcqtyKj qt qt(?!ykj) abcqt qt Wie oben, nun allerdings darf ykj nicht(!) auf qt folgen. Positive Look Behind Gruppe RA DATEN MATCH (?<=abcd+e) ^uxykj(?<=ykj)qt uxykjqtabc uxykjqt ykj(?<=ykj)qt uxykjqtabc ykjqt Bei den Lookahead-Gruppen muß einer Zeichenfolge in den DATEN eine bestimmte Zeichenfolge folgen, oder darf nicht folgen. Hingegen bei den Lookbehind-Gruppen muß eine bestimmte Zeichenfolge vor einer Zeichenfolge in den DATEN stehen, oder darf eben nicht vorangestellt sein. <--: . . . . . :--> Lookbehind Lookahead Ein Lookbehind-Verhalten ist sehr problematisch zu implementieren, falls das Grundkonzept einer regex-Engine dafür ungeeignet ist. Lookbehind ist daher oft nicht oder nur in sehr schlechter Ausführung enthalten. Zu den Einschränkungen gehören: o Nur Zeichenketten mit konstanter Länge erlaubt. Keine Quantisierung möglich. o Wenn Alternativen, dann nur mit gleich langen Zeichenfolgen. o Der Gruppeninhalt wird auf alle möglichen Längen untersucht, die er in den Daten potentiell überspannen kann. Die bish-XRE hat hier gar keine konzeptionellen Hürden, sondern kann den RA wie auch die DATEN temporär anders herum abarbeiten. Vor der Abarbeitung von rechts nach links muß überhaupt nichts analysiert werden. RA DATEN / MATCH \w*(mouse|dog|cat)\w{0,9}(?<=\b\w{6,12})\b sda,hmousegfhzx,lk hmousegfhzx h(mouse)gfhzx So kann denn auch der Beispiel-RA von Lookahead oben symmetrisch umgedreht werden für Lookbehind. Es sind allerdings absichtlich nicht sämtliche verschiedene RA-Einheiten um die Möglichkeit des Linksbetriebs erweitert worden. Gruppen sollen nicht quantifiziert, und Referenzen in Lookbehind nicht verwendet werden. Negative Look Behind Gruppe RA DATEN MATCH (?<!abcd+e) (?<!ykj)qt yKjqtabc qt \b\w+(?<!ung)\b Richtung,Verwendungen Verwendungen Siehe oben Negative Look Ahead. Hier darf ykj nicht vorangestellt sein. Das letzte Beispiel zeigt eine Wortsuche, wobei das Wort nicht mit der Zeichenfolge 'ung' enden darf. Bei der Standard-Anwendung von Lookaround-Gruppen wird nichts hinter bzw. vor die Gruppe gestellt. Wenn jedoch das doppelte Lesen ausgenutzt werden soll, muß ein Anhängen bzw. Voranstellen von weiteren RA-Einheiten erfolgen. Konditionale Gruppe (?(bedingung)yes|no) (?(<name>)yes|no) nicht implementiert (?('name')yes|no) nicht implementiert (?(number)yes|no) nicht implementiert (?(+number)yes|no) nicht implementiert (?(-number)yes|no) nicht implementiert (?(ausdruck)yes|no) (?(ausdruck)yes) RA DATEN MATCH x(?(a)b|c)y qxabyw xaby x(?(A)b|c)y qxacyw xacy x(?(a)b)y qxabyw xaby x(?(A)b)y qxayw xay x(?(A)b)y qxAbyw xAby Eine Reihe von Varianten wurde nicht implementiert, u.a. wegen der Uneindeutigkeit der vorgegebenen Syntax. Diese Gruppe prüft eine Bedingung (Kondition,condition) und durchläuft in Abhängigkeit des Prüfungsergebnisses den yes-Ausdruck oder den no-Ausdruck. Der no-Ausdruck darf weggelassen werden. Die Klammern bei (ausdruck) sind keine Gruppe, sondern (?( ist die Einleitung; die Klammern sind nur die Einrahmung für den Ausdruck. Es ist zu beachten, daß wenn die Bedingung nicht zutrifft, Zeichen aus den DATEN, die nicht passen, dennoch als angeblich passend im Gesamt-MATCH enthalten sind: hier a <> A Dieser Gruppe haften Einschränkungen an: Die Länge des Bedingungsausdrucks über die DATEN muß vorherbestimmbar sein; Es dürfen nur Einheiten mit fester Anzahl eingesetzt werden. Immerhin sind das: [ ] [ ]{2} a b c{3} .. .{10} \w \w{5} \t RA DATEN MATCH (?(aBiu{3})c|d) qabiuuddy qabiuud q(?(aBiu{3})c|d) qabiuuudy qabiuuud Das vorstehend erste Beispiel zeigt unerwünschtes Verhalten: Das q, gar nicht im RA enthalten, paßt nicht zum a. Deshalb springt die Verarbeitung sechs Zeichen (1+1+1+3) weiter, nach ddy. Die Verarbeitung soll ja nicht abbrechen wegen Nichtpassens, sondern mit dem no-Ausdruck weiter fortfahren. Fazit: Die Gruppe muß mit ihrem Bedingungsausdruck an eine DATEN-Position gebracht werden, wo sie auf einen Abschnitt trifft, den sie auch prüfen soll! Der Vorbau q im zweiten Beispiel sorgt dafür. Balancierende Gruppe (?<name1-name2>subexpression) (?<-name>subexpression) (((?'Open'\()[^\(\)]*)+((?'Close-Open'\))[^\(\)]*)+)*(?(Open)(?!))$ ^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$ <abc><mno<xyz>> Diese Konstruktion ist in der Funktionsbibliothek .NET von Microsoft enthalten. Sie wurde in der bish-XRE nur in den Compiler implementiert. Startzeichen-Syntax ( ) -- Standard-Gruppe (?< (?= (?' (?! (?: (?<= (?> (?<! (?(exp (?| (?( (?(< (?# (?opt (?(' (?3 (?+1 (?-2 (?& (?R (?0 Eine klare Eindeutigkeit liegt leider nicht vor! Die ersten beiden Zeichen sind speziell: (? \(? (\? \(\? Dann folgen fast immer ein drittes und manchmal ein viertes Zeichen, die eine eindeutige Erkennung an Hand der Startsequenz ermöglichen. Jedoch bei manchen Einheiten muß bis zu deren Ende geprüft werden, um sie erkennen und anerkennen zu können. Insbesondere bei (?[optionen][-^]optionen[:...]) Das dritte und weitere Zeichen haben keine Spezialbedeutung. Falls sie eine haben, verlieren sie sie hier. Danach fungieren sie durch den gegebenen Kontext als Erkennungszeichen. Im Gegensatz zu den ersten beiden Zeichen (? dürfen die weiteren Erkennungszeichen nicht maskiert werden! Sie dürfen im x-Modus auch nicht abgetrennt werden, durch Einfügen von Zwischenraumzeichen. Der Start (\? beginnt eine Standard-Gruppe ( ) mit dem ? als erstem gewöhnlichen Zeichen, falls ? ohne \ als speziell konfiguriert wurde. KLAMMERKONSTRUKTIONEN Kommentare (?#comment) '(?#co)(?x) ^a\,b $ #XC ' -- entspricht '^ab$' Der Kommentar '#XC ' und die anderen Zwischenraumzeichen werden durch den x-Modus ermöglicht. Dieser Kommentar reicht bis zum Zeilenende [\r\n]* einschließlich oder Ende des RA. Optionen (?bsminx-bsminx) - deaktiviert folgende Optionen (?bsminx^bsminx) ^ deaktiviert folgende Optionen (?-bsminx) (?bsminx) (?bi:regexp) RA mit temporären Optionen bi (?x) aktiviert den x-Modus Das Optionensetzen kann auch links vor einem Anker ^ vorgenommen werden. b wählt den Backslash (\ statt %) innerhalb des RA s Singleline-Modus (default; wird ignoriert) m Multiline-Modus (wird ignoriert) i unterscheide nicht zwischen A-Z und a-z (ignore case) n die Standard-Gruppe ( ) speichert keine Referenz x es können Zwischenraumzeichen eingefügt werden Die Zeilenmodi s m sind sinnlos mit den Kommandos grep und expr, da diese zeilenorientiert arbeiten und/oder keine Möglichkeit bieten, die Ergebnisse aus beliebig vielen Zeilen (m) mitzuteilen. Außerdem widersprechen sie dem rein binären Konzept der bish-XRE. Der Multiline-Modus bezieht sich auf die DATEN, nicht auf den RA. Option i erstreckt sich nur auf gewöhnliche Zeichen, nicht auf Zeichenklassen, wobei auch die Buchstaben des oberen Teils (>127) des Latin1-Zeichensatzes berücksichtigt werden. Der x-Modus gestattet es, Zwischenraumzeichen ( \t\r\n\f\v) an vielen Stellen des RA einzufügen, sofern dadurch keine speziellen Zeichenfolgen zerteilt werden. Mit dem x-Modus können mehrzeilige RA mit jeweiligen #Kommentaren vor dem Zeilenende geschrieben werden: (?xb) # Prüfung von IP-Nummern: 192.168.64.101 ^(1[0-9][0-9] # 1xx |2[0-4][0-9] # 2xx |25[0-5] # 25x |[1-9][0-9] # xx ohne 0x |[0-9]) # x \.(?1)\.(?1)\.(?1)$ # + 3 aufrufe Die Zwischenraumzeichen und # können im x-Modus mit dem Maskierzeichen zu gewöhnlichen Zeichen maskiert werden. Unterroutinen-Aufrufe (Subroutine calls) (?1) Referenznummer 1 (?1){m} mit Quantifizierung (?+1) relative Adressierung, nächste Gruppe (?-1) relative Adressierung, vorherige Gruppe (?&name) Angabe eines Referenznamens (?+1)(?'name'[abc])(?1)(?-1)(?&name) fünf Buchstaben aus der Menge [abc] [abc](?'name'[abc])[abc][abc][abc] entspricht dem Vorstehenden Diese Konstruktionen lassen die Inhalte speichernder Gruppen ablaufen. Bei diesen Aufrufen sind Vorwärtsreferenzen möglich. Andere Quantifizierungen als {m} sind logischerweise nicht möglich. Rekursive Aufrufe sollten vermieden werden! Diese Aufrufe sind etwas gänzlich Anderes als die 'Rückreferenzen'. ^(1[0-9][0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|[0-9])\.(?1)\.(?1)\.(?1)$ 7.8.122.255 ^(1[0-9][0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|[0-9])\.\1\.\1\.\1$ 122.122.122.122 Vorstehend eine Prüfung von IP-Nummern, gefolgt von einer Prüfung mit demonstrativen Rückreferenzen \1. Unterroutinen-Definition (?(DEFINE)(?'name'regexp)) ab(?(DEFINE)(?<name>regexp))cd paßt zu abcd (?&name) Aufruf Der Inhalt sind speichernde Gruppen, damit später ein Bezug durch einen Unterroutinen-Aufruf hergestellt werden kann. Andere Bezüge (\1 $1) sollten nicht hergestellt werden. Als Ganzes tritt diese Definition nicht in Erscheinung, sie ist mit ihrem Inhalt 'versteckt'. Eine solche Definition ist nicht notwendig, um Unterroutinen-Aufrufe verwenden zu können! Dazu reichen normal sichtbare Gruppen aus. Rekursion (?R) (?0) a(?R)z paßt zu aazz aaaazzzz az ... Diese Konstruktion ist in der bish-XRE nur im Compiler implementiert. Sie erfaßt den gesamten RA. Dies ist eine (kleinere) Alternative zur 'Balancierende Gruppe' (siehe oben), so ähnlich wie \K anstelle der Lookbehind-Gruppen. EINZELNE MERKMALE Siehe hierzu auch oben die Sektion ZEICHENKLASSEN. Dort sind viele RA-Einheiten beschrieben, die auch außerhalb von Zeichenklassen anwendbar sind und somit auch hierhin passen würden. Wortgrenzen \b paßt zu einer Wortgrenze (boundary) \B paßt zu einer Position ohne Wortgrenze \< paßt zu einem Wortbeginn ..[A-Za-z_] \> paßt zu einem Wortende Diese Einheiten überspannen keine Zeichen in den DATEN (zero length). In den Daten müssen aber bestimmte Zeichenabfolgen vorliegen, damit diese Einheiten passen. Und zwar muß ein Übergang von einem Zeichen, das nicht zu der Menge der Wortzeichen gehört, zu einem Zeichen, das zu der Menge der Wortzeichen gehört, vorhanden sein - oder umgekehrt. Die Besonderheit der Einheit \< ist, daß nur ein Wortbeginn paßt, der aus einem Nameführungszeichen (Head) besteht: ;[A-Za-z_][A-Za-z_0-9]* Statt \< \> kann < > konfiguriert werden. Rückreferenzen \1 \2 \3 \4 \5 \6 \7 \8 \9 \k<name> \k'name' \k{name} \k<nummer> \k'nummer' \k{nummer} \k<-nummer> \k'-nummer' \k{-nummer} \g<name> \g'name' \g{name} \g<nummer> \g'nummer' \g{nummer} \g<-nummer> \g'-nummer' \g{-nummer} \1* \1+ \1{2,5}? Diese Referenzen beziehen sich auf eine vorhergehende speichernde Gruppe. Genau derjenige Bereich in den DATEN, zu dem eine speichernde Gruppe paßt, muß auch an der Stelle der Rückreferenz hinsichtlich einer genau übereinstimmenden Zeichenfolge vorliegen! Rückreferenzen können einschränkungslos quantifiziert und qualifiziert werden. Vorwärtsreferenzen (+nummer,nummer) sind nicht möglich. RA DATEN MATCH ^(.+)\1\1$ jajaja ^(.+)\1\1$ neinneinnein ^(.+)\1\1$ tiptiptip ^(.+)\1\1$ iiiiiiiii ^(.+)\1{2}$ ,,, ^(.*)\1\1$ (.*)\1\1da da da Die ersten vorstehenden RA passen zu sämtlichen DATEN, die aus drei gleichen aneinanderstoßenden Teilen bestehen. Das sind praktisch unendlich viele. Dreimal diese Dokumentationsdatei hintereinander verkettet, würde auch passen! Tatsächlich ist das eine ganz einfache Aufgabe für das Kommando expr DATEIx3 xv:: '^(.+)\1\1$' Der vorletzte angegebene RA paßt auch zu drei leeren Zeichenfolgen, folglich zu leeren DATEN. Beim zuletzt angegebenen RA wurde .* mißbraucht; man erhält ein zumeist unerwartetes Resultat. Verwendung von .+ repariert dies Verhalten. RA DATEN MATCH ^(?<rr>.+)(\k<rr>{1,2})da tototototoda -- ^(?<rr>.+)(\k<rr>{1,2})da totototototoda (tototo)(tototo)da ^(?<rr>.+)(\k<rr>{1,8})da tototototoda (to)(totototo)da Solchermaßen unbestimmte RA sollten nicht konstruiert werden. Ohne Anker ^ paßt praktisch alles. Man wundert sich. Die Maschine geht dazu über, immer längere Stücke aus den Daten als Einheit zu betrachten. Kein Wunder, denn .+ hindert sie nicht daran. Beim letzten RA ist erkennbar, daß die Maschine durch das zuvor geringe Maximum ,2} gehindert wurde, ein Passen herzustellen. Achtung, {0,n} paßt immer irgendwo hin! Hinweis: \1 \1{2} sind beide ohne Qualifizierer + possessiv. Deshalb und wegen der Anker ^ $ ist der RA oben bei jajaja sicher anwendbar. Rückreferenzen müssen keineswegs aneinanderstoßende Regionen definieren. Zwischen ihnen darf beliebige und beliebig viel andere Syntax stehen. Auch Rückreferenzen zu anderen speichernden Gruppen. Wiederholung des Passens \G abc\Giuv entspricht abc(iuv)+ a|bc\Gwg|kalt (dsa\Gqz) Die oben notierte Entsprechung ist keine speichernde Gruppe; \G speichert nicht. Keep_Out \K abc\Kiuv ass|bc\Kwg|kalt\Koi (dsa\Kqz) Diese Funktion ist ein gewisser Ersatz für eine Lookbehind-Gruppe. Der Beginn des Passens des RA wird nach rechts verschoben; der Teil links von \K wird draußen gehalten (keep out). Maskierter Bereich \Q .. \E \Qsh{d\\h3*3(3)\38]3[2&%@25\E 25 Zeichen \Qa\kw\E\\E\Qq\ui\E entspricht a\\kw\\Eq\\ui Alle Zeichen zwischen \Q und \E werden eins nach dem anderen ohne Interpretation als gewöhnliche Zeichen gespeichert. Die Folge \E kann nicht in diesem Bereich stehen, sondern der Bereich \Q..\E muß zu diesem Zweck unterbrochen werden. Nulleinheiten Die folgenden Einheiten sind vollkommen wirkungslos im Hinblick auf den kompilierten RA. (?#comment) Kommentar (?#) leerer Kommentar \, kürzer, auch innerhalb [ ] Diese Einheiten können dazu dienen, Syntax-Sequenzen zu zerteilen, damit diese zu gewöhnlichen Zeichen oder anderen Einheiten zerfallen. SUBSTITUTION In einem Text-Editor ist möglicherweise ein Mechanismus 'Suchen_und_Ersetzen' vorhanden. Der kann sich folgendermaßen darstellen: :g/abc/s/rtv/\U=&:/g In allen Zeilen, die abc enthalten, sollen alle Vorkommnisse (/g) von rtv durch =RTV: ersetzt werden. Die bish-XRE bzw. das interne Kommando expr(K) bietet eine solche Möglichkeit: Syntax $$ $ als gewöhnliches Zeichen $_ Einsetzen der (gesamten) DATEN $0 $& Einsetzen des RA-Gesamt-Match $` Einsetzen des Teils links vor dem Gesamt-Match $' Einsetzen des Teils rechts nach dem Gesamt-Match $1 .. $9 Einsetzen der Rückreferenzen 1 bis 9 ${nummer} Einsetzen einer Rückreferenz mit Nummer 1..128 ${name} Einsetzen einer benamten Rückreferenz ${$name} Einsetzen des Inhalts einer Shell-Variablen @ ${*liste*anzahl} Multiples Einsetzen des Inhalts von Einheitenlisten @ $U Umwandlung zu Großbuchstaben $L Umwandlung zu Kleinbuchstaben $I Umwandlung aller Wörter zu Wwwwww $F Umwandlung aller Einsetzungen zu Eeeeee $E Deaktivierung der Modi $[ULIF] $d{255} Umwandlung einer Ziffernkette zu einem Byte-Wert $o{377} Umwandlung einer Ziffernkette zu einem Byte-Wert $x{FF} Umwandlung einer Zeichenkette zu einem Byte-Wert $u{00FF} Umwandlung einer Zeichenkette zu einem Byte-Wert $t Einsetzen eines TAB $r Einsetzen eines CR $n Einsetzen eines NL Das Zeichen $ ist als einziges global speziell. Insbesondere die mit @ gekennzeichnete Syntax wurde für bish-XRE kreiert. Bei der Syntax ${*liste*anzahl} darf 'liste' die gesamte vorstehende Syntax enthalten, auch rekursiv ${*abc*123} selbst, beliebig tief! Die 'anzahl' umfaßt den Wertbereich 0 .. 999999999. Das Zeichen * muß bei Verwendung in 'liste' doppelt ** gesetzt werden. Bei multiplem Ersetzen verändert sich zum Beispiel der Dateninhalt von $_ fortlaufend, denn die neuen DATEN beginnen jeweils hinter dem letzen Passenden bzw. hinter der letzten Ersetzung. arg0 arg1 arg2 arg3 arg4 arg5 expr 'abcdecfhc' x: 'c' += '++' ab++de++fh++ Vorstehend arg1 sind die DATEN, arg3 der RA, arg4 (+) bewirkt, daß jedes Vorkommnis ersetzt werden soll, und (=) schaltet alle eventuellen Spezialbedeutungen der Zeichen in arg5 (Einsetzungstext) ab. Beispiele expr abcdecfhc x: 'c' + '' abdefh Löschen des Passenden wird durch leeren Einsetzungstext vorgenommen. expr abcdecfhc x: 'c' '$IxYYG,hg,lKJ,jHHJ' abXyyg,Hg,Lkj,Jhhjdecfhc Hier wurde nur das erste Vorkommnis von c ersetzt. Die Funktion $I erfaßt nur die Einsetzung für das erste zu ersetzende c. expr abcdecfhc x: 'c(fh)' '+C$1.$1-' abcde+Cfh.fh-c Vorstehend wurde eine Gruppen-Rückreferenz $1 benutzt. expr abcdecfhc x: 'c' + '${*${*top*10}$n*2}' abtoptoptoptoptoptoptoptoptoptop toptoptoptoptoptoptoptoptoptop detoptoptoptoptoptoptoptoptoptop toptoptoptoptoptoptoptoptoptop fhtoptoptoptoptoptoptoptoptoptop toptoptoptoptoptoptoptoptoptop Hier wurde erneut dreimal c ersetzt. expr abcdecfhc x:ABC 'c' + '${*${*top*10}$n*1000000}' echo ${#ABC} 93000006 echo "$__MEM__" VARBUF 49152 100663296 536870912 16777216 12906496 Vorstehend wurde die bish-Variable 'ABC' mit 93000006 Bytes gesetzt. Das sind 2+(3*10+1)*1000000 + 2+(3*10+1)*1000000 + 2+(3*10+1)*1000000 expr 'abc' x: '' = '---' ---abc expr 'abc' x: '^' = '---' ---abc expr 'abc' x: '$' = '---' abc--- Leeren Raum vorne und hinten ersetzen (Daten vorsetzen/anfügen). expr '' x: '' '${*top*3}' toptoptop Dies Kommando kann auch einfach als Byte-Folgen-Generator genutzt werden. Zwei leere Argumente sind nützlich, wenn Daten wirklich nur generiert werden sollen. expr abcdecfhc x: 'dec(..)' fh Sehr wichtig ist auch die vorstehende Funktion mit drei Argumenten, die alle Zeichen zwischen allen gespeicherten Positionen ( ) ausgibt. Ausgabe kann auch in eine Variable (x:NAME) erfolgen. while readl Z do expr Z xv:: '^T_[0-9a-z_]{2,}$' || continue expr Z xv:W '^T_([0-9a-z_]{4})' && catv W /%n # ... done Vorstehend eine typische Anwendung, von denen in den zurückliegenden zwanzig Jahren etwa 3000 entstanden sind. #cp437 to Latin1 Trans=' 80 c7 81 fc .. .. fd b2 ' local Z:.200 qq=.. zz=.. q=. z=. while readl Z do for 2 qq zz in $Trans do base -16 qq +b q base -16 zz +b z expr "$Z" :Z "$q" += "$z" done catv Z /%n done Eine Zeichensatz-Übersetzung von CP437 nach Latin1 per bish vorstehend. Dabei wurden BRE verwendet. bish-XRE verlangt x:Z als zweites Argument. expr "$Z" x:Z '\x{'"$qq"'}' += '$x{'"$zz"'}' expr "$Z" x:Z "\\x{$qq}" += "\$x{$zz}" Mit XRE könnten die Hex-Sequenzen direkt eingebaut werden. Das Kommando base entfällt dadurch. :23,126!cp437_latin.bish Im vim-Editor kann dieses Skript wie vorstehend aufgerufen werden, und die angegebenen Zeilen :von,bis werden übersetzt. grep -Xn -e '[%d{128}-%d{255}-[äöüßÄÖÜ]]' /u/bish/man/?*.mn? Aufgrund des vorstehenden Kommandos werden alle passenden Zeilen aller relevanten Dateien mit Dateiname und Zeilennummer ausgegeben. Und zwar werden alle Zeilen gesucht, die Zeichen aus der oberen Hälfte des Zeichensatzes enthalten, wobei nach [äöüßÄÖÜ] nicht gesucht wird. Das Maskierzeichen ist hier % (default). (?b)[\d{128}-\d{255}-[äöüßÄÖÜ]] Das Maskierzeichen wurde vorstehend zu \ gewählt. HINWEISE / WARNUNGEN Verwendung möglichst vieler gewöhnlicher Zeichen im RA erhöht die Sicherheit, daß der RA so arbeitet, wie es beabsichtigt ist. Verkoppelungen mittels Anker erhöhen ebenfalls diese Sicherheit. Zudem wird dadurch die Verarbeitungsgeschwindigkeit gesteigert. Die RA-Einheit .* wird oft mißbraucht. Unbestimmter geht es nicht! Dennoch kann .* auch sicher funktionierend eingesetzt werden: /fkp/elem/qm.txt ^.*/([^/]+)$' /qm.txt ^.*/([^/]+)$' (qm.txt) Die Situation ist wegen ^ / $ eindeutig. Insbesondere / ist eine Konstante, die vorhanden sein muß und auch ein Ankerpunkt ist. Mit der possessiven Einheit .*+ vorne gibt es kein Passen. Eine Prüfung auf korrekte Pfadnamensyntax ist dies bei weitem nicht. (/[^\d{0}/]{0,254}){1,48} Vorstehender RA kommt dem schon sehr nahe: unter Unix sind alle Zeichen außer Null und / für einen Verzeichnis- und Dateinamen erlaubt, in beliebiger Abfolge. Testen Das Schreiben Regulärer Ausdrücke kann mit dem Programmieren in einer Programmiersprache verglichen werden. Daher sollte ein (vermeintlich) fertiger RA auch getestet werden! Possessiv qabcdedededekz abc((de){1,2}){1,3}k (1) qabcdedededekz abc((de){1,2}de){1,3}k (2) Beide RA passen zu weit mehr als zehn Folgen 'de', funktionieren also nicht so, wie multiplikativ prognostiziert. Zunächst ist erkennbar, daß beide RA unsinnig sind: abc(de){1,6}k (1a) abc((de){2,3}){1,3}k (2a) abc(de){2,9}k (2b) Vorstehend eine Umformung zu RA ohne unnötige Verschachtelung. abc((de){1,2}+){1,3}+k abc((de){1,2}+de){1,3}+k Beide RA wurden nun possessiv qualifiziert, und funktionieren dadurch wie beabsichtigt, obwohl sie unsinnig formuliert sind. Der zweite RA paßt also zu maximal neun 'de' (dedededededededede). Durch die Verhandlungen zwischen den verschachtelten Gruppen kommt es zu einem Passen eines zu langen Stückes aus den DATEN. Solche verschachtelten Gruppen erwarten eine Struktur mit Eckpunkten: abcggdefgdedeffkz abc(g+(de){1,2}f+){0,2}k Dieser RA paßt auch ohne Possessivität. Verschachtelte Gruppen, die gleichzeitig explizit nicht possessiv quantifiziert sind, sollten besonders gründlich durchdacht und getestet werden. Immenser Zeitbedarf RA DATEN ZEIT (x+x+)+y xxxxxxxxxxxxxxxxxxxxxy 0,000 s (x+x+)+y xxxxxxxxxxxxxxxxxxxxxZ 0,800 s (x+x+)+y xxxxxxxxxxxxxxxxxxxxxxZ 1,648 s (x+x++)+y xxxxxxxxxxxxxxxxxxxxxxZ 0,000 s Der Zeitbedarf steigt progressiv an mit der Anzahl der Zeichen x in den DATEN, wenn der RA nicht paßt. Der RA ist unsinnig komplex, wie beim vorstehenden Beispiel 'Possessiv'. Er entspricht x{2,}y ohne diesen Zeitbedarf. Wie im letzten Beispiel zu sehen ist, beseitigt Possessivität auch hier das problematische Verhalten. Die hier gesuchten DATEN verlangen keine Verhandlungen zwischen den RA-Einheiten. Null Vorkommnisse DATEN RA MATCH asqqeonpi er|(de){0,2}|n () asqqeonpi er|n|(de){0,2} () asqqeonpi er|(de){1,2}|n n 0-mal 'de' vorne paßt einwandfrei. (Der Quantifizierer ? = {0,1} sollte hier nicht vergessen werden.) Die Maschine vergleicht zuerst das 'a' ganz vorne. Und zu dem paßt 0-mal 'de', also leer, als einziges sofort. LIMITIERUNGEN Verschachtelung Bei nachfolgenden Angaben hierzu gilt auch Ebene 0 als Verschachtelungsebene. Namen Deren Länge darf 31 Zeichen betragen. Referenzen Es werden die Nummern 1 .. 128 zugeordnet. Zeichenklassen Es können bis zu 48 freie Definitionen [ ] erfolgen. Vordefiniert sind 82 Zeichenklassen. Gruppen-Quantifizierung ( ){m,n} ( )* ( )+ Die Werte m und n sind auf 30000 begrenzt. Bei Verwendung von * und + wird intern entsprechend begrenzt. Quantifizierte Gruppen können bis zu 4-fach verschachtelt werden. Unterroutinen-Aufrufe können bis zu 6-fach verschachtelt werden. Alternativen-Listen (a|b|c) können sich innerhalb der ersten 8 Verschachtelungsebenen befinden. Konditionale können nicht verschachtelt werden. Verschachtelungstiefe Allgemein beträgt diese maximal 255. VERSIONEN XRE-Doku, Version August 2015 bish-XRE, Version 0.95, August 2015 SIEHE AUCH bish(K), expr(K), grep(K), regexp® http://www.regular-expressions.info/tutorial.html AUTOR Copyright © Helmut Schellong Vlotho, Juli 2015 BEISPIELE Nachfolgend kommentarlose Beispiele, hier am Ende der Datei, weil der Umfang sehr groß ist. Es handelt sich um BRE-Ausdrücke mit dem Maskierzeichen %. 2750 Beispiel-Zeilen |
regexp® regexp® NAME regexp - Definition der Schreibweise sogenannter regulärer Ausdrücke (regular expressions) und beim Zeichenmustervergleich (pattern matching). BESCHREIBUNG Ein regulärer Ausdruck ist ein Mechanismus zur Feststellung der Position einer ganz bestimmten Zeichenfolge oder um ein solches Muster gezielt zu manipulieren. Dieser Mechanismus wird von vielen Hilfsprogrammen unterstützt. Zeichenmustervergleich wird von Shell- und anderen Programmen zur Verfügung gestellt, hauptsächlich zur Dateinamen-Expansion. Diese Beschreibung regexp® umfaßt Elementare reguläre Ausdrücke Erweiterte reguläre Ausdrücke Zeichenmustervergleich Abweichungen von den folgenden Regeln zu Schreibweise und Konstruktion sind bei den Einzelbeschreibungen der betreffenden Kommandos erklärt. Nachfolgend wird das Backslash-Zeichen (\) als Sonderzeichen benannt; man achte darauf, ob andere Beschreibungen hiervon abweichend das Prozentzeichen (%) benennen. Vergleiche basieren stets auf dem Bitmuster, also dem Zahlenwert der Zeichen und nicht auf der graphischen Repräsentation der Zeichen. ELEMENTARE REGULÄRE AUSDRÜCKE (RA) RAs, die für ein einzelnes Zeichen stehen Die folgenden RAs ersetzen ein einzelnes Zeichen oder ein einzelnes Zeichen aus einer Ansammlung von Zeichen: Gewöhnliche Zeichen Ein gewöhnliches Zeichen ist ein RA, der für sich selbst steht. Ein solches Zeichen ist jedes beliebige Zeichen aus dem unterstützten Zeichensatz, außer NL (newline) und denjenigen Zeichen, die innerhalb eines RA Spezialbedeutung haben und unten aufgelistet sind. Eine Zeichenfolge, die aus einem Backslash (\) und dann einem der der folgenden Zeichen besteht, wird als Spezialsymbol interpretiert: ( ) { } 1 2 3 4 5 6 7 8 9 Spezialzeichen Spezialzeichen haben eine Spezialbedeutung innerhalb von RAs, das heißt, sie enthalten eine bestimmte Funktionalität. Ein vorangestellter Backslash hebt die Spezialbedeutung eines Zeichens auf - das Zeichen steht dann für sich selbst. Diese Spezialzeichen und die Umgebungen, in denen sie Spezialbedeutung haben, sind: . [ \ Spezial, jedoch nicht innerhalb einer Zeichenklasse ([...]) * Spezial, jedoch nicht innerhalb einer Zeichenklasse, als erstes Zeichen eines RA und als erstes Zeichen nach der Zeichenfolge \( ^ Spezial, nur als erstes Zeichen eines RA und als erstes Zeichen einer Zeichenklasse. $ Spezial, nur als letztes Zeichen eines RA begrenzer Jedes Zeichen, das einen RA begrenzt, ist spezial für denjenigen RA (i.d.R. / und ?) Punkt Ein Punkt (.) außerhalb einer Zeichenklasse ersetzt ein beliebiges Zeichen außer NL. Zeichenklasse Eine Zeichenklasse, eingeschlossen in eckige Klammern ([ ]), ist ein RA, der ein einzelnes Zeichen ersetzt, das in der nichtleeren Ansammlung aus Zeichen vorkommt, die eine Zeichenklasse repräsentiert. Wenn also während einer Vergleichsoperation ein Zeichen aus dem zu prüfenden Vergleichsmuster mit einer Zeichenklasse verglichen wird und dieses Zeichen eines der Zeichen ist, die von der Zeichenklasse repräsentiert werden, dann gilt dieser Vergleich als zutreffend. Folgende Regeln bestehen zu Zeichenklassen: Das Zeichen NL wird von einer Zeichenklasse niemals repräsentiert. Innerhalb einer Zeichenklasse haben nur die Zeichen ^ ] - Spezialbedeutung, ^ nur direkt nach der Startklammer [ . Die Zeichen . * \ [ verlieren hierin ihre spezielle Bedeutung. Standardmäßig repräsentiert eine Zeichenklasse genau diejenigen Zeichen, die zwischen den beiden eckigen Klammern angegeben sind, wobei die Art der Darstellung keine Rolle spielt. Wenn jedoch das erste Zeichen nach [ das Zeichen ^ ist, werden diejenigen Zeichen repräsentiert, die NICHT angegeben sind. [abc] paßt zu a oder b oder c. [^abc] paßt zu allen Zeichen, außer zu a und b und c und NL. Das Abschlußzeichen ] verliert diese Bedeutung, wenn es dem Startzeichen [ oder [^ direkt folgt. Es gilt in diesem Fall als gewöhnliches Zeichen. Das Minuszeichen (-) dient dazu, um per Kurzschreibweise Zeichenbereiche darzustellen. Es verliert seine Spezialbedeutung, wenn es an den Rändern, also nach [ oder nach [^ oder vor ] steht, oder wenn es das rechte Zeichen eines Zeichenbereiches ist. Es gilt in diesen Fällen als gewöhnliches Zeichen. Der Zahlenwert des rechten Zeichens eines Zeichenbereiches muß gleich oder größer als der Wert des linken Zeichens sein. [a-dU-Z] entspricht [abcdUVWXYZ] [^a-dU-Z] entspricht [^abcdUVWXYZ] [a-d-f] entspricht [a-dd-f] [-ac] sind gleichwertig und passen zu [ac-] a oder c oder - [-ca] [ca-] [#--] paßt zu # bis - einschließlich [--@] paßt zu - bis @ einschließlich [a#--f] paßt zu a oder (# bis -) oder f RAs, die mehrere Zeichen ersetzen Sie werden konstruiert aus RAs, die ein Zeichen ersetzen. RARA Beispielsweise bc paßt zum ersten Vorkommen von bc in abcdefabcdef: zweites und drittes Zeichen. Ein RA sucht generell Übereinstimmung mit der ERSTEN und LÄNGSTMÖGLICHEN Zeichenfolge. RA* Ersetzt null oder mehr (beliebig viele) Vorkommen von RA. b*c oder bbb*c oder bbbc ersetzen das zweite bis fünfte Zeichen in abbbcdeabbbbbbcde . Der Stern (*) verliert seine Spezialbedeutung als erstes Zeichen eines RA. \(RA\) Unterausdruck Ein RA als Unterausdruck paßt zu allem, was ohne die Zeichenfolgen \( und \) passen würde. Unterausdrücke können verschachtelt werden. Ein Stern (*) nach \( verliert seine Spezialbedeutung. Nach \) ist ein Stern nicht erlaubt. \n Die Zeichenfolge \n steht für einen Unterausdruck, der zuvor mittels \( und \) definiert wurde. n muß ein Digit von 1 bis 9 sein, das den RA adressiert, der zwischen der n-ten Zeichenfolge \( und der korrespondierenden Zeichenfolge \) steht. ^\(.*\)\1$ paßt beispielsweise zu einer Zeile, die zwei gleiche Zeichenketten hintereinander enthält. Und zwar irgendwelche zwei gleiche Zeichenketten! Nach \n kann ein Stern (*) stehen, der dann zu null oder mehr Vorkommnissen des Unterausdrucks multipliziert. \(ab\(cd\)ef\)T\2*T\1 paßt beispielsweise zu abcdefTcdcdTabcdef Unterausdrücke sind äußerst sinnvoll bei den Kommandos vi, ed, sed und expr(K). Vorher: Array[sel][1] Array[i][0] Array[esnu][0] Im vi-Editor: :g/Array\[\([a-z].*\)\]\[\([01]\)\]/s//Array[\2][\1]/ Nachher: Array[1][sel] Array[0][i] Array[0][esnu] Man kann so stundenlange Arbeit durch 2 Minuten ersetzen! RA\{m,n\} Die Spezialfunktion des Stern (*) wird durch \{m,n\} erweitert. (\{m,n} ist auch möglich.) Mittels m und n wird angegeben, wie oft mindestens und wie oft maximal RA vorkommen darf, damit ein Vergleich zutreffend ist. Für m und n ist ein Bereich von 0 bis 255 gültig. \{m\} m Vorkommnisse \{m,\} >=m Vorkommnisse \{m,n\} >=m,<=n Vorkommnisse b\{3\} paßt zum zweiten bis vierten, b\{3,\} zum zweiten bis achten, und b\{3,5\}c zum vierten bis neunten Zeichen von abbbbbbbc Positionsfixierung eines RA Ein RA kann in Bezug auf das zu prüfende Vergleichsmuster in seiner Position festgelegt werden: Das Zeichen ^ zu Beginn eines RA erzwingt, daß der RA beginnend vom Anfang einer Zeile an passen muß. Das Zeichen $ am Ende eines RA erzwingt, daß der RA am Ende einer Zeile passen muß. Bei Verwendung beider Fixierungszeichen muß der RA am Anfang und am Ende einer Zeile passen. Hier passen also nur komplette Zeilen, von NL bis NL bzw. CR-NL. ^$ paßt nur zu Leerzeilen. ERWEITERTE REGULÄRE AUSDRÜCKE (ERA) Die wesentlichen Erweiterungen, die ERAs gegenüber den RAs bieten, sind die Klammern (), um zusammengefaßte Einheiten zu bilden, und der Oder-Operator | für die Alternativ-Funktion. Die Spezialzeichenfolgen der RAs \( \) \{ \} \1 bis \9 gelten hier nicht. \{m,n\} wird teilweise durch die hier gültigen hinzugekommenen Spezialzeichen + und ? aufgewogen. ERAs sind zumindest für Editor-Programme nicht so gut geeignet wie die (einfacheren?) RAs. ERAs, die für ein einzelnes Zeichen stehen Die folgenden ERAs ersetzen ein einzelnes Zeichen oder ein einzelnes Zeichen aus einer Ansammlung von Zeichen: Gewöhnliche Zeichen Ein gewöhnliches Zeichen ist ein ERA, der für sich selbst steht. Spezialzeichen Die hier geltenden Spezialzeichen und die Umgebungen, in denen sie Spezialbedeutung haben, sind: . [ \ ( ) * + ? $ | Spezial, jedoch nicht innerhalb einer Zeichenklasse ([...]). ^ Spezial, jedoch nicht innerhalb einer Zeichenklasse in nichtführender Position. begrenzer Jedes Zeichen, das einen ERA begrenzt, ist spezial für denjenigen ERA (i.d.R. / und ?) Punkt Ein Punkt (.) außerhalb einer Zeichenklasse ersetzt ein beliebiges Zeichen außer NL. ERA Zeichenklasse Siehe RA Zeichenklasse ERAs, die mehrere Zeichen ersetzen Sie werden konstruiert aus ERAs, die ein Zeichen ersetzen. Im Unterschied zu RAs können bei den ERAs mehrere hintereinander stehende ERAs mittels Klammern () zu einer Einheit zusammengefaßt werden, so daß Spezialzeichen auf die gesamte Einheit wirken. Eine solche Einheit kann dann als einzelnes Zeichen aufgefaßt werden. Die Klammern zeigen lediglich an, ob und was zusammengefaßt werden soll und sind nach Erfüllung ihrer Aufgabe nicht mehr Bestandteil eines ERA. ERAERA Beispielsweise bc paßt zum ersten Vorkommen von bc in abcdefabcdef: zweites und drittes Zeichen. Gleiches gilt für bc in Klammern: (bc) Ein ERA sucht generell Übereinstimmung mit der ersten und längstmöglichen Zeichenfolge. ERA+ Paßt zu einem oder mehr Vorkommen von ERA. b+c paßt zum vierten bis siebten Zeichen in acabbbcde . ERA* Paßt zu null oder mehr Vorkommen von ERA. b*c paßt zum ersten Zeichen in cabbbcde . b*cd paßt zum dritten bis siebten Zeichen in cabbbcdebbbbbbcdbc . ERA? Paßt zu null oder einem Vorkommen von ERA. b?c paßt zum zweiten Zeichen in acabbbcde . Alternative Zwei ERAs mit dem Zeichen | dazwischen passen zu einem Vergleichs= muster, daß zu dem einen oder dem anderen ERA paßt. Der ERA ((ab)|c)d paßt zu abd oder zu cd Vorrang Mit fallender Priorität: [ ] Zeichenklasse * + ? Stern, Pluszeichen, Fragezeichen ^ $ Positionsfixierung Verkettung, Hintereinanderfolge | Oder-Auswahl, Alternative Bei abba|cde sucht der ERA Übereinstimmung mit abba oder mit cde weil Verkettung eine höhere Priorität hat als die Alternative. Positionsfixierung eines ERA Siehe Positionsfixierung eines RA ( ^ $ ) ZEICHENMUSTERVERGLEICH (pattern matching notation) Patterns, die für ein einzelnes Zeichen stehen Die folgenden Patterns ersetzen ein einzelnes Zeichen oder ein einzelnes Zeichen aus einer Ansammlung von Zeichen: Gewöhnliche Zeichen Ein gewöhnliches Zeichen ist ein Pattern, das für sich selbst steht. Die Spezialzeichenfolgen der RAs \( \) \{ \} \1 bis \9 gelten hier nicht. Spezialzeichen Spezialzeichen haben eine Spezialbedeutung innerhalb von Patterns, das heißt, sie enthalten eine bestimmte Funktionalität. Ein vorangestellter Backslash hebt die Spezialbedeutung eines Zeichens auf - das Zeichen steht dann für sich selbst. Diese Spezialzeichen und die Umgebungen, in denen sie Spezialbedeutung haben, sind: ? * [ Spezial, jedoch nicht innerhalb einer Zeichenklasse ([...]) Fragezeichen Ein Fragezeichen (?) außerhalb einer Zeichenklasse steht für ein beliebiges Zeichen. (Bei RAs und ERAs der Punkt (.)) Zeichenklasse Siehe RA Zeichenklasse. Abweichungen: Das Ausrufezeichen (!) ersetzt das Zeichen ^ in seiner Funktion als Invertierer. Der Backslash (\) wird innerhalb als Maskierzeichen benutzt, das Spezialbedeutungen aufhebt. Patterns, die mehrere Zeichen ersetzen Sie werden konstruiert aus Patterns, die ein Zeichen ersetzen. * Der Stern paßt zu jeder Zeichenkette, einschließlich der leeren Zeichenkette. Es werden beliebig viele beliebige Zeichen ersetzt. Der Stern ist hier das, was bei den RAs und ERAs die Zeichenfolge .* ist. Dort werden werden durch den Stern beliebig viele bestimmte Zeichen ersetzt. RARA a[bc] paßt zu (Verkettung) ab und zu ac a*d paßt zu ad , abd , abcd , jedoch nicht zu abc . *a*d* paßt zu einem Muster, das irgendwo ein a enthält, dem in beliebigem Abstand ein d folgt... SIEHE AUCH bish(K), expr(K), grep(K), pg(K). AUTOR Helmut Schellong, Bad Salzuflen LITERATUR Manual-Page regexp(5) HP-UX Rel. 9.0 - Hewlett-Packard Company |
ansi® ansi® NAME ansi-Treiber-Funktionen bei Ausgaben auf den Bildschirm (Intern, nur bei bsh32.exe) SYNTAX Escape-Sequenzen: esc[Z, esc[nZ, esc[n;n...m, esc[=nZ, ... BESCHREIBUNG Mit Hilfe von Escape-Sequenzen können verschiedene Funktionen des Bildschirms -und auch andere- gesteuert werden. Eine Escape-Sequenz beginnt stets mit einem Escape-Zeichen (dezimal 27), fast immer gefolgt von dem Zeichen '['. Beendet wird solch eine spezielle Zeichenfolge fast ausnahmslos durch einen Buchstaben, meist ein Großbuchstabe. Escape-Sequenzen werden nur verarbeitet, wenn sie zu einem Bildschirm-Gerät geschrieben werden. Das sind beispielsweise: CON, CONOUT$, /dev/tty, /dev/tty01, /dev/console, ... Ein 'Leckerbissen' ist die MultiScreen-Sequenz esc[nz, s.u. Mit esc[c;sp können Tasten programmiert werden, wodurch man sich eine _sehr_ bequeme Bedienung zurechtbasteln kann. Sequenzen gemäß ANSI X3.64-1979: -------------------------------- Für ein fehlendes 'n' wird in der Regel '1' eingesetzt. esc[nA Cursor n Zeilen aufwärts esc[nB Cursor n Zeilen abwärts esc[nC Cursor n Zeichen vorwärts esc[nD Cursor n Zeichen zurück esc[nE Cursor auf Anfang, n Zeilen abwärts esc[nF Cursor auf Anfang, n Zeilen aufwärts esc[H Cursor auf Position 1;1 esc[v;hH Cursor auf Position vertikal;horizontal esc[v;hf dito esc[n` Cursor auf Spalte n (`==Backquote!) esc[nG Cursor auf Spalte n-1 (nicht ANSI) esc[nd Cursor auf Zeile n esc[nP Löscht n Zeichen esc[nM Löscht n Zeilen esc[nX Überschreibt n Zeichen leer esc[0J Löscht Bildschirm, von Position bis Ende 1J Löscht Bildschirm, von Anfang bis Position 2J Löscht Bildschirm, Cursor auf 1;1 3J Löscht Bildschirmpuffer, Cursor 1;1 (n.ANSI) esc[K Löscht Zeile, von Position bis Ende esc[0K Löscht Zeile, von Position bis Ende 1K Löscht Zeile, von Anfang bis Position 2K Löscht Zeile esc[n@ Einfügt n Leerstellen esc[nL Einfügt n Leerzeilen esc[nS Scrollt Bild n Zeilen aufwärts esc[nT Scrollt Bild n Zeilen abwärts esc[nZ -- Cursor n TABs zurück esc[s Sichert aktuelle Cursor-Position (Wert=0) esc[u Holt Cursor-Position (Wert=0) esc[ns Sichert aktuelle Cursor-Pos. (16 Werte, n=0-15) esc[nu Holt Cursor-Position (16 Werte, n=0-15) esc[a;ns Sichert aktuelle Zeichenattribute (n=0-15) a=0: normal+reverse a=1: normal a=2: reverse esc[a;nu Holt aktuelle Zeichenattribute (n=0-15) a=0: aktuelle Mode (7m,0m) entscheidet. a=1: normal a=2: reverse esc[?25h Cursor sichtbar esc[?25l Cursor unsichtbar esc[?6l Normaler Cursor-Modus (?) (Home) esc[nm Setzt Zeichenattribute: (mehrere: esc[n1;n2;n3;n4...m sind angebbar) esc[0m Löscht Zeichenattribute: 1m,7m,8m 1m Helligkeit ein 2m - Helligkeit gering 3m - Italic ein 4m - Unterstreichen ein 5m Blinken ein 6m - Blinken ein, hohe Frequenz 7m Reverse video ein 8m Sichtbarkeit (Input-Echo) aus. Wirkt nicht innerhalb der Kommandozeile des Kommandozeilen-Editors; ist dennoch aktiviert. 10m - Primärer Font 11m - Erster alternativer Font 12m - Zweiter alternativer Font 19m - Neunter alternativer Font 21m - Helligkeit aus 22m Normal-Farbe oder -Helligkeit 23m - Italic aus 24m - Unterstreichen aus 25m Blinken aus 27m Reverse video aus 30m Vordergrund schwarz 31m Vordergrund rot 32m Vordergrund grün 33m Vordergrund braun 34m Vordergrund blau 35m Vordergrund magenta 36m Vordergrund cyan 37m Vordergrund weiß 38m Erweiterte Vordergrundfarbe esc[38;5;Cm C=0..255; s.u. esc[38;2;r;g;bm rgb=0..255 39m Default Fordergrund 40m Hintergrund schwarz 41m Hintergrund rot 42m Hintergrund grün 43m Hintergrund braun 44m Hintergrund blau 45m Hintergrund magenta 46m Hintergrund cyan 47m Hintergrund weiß 48m Erweiterte Hintergrundfarbe esc[48;5;Cm C=0..255; s.u. esc[48;2;r;g;bm rgb=0..255 49m Default Hintergrund 90.. 97m Helle Vordergrundfarbe 100..107m Helle Hintergrundfarbe esc[6n Schreibt die aktuelle Cursor-Position in die Eingabe: "VP HP\n" esc[2i Konvertiert den Bildschirmpuffer und schreibt diese Daten (OEMTEXT) in die Zwischenablage. esc[2h -- Locks keyboard esc[2l -- Unlocks keyboard esc[=7h Autowrap ein esc[=7l Autowrap aus esc[c;sp Programmiert Tasten: code;string[;...;...]p string;code code;code string;string Siehe unten: HINWEISE. 38m, 48m: 0- 7: Normalhelle Farben 8-15: Helle Farben 16-E7: 6 * 6 * 6 = 216 colors: 16 + 36 * r + 6 * g + b (0 <= r, g, b <= 5) E8-FF: grayscale from black to white in 24 steps Sequenzen nicht ANSI-konform: ----------------------------- esc[=cA -- Overscan-Farbe auf c esc[=f;dB Signalton freq;dauer 37-32kHz;millisek (f;d werden nur unter NT berücksichtigt) esc[=s;eC Cursor-Größe start;ende (0;15,...,16;0) Bei s>e oder s>15 wird Cursor unsichtbar. (0;13 hat gleiche Wirkung wie 2;15 , da Windows nur *einen* Wert (1-100) verarbeitet.) esc[=0C Schreibt aktuelle start;ende-Werte in die Eingabe. Siehe unten: esc[=nM escQFn"str"-- Programmiert die Funktionstaste Fn mit "str" Abgrenzungen ": irgendwelche Zeichen nicht in str F1:Fn=='0', F2:Fn=='1', ..., F16:Fn=='?', ..., bis F96: esc[0k Tastendruck-Klick ein (Wirkt nur unter NT richtig.) esc[1k Tastendruck-Klick aus esc[nz MultiScreen: Wechselt zu Bildschirm n esc[=cF Normale Vordergrundfarbe auf c esc[=cG Normale Hintergrundfarbe auf c esc[=cH Reverse Vordergrundfarbe auf c esc[=cI Reverse Hintergrundfarbe auf c esc[=cJ -- Grafik Vordergrundfarbe auf c esc[=cK -- Grafik Hintergrundfarbe auf c esc[=0L Füllung neuer Bereiche mit aktuellen Farben (STD) 1L Füllung neuer Bereiche mit Normal-Farben esc[=0M Schreibt aktuelle Normal-Farben in die Eingabe 1M Schreibt aktuelle Reverse-Farben in die Eingabe 2M -- Schreibt aktuelle Grafik-Farben in die Eingabe: Rückgabe: "VG HG\n", als dezimale Digit-Strings. Siehe BEISPIELE. Farbwerte: 0 Schwarz 8 Grau 1 Blau 9 Hell Blau 2 Grün 10 Hell Grün 3 Cyan 11 Hell Cyan 4 Rot 12 Hell Rot 5 Magenta 13 Hell Magenta 6 Braun 14 Gelb 7 Weiß 15 Hell Weiß HINWEISE bsh: set +S / set -S schalten ansi aus/ein. readc.com funktioniert auch unter NT. Normal- und Reverse-Farben sind voneinander getrennt. Ebenso die nm- von den =cX-Farb-Einstellungen. 7m / 0m schalten Reverse ein/aus. =cF =cG =cH =cI gestatten eine getrennte Einstellung, zudem mit Werten von 0-15, also einschließlich bold-Bit. Man beachte, daß eine Reverse-Farbwahl im Normal-Modus keine sofortige Wirkung zeigt, sondern erst bei esc[7m ! Die Zeichenfolgen - und -- (siehe oben) bedeuten, daß diese Escape-Sequenzen nicht (--) oder eventuell (-) realisiert wurden/werden. Der interne Kommandozeilen-Editor der bsh32 hat (ebenfalls) ein Tasten-Mapping eingebaut: <Alt>+<Taste> Mit Escape-Sequenzen programmierte Tasten wirken nur bei eingeschaltetem Kommandozeilen-Editor (set -E). Die Sequenz 8m ist zur Eingabe von Geheimworten nützlich. Wirkt nicht sichtbar innerhalb der Kommandozeile des Kommandozeilen-Editors, ist aber dennoch aktiv. Wirkt aber beim read-Kommando, usw. Tasten-Mapping mit esc[...p: ============================= echo '%e["sf9";"echo 999 "p%c' programmiert 'echo 999 ' auf die Tasten <Shift>+<F9>. Nach Tastendruck sieht die Kommandozeile so aus: # echo 999 _ und man kann <Enter> drücken zur Ausführung. echo '%e["sf9";"echo 999%r"p%c' programmiert die <Enter>-Taste gleich mit (%r==CR). echo '%e["scaf12";"echo aaa%r"p%c' echo '%e["sca;f12";"echo aaa%r"p%c' echo '%e["sca:f12";"echo aaa%r"p%c' <Shift>+<Ctrl>+<Alt>+<F12>, die 96-ste Fu-Taste. Wie oben in der Liste gezeigt, können Strings und Dezimalzahlen beliebig kombiniert werden. Mit Zahlen ist immer nur _ein_ Zeichen darstellbar: echo '%e[65;66;"B";67;"C";68p' echo '%e["aA";"B";"a:B";"a:C";"C";"D"p' <Alt>+<A>==B, <Alt>+<B>==C, <Alt>+<C>==D Man beachte das <Alt>: Bei der Programmierung von normalen Einzelzeichen ist nur <Alt>+<Zeichen> oder <Alt>+<Shift>+<Zeichen> möglich, auch wenn man es bei Zahlenangabe anstelle von Strings nicht angeben konnte. Es sind maximal 8 Paare innerhalb einer einzigen Sequenz esc[...p angebbar. Anstelle von "aa'a'aa" kann auch 'aa"a"aa' verwendet werden, damit man die Abgrenzungszeichen ('") auch jeweils programmieren kann: Die Ergebnisse: aa'a'aa und aa"a"aa Noch universeller ist es, zwei Delimiter innerhalb direkt hintereinander zu stellen: "aa""bb" programmiert: aa"bb 'aa''bb' programmiert: aa'bb 'aa''""' programmiert: aa'"" 'aa''"' programmiert: aa'" '''' programmiert: ' ''' programmiert: FEHLER! "" programmiert: LEER '' programmiert: LEER echo '%e["sca:f12";"echo ""aaa b""%r"p%c' programmiert: echo "aaa b"CR MultiScreen: echo '%e["sf4";"echo ''%%e[4z%%c''%r"p%c' programmiert: echo '%e[4z%c'CR womit man durch <Shift>+<F4> zum Screen4 wechselt. Maskierungen: echo '%e["sf4";"echo ''%%e[4z%%c''%r"p%c' ' ' '' '' für die Shell: '' --> ' %% %% für das äußere echo-Kommando: %% --> % %c unterdrückt Zeilenvorschub. %e ist Kurzform von %033. Solche Maskierebenen sind leider notwendig, wenn man alles machen können will. Besser so als gar nicht. Hier sind immerhin drei Syntax-Formen verschachtelt beteiligt: Shell (bsh), echo-Kommando und ansi-Treiber! Aber in der Praxis braucht man nur _ein_ erfolgreiches Muster, das man ja kopieren kann. Weiterhin können Shell-Variablen benutzt werden: E="xyz"; echo "...$E..."; ... Das macht's dann doch wieder einfach, weil hübsch nacheinander und weil $E vieles verbirgt. BEISPIELE Umgang mit den Input-Schreib-Sequenzen 6n =0C =0M =1M: echo '%033[=0M%c'; read vordgr hintgr echo '%e[=0M%c'; read vordgr hintgr echo '%e[=0M%e[8m%c'; read vordgr hintgr; echo '%e[0m%c' Auf diese Weise verhindert man, daß die Informationen direkt als Eingabe von Kommandos verarbeitet werden; Ohne Zeilenvorschub müßte man bei 'read' <Enter> drücken. Das will man ja nicht haben: # echo '%e[=0C%c' # 13 15 bsh: Kommando nicht gefunden: '13' # _ Die Sequenzen 8m/0m schalten das Echo der Systemfunktion innerhalb von read aus/ein. Die beiden Zahlen werden auf diese Weise nicht sichtbar. EXIT-CODE Gibt es nicht. Bei falschen oder unbekannten Sequenzen werden diese teilweise ausgeschrieben, also nicht ganz 'geschluckt'. DIAGNOSE Es gibt Fehlermeldungen, falls dieser interne ansi-Treiber gar nicht genutzt werden kann. SIEHE AUCH bsh(K), readc(K), bsh32.exe, DOS-help:ansi.sys . AUTOR Diese Funktionen ansi wurden entwickelt von: Helmut Schellong, Bad Salzuflen |
readc(K) readc(K) NAME readc.com - Liest im raw-Modus ein Zeichen von der Tastatur SYNTAX readc [ -cew2 ] keystr=`readc` BESCHREIBUNG Das Kommando readc wartet nach Aufruf auf einen Tastendruck oder eine Tastendruck-Kombination (<Taste>,<Ctrl>+<Taste>,...). Ist ein solcher erfolgt, schreibt das Kommando eine zur Taste gehörende Zeichenkette (Kürzel) oder das originale Einzelzeichen zur Standard-Ausgabe. Die Eingabetaste <Enter> braucht also nicht als Abschluß gedrückt zu werden, sondern für sie gibt es auch (ein) Kürzel. Die Kommandozeilen-Optionen sind: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -c Es werden alternative Kürzel für die Zeichen 1-31 ausgegeben: ^A ... ^Z ^[ ... ^_ Dies ist eine verbreitete Darstellungsart für <Ctrl>-Zeichen. -e Aktiviert eine Echo-Funktion. Bei normaler Anwendung innerhalb eines geeigneten Shell-Programms werden die Kürzel und Einzelzeichen per Kommando-Substitution in eine Variable gelenkt: key=`readc` ( oder key=$(readc) ). Option -e bewirkt, daß (nur!) Einzelzeichen dann zur Standard- -Fehlerausgabe geschrieben werden, damit sie sichtbar auf dem Bildschirm erscheinen und nicht nur in eine Variable gelangen. Ein Echo wird vorgenommen falls nur die Standard-Ausgabe oder nur die Standard-Fehlerausgabe mit dem Bildschirm verknüpft ist. Bei gesetzter Option -2 geht das Echo auf Handle 1 statt 2. -w Alle Kürzel werden zur Standard-Ausgabe geschrieben, damit man sie kennenlernen kann. Zu diesem Zweck kann man sie per Umlenkung in eine geeignete Zieldatei schreiben: readc -w >> script_datei Diese Option berücksichtigt gesetzte Optionen -c und -2. -2 Die Kürzel werden zur Standard-Fehlerausgabe geschrieben. Handle 2 wird also anstelle von Handle 1 verwendet. Die Kommandozeilen-Optionen können beliebig gruppiert angegeben werden. Die annähernd 200 Kürzel sind selbsterklärend und bestehen weit überwiegend nur aus Großbuchstaben und den Zeichen '_1234567890'. Beispiel: ESC, INS, HOME, UP, DOWN, LEFT, RIGHT, F1, F11, BACK, ENTER, C_ENTER, C_D, ^D, C_F1, A_F5, N5, A_N5, ... C_ ist <Ctrl> A_ ist <Alt> N ist <auf dem Nummernblock> Eine Liste aller Kürzel kann man per '-w' leicht erzeugen. Wenn man 'readc' aufruft und eine Taste drückt, sieht man sofort die Antwort. In dieser Dokumentation ist daher keine Liste enthalten. Ein Zeilenvorschub wird nur bei nicht umgelenkter Ausgabe ausgegeben. Eine Garantie gibt es nicht dafür, daß sämtliche Kürzel auf jeder beliebigen Hardware zu den Tastendrücken passen. Dieses Kommando macht nur richtig Sinn in Zusammenarbeit mit einem Shell-Programm, das Kommando-Substitution beherrscht. In der Regel sind das die UNIX-Shells und 'bish.exe' für DOS. Umgebungsvariablen: ~~~~~~~~~~~~~~~~~~~ readc berücksichtigt hier folgende Variablen (Environment): BSHAUTOR Um die Autoren-Meldung zu unterdrücken: BSHAUTOR=H.Schellong,Vlotho READCPROGRAM Um die Freeware-Meldung zu unterdrücken: READCPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (BSHAUTOR muß hierfür auch gesetzt sein.) BEISPIELE keystr=`readc` keystr=$(readc -ce) readc -wc > shorties readc SIEHE AUCH bish(K), read(bish(K)) DIAGNOSE Fehlermeldungen mit nachfolgendem Programmabbruch. EXIT-CODE 0 Kein Fehler aufgetreten. >0 Fehler AUTOR Das Programm readc wurde entwickelt von: Helmut Schellong, Bad Salzuflen Copyright © 1997 |
calc(K) calc(K) NAME calc.exe - Rechnet mit Gleit- und Festkommazahlen SYNTAX calc [ arithmetischer_ausdruck ... ] kdo | calc calc < datei BESCHREIBUNG Das Kommando calc gestattet Berechnungen mit Gleitkommazahlen und Festkommazahlen. Es sind in etwa diejenigen Rechenoperationen und Funktionen vorhanden, die wissenschaftliche Taschenrechner zur Verfügung stellen. Zusätzlich gibt es Operationen, wie sie typischerweise bei Programmiersprachen anzufinden sind. calc verarbeitet und produziert bei Eingabe und Ausgabe die Darstellungsarten Dezimal, Hexadezimal, Octal und Dual. Die Darstellung bei Ausgabe ist einstellbar, bei Eingabe wird die Darstellung mittels der Suffixe h,o,b identifiziert, wobei bei Hexadezimaldarstellung gegebenenfalls eine Null (0) vorangestellt werden muß: 0fa98ch Ergebnisse werden zur Standard-Ausgabe geschrieben. Die Eingabe entnimmt calc angegebenen Argumenten, wobei nach Erreichen des Endes eines jeden Argumentes die Berechnung gestartet und ein zugehöriges Ergebnis (manchmal zwei oder drei) ausgegeben wird. Das bedeutet, daß jedes Argument ein sinnvoller arithmetischer Ausdruck sein muß. Die Ausgabe kann unterdrückt werden, durch Anhängen eines Leerzeichens als letztes Zeichen eines Argumentes. Falls keine Argumente angegeben wurden, liest calc von der Standard-Eingabe. Hierbei werden arithmetische Ausdrücke durch ein Semikolon (;), ein Newline-Zeichen (NL) oder Eingabeende beendet. Ein Leerzeichen zur Ausgabeunterdrückung muß vor den vorgenannten Endemarkierungen stehen. Wenn beim Lesen von der Standard-Eingabe diese mit einem Gerät (z.B. Tastatur) verknüpft ist, beendet ein ^D (Ctrl-D) am Zeilenanfang die Eingabe. calc hat 26 interne Variablen a,b,c,d,...,z . Definierte Inhalte bleiben während eines Aufrufs des Kommandos erhalten. Lesezugriff auf eine nichtgesetzte Variable ist ein Fehler. Bei Ganzzahloperationen wird (zwischendurch) mit 32 Bit gerechnet. Generell wird gleitkommamäßig operiert, und zwar mit mindestens 15-stelliger Signifikanz, unter DOS 19-stellig, unter HPUX 15/31-stellig. calc berücksichtigt die folgenden Umgebungsvariablen (Environment): CALCAUTOR Um die Autoren-Meldung zu unterdrücken: CALCAUTOR=H.Schellong,Vlotho CALCPROGRAM Um die Freeware-Meldung zu unterdrücken: CALCPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (CALCAUTOR muß hierfür auch gesetzt sein.) Einstellungen und Kommandos: deg Argumente in Grad bei sin, cos, tan, cot, asin, acos, atan, acot, u.a. (default) rad Argumente in Radiant dhob Zahlendarstellung dezimal, hexadezimal, oktal und bit. Eingabe beliebig, jedoch mindestens 2 Buchstaben, gegebenenfalls doppelt wie z.B. 'dd'. Bei Eingabe gilt gleiche Darstellung wie bei Ausgabe. PI Zeigen die Zahlen pi, e und w2 mit bis zu 99 Nachkommastellen. EU (Dies sind lediglich Zeichenketten-Ausgaben.) QW Operatoren: dyadisch: + - * / % ** // & ^ | << >> monadisch: + - " : ! ~ # Klammern: () [] {} <> + Addition (unär = Absolutwert |x|) - Subtraktion (auch unär) * Multiplikation / Division % Divisionsrest (modulo) " Quadrat, (unär/monadisch) : Quadratwurzel, (unär/monadisch) ** Potenzierung für GANZzahlige Exponenten (s.pow()) // N'te Wurzel aus x & Binäre UND(AND)-Verknüpfung | Binäre ODER(OR)-Verknüpfung ^ Binäre EXOR-Verknüpfung ~ Binäres NICHT(NOT), (unär) << Links-Schieben >> Rechts-Schieben ! Fakultät, (unär) (!6 = 1·2·3·4·5·6 = 720) (<=!1754) <{[()]}> Klammern #c liefert Zeichensatz-Wert des Zeichens 'c' , Komma als Trenner bei >=2 Funktionsargumenten Der Vorrang der Operatoren entspricht üblichen Gepflogenheiten. Punkt- geht vor Strichrechnung, unäre Operatoren haben Vorrang vor dyadischen und werden von rechts nach links abgearbeitet. Ausnahme bildet die Zuweisung per '=' (siehe unten). Syntax / Beispiele: Es dürfen Leerzeichen, Tabs und NewLines eingefügt werden. (Stellenweise Spezialbedeutung der NL siehe oben.) Der Multiplikations-Operator '*' kann oft weggelassen werden: 4(a+3)(66-18)f entspricht 4*(a+3)*(66-18)*f a b 51 entspricht a*b*51 b=5 d=b a= 3+12.68+(b-1)c( 11+pow(3,b=5*17)b )-32.4--d+!8 a 36 nk(49,6) + b= 1100100b&~(1<<5) h=i=j=k= a b c :3 ""5 44.52 Funktionen: y= pi() y= eu() y= sqrt(x) y= sin(x) y= cos(x) y= tan(x) y= cot(x) y= asin(x) y= acos(x) y= atan(x) y= acot(x) y= sinh(x) y= cosh(x) y= tanh(x) y= coth(x) y= asinh(x) y= acosh(x) y= atanh(x) y= acoth(x) y= lg(x) y= ln(x) y= ld(x) y= ilg(x) y= iln(x) y= ild(x) y= abs(x) y= rnd(x) y= up(x) y= dwn(x) -y= chop(x) y= ichop(x) y= fak(x) 2y= xtract(x) 3y= dsm(x) y= log(a,b) y= pow(a,b) y= powi(a,b) y= root(a,b) y= prem(a,b) -y= scale(a,b) y= nk(a,b) y= zz(a,b) y= rp(a,b) -2y= ctop(a,b) -2y= ptoc(a,b) -3y= zze(a,b,c) -2y= quaequ(a,b,c) y= smd(a,b,c) Bei 2 oder 3 Resultatwerten werden die Variablen u und v belegt. -) Funktion nicht in jeder OS-Version vorhanden. Funktionsbeschreibungen: pi(0) Liefert die Zahl PI eu(0) Liefert die Eulersche Zahl e= iln(1) sqrt(1) QuadratWurzel sin(1) Sinus (Beachte rad/deg !) cos(1) CoSinus tan(1) Tangens cot(1) CoTangens asin(1) ArcusSinus (sin-Umkehrfunktion) acos(1) ArcusCoSinus atan(1) ArcusTangens acot(1) ArcusCoTangens sinh(1) SinusHyperbolicus cosh(1) CoSinusHyperbolicus tanh(1) TangensHyperbolicus coth(1) CoTangensHyperbolicus asinh(1) AreaSinusHyperbolicus (sinh-Umkehrfunktion) acosh(1) AreaCoSinusHyperbolicus atanh(1) AreaTangensHyperbolicus acoth(1) AreaCoTangensHyperbolicus lg(1) Dekadischer(Zehner-) Logarithmus, zur Basis 10 ln(1) Natürlicher Logarithmus, zur Basis e ld(1) Logarithmus Dualis, zur Basis 2 (ld(16)=4; 2^4=16) ilg(1) lg-Umkehrfunktion (z.B. ilg(2)=10²=100) iln(1) ln-Umkehrfunktion ild(1) ld-Umkehrfunktion abs(1) Absolutwert |x| (Ergebnis ist immer positiv) rnd(1) Rundet zur nächstliegenden ganzen Zahl ab/auf up(1) Rundet in Richtung +unendlich dwn(1) Rundet in Richtung -unendlich chop(1) Rundet in Richtung 0 ichop(1) Schneidet die Vorkommastellen ab fak(1) Fakultät von 4= 1·2·3·4 = 24 (x<=170 / x<=1754) xtract(1) Extrahiert Signif.u.Expon.: s·(2)^n = (x); dsm(1) Stunden,Minuten,Sekunden = (Dezimalzeit) log(2) Logarithmus, n= log(beliebige Basis b, y) pow(2) Potenzierung y=bü (log-Umkehrfunktion) powi(2) Potenzierung für ganzzahlige Exponenten n root(2) y= n-te Wurzel von x; y= (x, n) prem(2) Divisionsrest von q/d: r= (q, d) scale(2) y= s·2^n; y= (s, n) nk(2) n über k; lotto= nk(49,6), 6 aus 49 zz(2) y= wurzel(a²+b²); Hypotenuse, Betrag |Z| komplexe Zahl rp(2) y= 1/(1/a+1/b); z.B. Widerstände parallel ctop(2) Kartesische Koordinaten zu Polaren: r,pi= (x,y) ptoc(2) Polare Koordinaten zu Kartesischen: x,y = (r,pi) zze(3) |Z|,a1,jb1 = (a0, jb0, exponent); (a+jb)^n quaequ(3) x1,x2= (a,b,c); Quadratische Gleichung smd(3) Dezimalzeit = (Stunden, Minuten, Sekunden) BEISPIELE (siehe auch bish-Kommandosyntax.) calc "a=12.7 " "f=0.8 " "4(a+3)(66-18)f" 2411.52 echo "b=5 ;c=d=b ; a= 3+12.68+(b-1)c[ 11+pow(3,b=5*17)b ]-32.4--d+!8 ; a" | calc 6.10598274310663e+43 (Zwei Semikoli sind hier redundant!) calc dhob 36 36 000000024h 00000000044o 00000000000000000000000000100100b calc "nk(49,6) + b= 1100100b&~(1<<5)" 'h=i=j=k= 4 b 5 :3 ""5 44.52' 13983884 65544266.6600214 calc < arithmetik_datei LIMITS 2048 Byte Beim Lesen von der Standard-Eingabe. 256 Byte Arithmetischer Ausdruck. EXIT-CODE 0 Letztes Resultat war ungleich Null (0.0). 1 Letztes Resultat war gleich Null (0.0). 2 Bei Fehlern. 3 Bei Abbruch wegen SIGNAL. SIEHE AUCH bish(K). AUTOR Dieses Kommando calc wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
comx(K) comx(K) UNIX-Variante (VBM) NAME com - Kommunikation über serielle Schnittstelle ext - Kommunikation über serielle Schnittstelle (intern bish(K)) SYNTAX com +[LBM#T#A#H#] /dev/term/0{0|1|2|3}[m|h|s|t] com -B#focicoD#iD#od#id#ot#it#iO#oO#o[#]i[#] [ name ] com -spH [ name|handle ] com -|+b[1|0]nnn com - ext (wie com) $. BESCHREIBUNG Die Kommandos com/ext lesen aus der Shell-Variablen 'name' und schreiben zur seriellen Schnittstelle und/oder lesen von der seriellen Schnittstelle und schreiben in die Variable 'name'. Die Anzahl geschriebener/gelesener Zeichen kann der Spezial-Shell-Variablen '$.' entnommen werden, bei gegebener Option o und/oder i (nicht ic oc it ot ...). Kommandozeilen-Optionen: + Gerätedatei Angegebenes Device wird geöffnet mit -B9600. tty-Device-Namen sind system-spezifisch: /dev/tty1A /dev/term/01m ... +LB Gerätedatei Bei 'L' und/oder 'B' wird CLOCAL gesetzt bzw. O_NONBLOCK nicht gesetzt. +M# Gerätedatei uchar c_cc[VMIN]=#; wird gesetzt. (0) +T# Gerätedatei uchar c_cc[VTIME]=#; wird gesetzt. (0) 1 entspricht 0.1 sec. +A# Gerätedatei Assoziation Controlling Terminal (Falls O_NOCTTY fehlt) ioctl(fd, TIOCNOTTY, 0|1); +H# Angabe eines Handle. open() wird nicht verwendet. - Zuvor geöffnetes Device wird geschlossen. -s Ausgabe des Status (7 Bits): "bbbbbbb rts,cts,dtr,dsr,cd,ri,le" Ausgabe zur Standard-Ausgabe, falls kein 'name' angegeben ist, andernfalls Ausgabe in 'name' oder zum angegebenen Handle. tty-Ausgabe mit "rts,cts,...\n". Hiernach sofortiger Exit! (TRUE) -p PEEK: ist ein Eingabezeichen lesbar vorhanden? Falls ja: Ausgabe zum angegebenen Handle oder Ausgabe in 'name'. (Binärmodus) Variablenlänge==1 ggf. danach. Ohne Argument verbleibt der Exit-Code. Ein gelesenes Zeichen verbleibt lesbar im Puffer. Hiernach sofortiger Exit! Exit: TRUE/FALSE (0/1) -H Ausgabe des Handle. Hiernach sofortiger Exit! -B# Einstellung der Schnittstellengeschwindigkeit (baud): 9600 19200 38400 57600 115200 4800 2400 1800 1200 600 300 50 75 0 110 134 150 200 -f FLASH: Ausgabe-Puffer wird ausgeschrieben. Wartet auf Komplettierung! tcdrain(fd) -oc Ausgabepuffer löschen (clear). -ic Eingabepuffer löschen (clear). -c Beide Puffer löschen. (c ohne [oi] davor) -D# Delay (ohne o|i davor) -oD# Ausgabe-Delay nach write()<=0 (-oD10) -iD# Eingabe-Delay nach read()<=0 (-iD10) -od# Ausgabe-Delay nach Fehlendem (-od10) -id# Eingabe-Delay nach Fehlendem (-id10) -ot# Ausgabe-Timeout (-ot0) -it# Eingabe-Timeout (-it0) (Alle Zeiten in ms. Granularität meistens 10ms. Kleinere Werte werden meist aufgerundet.) -oO# Setzt den o-Offset in der io-Variable. -iO# Setzt den i-Offset in der io-Variable. -O# Setzt beide Offsets. (ohne o|i davor) (Voreingestellt ist 0) -o# Ausgabe von maximal # Bytes. -i# Eingabe von maximal # Bytes. Ohne Zahlen # wird 2^31-1 angenommen. -bnnn nnn= rts|cts|dtr|dsr|cd|ri|le Testet, ob angegebenes Bit gesetzt ist. Antwortet mit einem entsprechenden Exit-Code. Hiernach sofortiger Exit! +b[1|0]nnn Setzt ein angegebenes Bit auf 1 oder 0. (set/clear) Ohne [1|0] wird 1 (set) angenommen. Hiernach sofortiger Exit! Exit=TRUE, wenn kein Fehler. Die Optionen können (prinzipiell) in beliebiger Kombination und Reihenfolge mittels eines(!) Argumentes angegeben werden. Die Reihenfolge wird aktionsmäßig berücksichtigt, allerdings bei gleichzeitig -oi gilt immer: o, dann i. Optionen nach -spb sind sinnlos, wegen jeweiligem sofortigen Exit. Bei mehreren Optionen ist die Herkunft eines eventuellen FALSE-Exit nicht feststellbar. Als Fehlendes wird gewertet, wenn die angegebene Byte-Anzahl nicht mit einem einzigen read()/write() 'erledigt' werden konnte. Es wird dann -d# ms gewartet und erneut versucht, bis d#-Summe > t# . Der Maximal-Wert bei -o# wird auf die Inhaltslänge der Variable 'name' gesetzt, falls diese geringer ist. Maximal-Wert bei -i# : Ein bereits existierender Variableninhalt wird mit maximal # Bytes überschrieben, falls dieser Inhalt größer/gleich # oder größer/gleich 8*1024 Byte ist. Die bestehende Inhaltslänge wird nicht verändert. Andernfalls wird der Puffer dieses Kommandos (8*1024 Byte) verwendet, um eine Variable zu erzeugen oder deren Inhalt zu verlängern - bis maximal 8*1024 Byte. Variablen können viel größer sein als 8*1024 Byte. Bei gleichzeitiger Angabe von o und i kann mit einem einzelnen Kommando-Aufruf geschrieben und danach gelesen werden. In $. steht dann jedoch die abschließende i-Anzahl, während die o-Anzahl verloren ist. Achtung!: $. wird von 'conv' und 'cmpv' ebenfalls gesetzt, und hat den Startwert -1 . BEISPIEL extinp="@EEDATA:" ext -B9600cit2500id20oi extinp echo $extinp nread=$. EXIT-CODE 0 falls nicht anders angegeben 1 bei Fehler/Fehlschlag/FALSE-Situation AUTOR Dieses Kommando comx wurde entwickelt von: Helmut Schellong, Bad Salzuflen Copyright © 2002 CIE Convertronic GmbH, Kirchlengern Copyright © 2002 Helmut Schellong, Bad Salzuflen ------------------------------------------------------------------------------ Variante: DOS 16Bit (Beck@IPC) NAME com - Kommunikation über serielle Schnittstelle 'com' ext - Kommunikation über serielle Schnittstelle 'ext' (intern bish(K)) bish-Portierung für Embedded-DOS IPC@CHIP(Fa.Beck) SYNTAX com -spb#h[#]focicod#id#ot#it#oT#iT#o[#]i[#] [ name ] com com - ext (siehe oben) ext ext - $. BESCHREIBUNG Die Kommandos com/ext lesen aus der Shell-Variablen 'name' und schreiben zur seriellen Schnittstelle und/oder lesen von der seriellen Schnittstelle und schreiben in die Variable 'name'. Die Anzahl geschriebener/gelesener Zeichen können der Spezial-Shell-Variablen '$.' entnommen werden, bei gegebener Option o und/oder i (nicht ic oc it ot ...). Kommandozeilen-Optionen: -s Ausgabe des Status bbbbbbb (7 Bits: 6543210) 6 Ausgabepuffer leer 5 Ausgabepuffer nicht voll 4 Line-Break empfangen 3 Frame-Fehler 2 Parity-Fehler 1 Overrun Eingabepuffer 0 Eingabepuffer nicht leer Ausgabe zur Standard-Ausgabe, falls kein 'name' angegeben ist, andernfalls Ausgabe in 'name'. (Textmodus) Hiernach sofortiger Exit! (TRUE) -p PEEK: ist ein Eingabezeichen lesbar vorhanden? Falls ja: Ausgabe zur Standard-Ausgabe, falls kein 'name' angegeben ist, andernfalls Ausgabe in 'name'. (Binärmodus) Ein gelesenes Zeichen verbleibt lesbar im Puffer. Hiernach sofortiger Exit! Exit: TRUE/FALSE -b# Einstellung der Schnittstellengeschwindigkeit (baud): b3840 (38400) b19200 b9600 b4800 b2400 b1200 b600 b300 Danach sollte man mit ic und oc die Puffer löschen. -h Hardware-Handshake (rts/cts) EIN -h1 Hardware-Handshake (rts/cts) EIN -h0 Hardware-Handshake (rts/cts) AUS -f FLASH: Ausgabe-Puffer wird ausgeschrieben. Wartet auf Komplettierung! -oc Ausgabepuffer löschen (clear). -ic Eingabepuffer löschen (clear). -od# Ausgabe-Delay nach Zeichenfehlschlag d0..32767 -id# Eingabe-Delay nach Zeichenfehlschlag d0..32767 -ot# Ausgabe-Timeout t0..32767 ab 2. Fehlschlag -it# Eingabe-Timeout t0..32767 ab 2. Fehlschlag -oT# Ausgabe-Timeout T0..32767 Gesamt-Delay -iT# Eingabe-Timeout T0..32767 Gesamt-Delay (Alle Zeiten in ms) -o# Ausgabe von maximal # Bytes. -i# Eingabe von maximal # Bytes. Ohne Zahlen # wird 32767 angenommen. Die Optionen können in beliebiger Kombination und Reihenfolge mittels eines(!) Argumentes angegeben werden. Die Reihenfolge wird aktionsmäßig berücksichtigt, allerdings bei gleichzeitig -oi gilt immer: o, dann i. Optionen nach -s oder -p sind sinnlos, wegen jeweiligem sofortigen Exit. Bei jeglicher erster Verwendung wird die Schnittstelle initialisiert. Beispielsweise bei 'com'. Bei Init-Erfolg wird Exit=0 (TRUE) gegeben. Explizite Deinitialisierung erfolgt durch 'com -'. Falls eine Schnittstelle STDIN/STDOUT zugeordnet ist, ist das nach Init nicht mehr der Fall, aber wieder nach De-Init. Die bish macht vor ihrem Exit automatisch De-Init. Nur eine Task kann eine Schnittstelle 'besitzen'. Der Maximal-Wert bei -o# wird auf die Inhaltslänge der Variable 'name' gesetzt, falls diese geringer ist. Maximal-Wert bei -i# : Ein bereits existierender Variableninhalt wird mit maximal # Bytes überschrieben, falls dieser Inhalt größer/gleich # oder größer/gleich 1024 Byte ist. Die bestehende Inhaltslänge wird nicht verändert. Andernfalls wird der Puffer dieses Kommandos (1024 Byte) verwendet, um eine Variable zu erzeugen oder deren Inhalt zu verlängern - bis maximal 1024 Byte. Variablen können sehr viel größer sein als 1024 Byte. Bei gleichzeitiger Angabe von o und i kann mit einem einzelnen Kommando-Aufruf geschrieben und danach gelesen werden. In $. steht dann jedoch die abschließende i-Anzahl, während die o-Anzahl verloren ist. Achtung!: $. wird von 'conv' und 'cmpv' ebenfalls gesetzt, und hat den Startwert -1 . BEISPIEL extinp="@DK40:" ext -b9600icocit2000id10oi extinp echo $extinp nread=$. EXIT-CODE 0 falls nicht anders angegeben 1 bei Fehler/Fehlschlag/FALSE-Situation AUTOR Dieses Kommando comx wurde entwickelt von: Helmut Schellong, Bad Salzuflen Copyright © 2001 CIE Convertronic GmbH, Kirchlengern Copyright © 2001 Helmut Schellong, Bad Salzuflen |
dat(K) dat(K) NAME dat.exe - Setzt oder zeigt System-Datum und -Uhrzeit SYNTAX dat [ TTMMJJhhmmss ] BESCHREIBUNG Das Kommando dat (date_and_time) setzt die Systemzeit oder zeigt sie an. Wenn kein Argument angegeben wurde, wird die aktuelle Systemzeit zur Standard-Ausgabe geschrieben. Das Ausgabe-Format ist mit dem oben gezeigten Eingabe-Format identisch. Bedeutung der Buchstaben in der Zeitangabe: Tag, Monat, Jahr, hour(Stunde), minute, sekunde. Es müssen gegebenenfalls führende Nullen (0) angegeben werden. Als Jahreszahl können Werte von 00 bis 99 angegeben werden. Daraus resultieren die Jahre 1980 bis 2079. (80...99 --> 1980...1999 und 00...79 --> 2000...2079) Bei der Ausgabe wird auf volle Sekunden aufgerundet. dat berücksichtigt die folgenden Umgebungsvariablen (Environment): BSHAUTOR Um die Autoren-Meldung zu unterdrücken: BSHAUTOR=H.Schellong,Vlotho DATPROGRAM Um die Freeware-Meldung zu unterdrücken: DATPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (BSHAUTOR muß hierfür auch gesetzt sein.) BEISPIELE dat 011194223344 Setzt die Systemzeit auf 01.11.1994, 22:33:44 Uhr. dat Zeigt die aktuelle Systemzeit. ADT=`dat` dat 011194223344 ... dat $ADT Setzt die Systemzeit vorübergehend auf einen bestimmten Wert. Die Aktion (...) sollte nicht zu lange dauern. (Wer zu spät kommt ...) EXIT-CODE 0 Kein Fehler. 1 Fehler bei den Optionen. SIEHE AUCH bish(K), touch(K). AUTOR Das Kommando dat wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
dd(K) dd(K) NAME dd.exe - Liest und schreibt Daten blockweise ein/aus SYNTAX dd [if=idatei] [of=odatei] [bs=n] [ibs=n] [obs=n] [count=n] [skip=n | iseek=n] [seek=n | oseek=n] [bmode=n] [ibmode=n] [obmode=n] [conv=bmode] [conv=notrunc] [noinfo] dd [ if={h|f}d{0-3}:[c#h#s#] ] [ of={h|f}d{0-3}:[c#h#s#] ] [s.o.] dd calc=n n: #[{b|k|w|l}][{x|+}#[{b|k|w|l}]]...[{x|+|-}#[{b|k|w|l}]] #: [0]...{1-9}...[{0-9}]... BESCHREIBUNG Das Kommando dd liest blockweise aus einer Eingabedatei und schreibt blockweise in eine Ausgabedatei. Die Blockgrößen können unabhängig voneinander eingestellt werden. Voreingestellt als Eingabe- und Ausgabedatei sind die Standard- -Eingabe und die Standard-Ausgabe. Geräte, wie Festplatten und Diskettenlaufwerke, können ebenfalls für Eingabe und Ausgabe angegeben werden. Dateien werden ausschließlich im Binär-Modus geöffnet. Dieses dd hat eine Fortschritt-Anzeige: 0000%% 00000 MB dd berücksichtigt die folgenden Kommandozeilen-Optionen: if=datei Angabe der Eingabedatei. (Voreinstellung: Standard-Eingabe) of=datei Angabe der Ausgabedatei. (Voreinstellung: Standard-Ausgabe) ibs=n Blockgröße in Bytes bei der Eingabe. obs=n Blockgröße in Bytes bei der Ausgabe. bs=n Blockgröße in Bytes für Eingabe und Ausgabe. Vorrang vor ibs und obs. count=n Anzahl der Eingabe-Blöcke, die maximal gelesen werden. Ohne diese Angabe wird bis Eingabeende gelesen. skip=n Anzahl der Eingabe-Blöcke, iseek=n die übersprungen werden, bevor gelesen wird. skip erzwingt das tatsächliche Lesen von Daten anstelle eines Überspringens. Solchermaßen gelesene Daten werden weggeworfen. Sinnvoll bei Eingabegeräten, die nicht positionierbar (seekable) sind. seek=n Anzahl der Ausgabe-Blöcke, oseek=n die übersprungen werden, bevor geschrieben wird. bmode=n Angabe derjenigen Blockgröße, mit der der ibmode=n direkte Zugriff bei Ein- und Ausgabe erfolgt. obmode=n (In der Regel Bytes pro Sektor bei Disks.) Analog zu bs, ibs, obs; bmode hat Vorrang vor ibmode und obmode. Dieser Pufferungsmechanismus ist dem oben beschriebenen nachgeschaltet. Wenn Festplatten oder Floppies angegeben sind, wird automatisch auf 512 gesetzt. Explizite Angaben (2...2048) haben Vorrang. Bei der UNIX-Version dieses dd-Kommandos zeigt eine explizite Angabe hier an, daß der Dateiname hinter if=/of= eine Disk repräsentiert. conv=bmode Entspricht bmode=512. conv=notrunc Verhindert das Setzen einer vorhandenen Ausgabedatei auf Dateigröße=0 vor Schreibbeginn. Es kann dann mitten in eine bestehende Datei hinein geschrieben werden. Normalerweise werden bei seek=größer_null entsprechend viele Null-Zeichen geschrieben, bevor die Übertragung In->Out beginnt. Disks werden selbstverständlich nicht gelöscht, wenn diese Option fehlt. noinfo Die Abschlußmeldung wird abgeschaltet. (s.unten: DIAGNOSE) calc=n Dient zur Überprüfung der arithmetischen Ausdrücke, für die ``n'' steht. Beispiel: calc=33bx4x15+1200+25-3l entspricht calc=1014973 x ist ein Multiplikations-Operator. b entspricht x512 k entspricht x1024 w entspricht x2 l entspricht x4 Zugriff auf Festplatten und Diskettenlaufwerke: if= / of=hd0:c#h#s# if= / of=hd1:c#h#s# if= / of=hd2:c#h#s# if= / of=hd3:c#h#s# if= / of=fd0:c#h#s# if= / of=fd1:c#h#s# if= / of=fd2:c#h#s# if= / of=fd3:c#h#s# if= / of=hd0: siehe nachfolgend: Angabe der Anzahlen für Zylinder(c)/Köpfe(h)/Sektoren(s): c#h#s# Wenn die folgenden Umgebungsvariablen gesetzt sind, können diese Angaben in der Kommandozeile entfallen: DD_HD0=c#h#s# DD_HD1=c#h#s# DD_FD1=c#h#s# ... Der Doppelpunkt (:) muß dann trotzdem angegeben werden: z.B. if=hd0: Beispiel: DD_HD1=c1023h16s63 504 MB DD_HD2=c833h6s31 80 MB DD_HD0=c19650h16s63 9671 MB DD_HD0=c1024h255s63 <9671 MB (LBA: max.8033MB) DD_FD0=c80h2s18 1440 3½" DD_FD0=c80h2s9 720 3½" DD_FD1=c80h2s15 1200 5¼" DD_FD1=c40h2s9 360 5¼" Die chs-Angaben sind die Anzahlen, nicht der höchste Wert von-bis. Wenn von der Standard-Eingabe gelesen wird und diese mit einem zeichenorientierten Gerät verknüpft ist, kommt eine Spezialsyntax zur Eingabe von (nichtabdruckbaren) Zeichen in Funktion. Ein Backslash (\) gefolgt von ein bis drei Digits 0...9 wird in die entsprechende Zahl 0...255 umgewandelt. Beendet wird, sobald drei Digits gelesen wurden oder ein Nichtdigit erreicht ist. Zwei Backslash (\\) werden zu einem (\) ohne Spezialbedeutung reduziert. Ein \ gefolgt von einem gewöhnlichen Zeichen (alle außer [\0-9]) ist ebenfalls gewöhnlich. Anhängende Zeilenvorschübe (NL) werden entfernt; man kann explizit \10 angeben. Mit ^D (Ctrl-D) bzw. ^Z wird eine solche Tastatur-Eingabe beendet. Für die Standard-Ausgabe gilt analog entsprechendes: Die Zeichenwerte 0-32,127,155 und 255 werden zu '\ddd' umgeformt, etc. Ein \ wird immer zu \\ erweitert. Diese Konversionen können einen Hex/Dez/Oct-Präsentator natürlich nicht ersetzen. Sie sind dafür, falls man einmal doch nicht mit Dateien arbeiten will, was für dieses Kommando untypisch ist. dd versucht stets, Einheiten ausschließlich in den angegebenen Blockgrößen zu bilden. Dazu werden unter anderem Teilbereiche im Puffer verschoben. Nur ganz zum Schluß muß unter Umständen gestückelt werden. Der interne Puffer ist 63b groß. Wird eine größere Blockgröße angegeben, muß zwangsläufig gestückelt werden. Bei Disks werden unter allen Umständen nur ganze Sektoren gelesen oder geschrieben. Dazu wird u.a., falls erforderlich, ein Sektor gelesen, teilweise geändert, und anschließend als Ganzes zurückgeschrieben. Gleichzeitig werden stets maximal viele Sektoren einer Spur auf einmal gelesen oder geschrieben. dd berücksichtigt auch die folgende Umgebungsvariable (Environment): DDAUTOR Um die Autorenmeldung abzuschalten: DDAUTOR=H.Schellong,Vlotho DDPROGRAM Um die Freeware-Meldung zu unterdrücken: DDPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung DDPROGRAM=FreeLizenz_Software_von_Helmut_Schellong (DDAUTOR muß hierfür auch gesetzt sein.) WARNUNGEN Bei arithmetischen Ausdrücken sollte ein Minuszeichen gegebenenfalls nur vor der letzten Zahl stehen. Sonst gibt es unerwartete Resultate. Man beachte, daß bei count,skip,seek eine Anzahl BLÖCKE festgelegt wird, und nicht Bytes! Falls man im BIOS eine zweite Festplatte (slave) als Bootplatte angibt (z.B. D,A statt A,C), dann ist diese 'D' 'hd0' für 'dd' und die Hauptplatte 'hd1'. Das BIOS macht das halt so, man muß das ggf. durch Lesen mal probieren, ob das bei einem selbst auch so ist. HINWEISE Die Bezeichnungen a:, b:, c:, ... für Disks unter DOS wurden absichtlich nicht als Syntax gewählt, weil auf physikalische Laufwerke zugegriffen wird. Beispielsweise ist c: die DOS-Abteilung einer Festplatte und nicht der wirkliche Beginn, der mit Masterboot und Haupt-Partitionstabelle beginnt. Unter DOS können maximal 1023 cyl erreicht werden - über 503 MB kommt man also nicht hinaus! Mit LBA-Einstellung allerdings doch, und zwar bis 8033 MB. (s.o.) Per LBA können 1023*255*63+254*63+63 Sektoren erreicht werden. Wenn beispielsweise von einer Festplatte gelesen und in eine Datei geschrieben wird, wird man in der Regel eine heftige Kopfaktivität feststellen, weil die Datei sich meistens auf der selben Festplatte befindet - allerdings an anderer Position. Der Puffer des Kommandos ist (nur) 63*512 Bytes groß, weshalb eine wiederkehrende Kopfumpositionierung erfolgt. Anlegen der Datei in einer RAM-Disk bringt hier Abhilfe - wenn man sehr intensiv in dieser Weise mit dd arbeitet. Oder auch bs=63b als Mindestblockung angeben und mit Spur-Nummern anstatt mit Sektor-Nummern arbeiten; dennoch ist eine RAM-Disk wesentlich besser. Bei Floppies schlägt der erste Zugriff fast immer fehl. Zumindest wenn man nach Systemstart darauf zugreift, ohne irgendeinen Zugriff zuvor. dd versucht bis zu dreimal, erfolgreich zu sein, mit Pausen von einer Sekunde vor jedem Neuversuch. Blindlesezugriff bis dd-Exit==0 empfiehlt sich hier, falls das noch nicht ausreichen sollte. Die Optionen bmode,ibmode,obmode,noinfo,calc sind in den UNIX-Originalen dieses Kommandos nicht vorhanden. Das gilt auch für die speziellen Disk-Namen hd0:,..., weil unter UNIX Disks und alle anderen Geräte normale Dateinamen haben. Die Umwandlungen bei Standard-Ein- und -Ausgabe (\ddd) fehlen auch. Options-Arithmetik: n: #[{b|k|w}][x#[{b|k|w}]]...[x#[{b|k|w}]] Dafür fehlen diesem dd: cbs=n und conv=conversion_option . Bei der Eingabe von der Tastatur ist zu beachten, daß bei einer angegebenen Blockgröße ibs=s / bs=s und count=n n Zeilen mit je s Zeichen gelesen (angefordert) werden. Überzählige Zeichen pro Zeile werden ignoriert. '\ddd' gilt selbstverständlich als ein (1) Zeichen. Mit ^D bzw. ^Z kann man vorzeitig beenden. (s.o.) BEISPIELE Liest eine 1440K-Floppy und erzeugt eine Datei von 1474560 Byte Größe: dd if=fd0:c80h2s18 of=datei bs=18k count=80 Schreibt ein Byte zur Festplatte: Und zwar wird eine erweiterte DOS-Partition unkenntlich gemacht, die normalerweise \4 oder \6 dort stehen hat. Gelesen wird von der Standard-Eingabe. dd of=hd0: bs=1 count=1 seek=828576b+450 \000 ^D (^Z) Sicherer ist der Umweg über eine Datei: dd if=hd0: of=datei512 bs=1b count=1 iseek=828576 ... dd if=datei512 of=hd0: bs=1b count=1 oseek=828576 Es werden nacheinander Bootblock, Fat1, Fat2 und Root-Directory von einer 1440-Floppy gelesen: dd if=fd0: of=boot bs=1b count=1 [iseek=0] dd if=fd0: of=fat1 bs=1b count=9 iseek=1 dd if=fd0: of=fat2 bs=1b count=9 iseek=10 dd if=fd0: of=root bs=1b count=14 iseek=19 Der Bootblock und der Anfang der ersten FAT werden gelesen: dd if=hd0:c1024h255s63 of=bf bs=1b iseek=11612160 count=3 Der Startsektor 11612160 ist beispielhaft; LBA. dd if=hd0:c1024h255s63 of=bf bs=63b iseek=184320 count=1 Dies ist die gleiche Position, nur schwächer geblockt und 63*512 statt 3*512 Dateigröße. 184320 ist die Spur(track)-Nummer (11612160/63=184320). DIAGNOSE Meldung auf die Standard-Ausgabe: n blocks + n bytes in n blocks + n bytes out (Kann abgeschaltet werden.) Fehlermeldungen. Es ist eine Fortschritt-Anzeige implementiert: Promille + MByte, die ab 1 MB arbeitet. Ohne Angabe von count=x stimmt die %%-Angabe nicht. Auch diese Anzeige kann durch 'noinfo' abgeschaltet werden. EXIT-CODE 0 Kein Fehler. 1 Fehlerhafte Argumentliste. 2 Benötigte Variable undefiniert. 3 Dateiöffnen fehlgeschlagen. 4 Fehler von Systemfunktion. 5 Fehler beim Dateilesen. 6 Fehler beim Dateischreiben. SIEHE AUCH bish(K), hx(K), cmp(K). AUTOR Dieses Kommando dd wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
hx(K) hx(K) NAME hx.exe - Wandelt Daten um in lesbare Darstellungsformen hx (intern bish(K)) SYNTAX hx [-a[d][b]] [-b[d][b]] [-t[g78d]] [-o[0]N] [-nN] [-[-]] [datei ...] h k h w H K H l [x]N c[g78d] N: #[{b|k|w|l}][{x|+}#[{b|k|w|l}]]...[{x|+|-}#[{b|k|w|l}]] #: [0]...{1-9}...[{0-9}]... BESCHREIBUNG Das Kommando hx liest Daten aus einer oder mehreren Eingabedateien und schreibt sie formatiert zur Standard-Ausgabe. Wenn keine Dateien angegeben sind, liest hx von der Standard-Eingabe. Falls diese dabei mit einem zeichenorientierten Gerät verknüpft ist, kann die Eingabe mittels Eingabe von ^D (Ctrl-D) bzw. ^Z beendet werden. Dateien werden ausschließlich im Binär-Modus geöffnet. Bei Angabe von zwei oder mehr Dateien wird der Dateiname jeweils zu Anfang ausgegeben. hx verfügt über mehrere wählbare Darstellungsformen bei der Ausgabe. Für eine Zahl 'N', die an drei Stellen angegeben kann, gibt es eine eigene Arithmetik-Syntax (s.u.). hx berücksichtigt fünf Haupt-Optionen, mit bis zu zwei Gruppen von dazugehörenden Unter-Optionen. Die Kommandozeilen-Optionen sind im einzelnen: -a Darstellung der Adresse am Zeilenbeginn. -b Darstellung der Bytes. (16 oder 64 pro Zeile) -t Zusätzliche Textdarstellung der Bytes am Zeilenende. -o Angabe, wieviel Bytes zu Beginn ignoriert werden sollen. -n Angabe, wieviel Bytes (maximal) gelesen werden sollen. -: Ersetzt bei einigen Formaten den ':' durch Leerzeichen. - Nachfolgende Argumente werden als Dateinamen -- aufgefaßt, auch wenn sie mit '-' beginnen. -a Darstellung der Adresse am Zeilenbeginn. Ohne Unteroption wird die Adressenausgabe unterdrückt. dhH Darstellung dezimal, hexadezimal (abcdef) oder hexadezimal (ABCDEF). bkK Darstellung in Anzahl Blocks plus Anzahl Bytes: ##x+## wobei x für [bkK] steht. Blockgrößen: b,k,K = 512,1000,1024 (Bei zu langen Zeilen wird '+' weggelassen.) xN Per N kann eine beliebige Blockgröße eingestellt werden. x ist ein beliebiges Zeichen als Kennung. (N-Syntax siehe unten.) -b Darstellung der Bytes. (16 oder 64 pro Zeile) dhH Darstellung dezimal, hexadezimal (abcdef) und(!)/oder hexadezimal (ABCDEF). bwl Darstellung von 16 Bytes, 8 Wörtern und(!)/oder 4 Doppelworten (long). c[g78d] Textdarstellung, 64 Byte pro Zeile. Diese Unteroption hat Vorrang vor den anderen und schaltet die Hauptoption -t ab. Voreingestellt ist (c)g. ([g78d] siehe unten -t.) -t Zusätzliche Textdarstellung der 16 Bytes am Zeilenende. Es sind verschiedene Ersetzungen der nichtabdruckbaren Zeichen und der Zeichen aus der oberen Hälfte des Zeichensatzes einstellbar: g Kontrollzeichen='.'; Werte>127='·' außer äöüÄÖÜß 7 Werte<' ' und Werte>=127 = '.' (ascii standard) 8 Kontrollzeichen='·' d Kontrollzeichen='?'; Null='_' Kontrollzeichen sind: 0...31,127,155,255 Ohne jede Unteroption wird diese Ausgabe abgeschaltet. -o[0]N Angabe, wieviel Bytes zu Beginn ignoriert werden sollen. Bei Dateien (seekable) wird zur angegebenen Byte-Adresse gesprungen. Beim Lesen von der Standard-Eingabe werden entsprechend viele Bytes überlesen. (Offset) Eine führende Null bewirkt, daß die ausgegebenen Adressen -trotz Offset- bei Null beginnen. Normalerweise zeigen die Adressen die tatsächliche Byte-Adresse. -nN Angabe, wieviel Bytes (maximal) gelesen werden sollen. Voreingestellt sind: -adb -bhb -tg -o0 -ninf Syntax für N: N: #[{b|k|w|l}][{x|+}#[{b|k|w|l}]]...[{x|+|-}#[{b|k|w|l}]] #: [0]...{1-9}...[{0-9}]... x ist ein Multiplikations-Operator. b entspricht x512 k entspricht x1024 w entspricht x2 l entspricht x4 Beispiel: -n33bx4x15+1200+25-3l entspricht -n1014973 hx berücksichtigt die folgenden Umgebungsvariablen (Environment): HXAUTOR Um die Autorenmeldung abzuschalten: HXAUTOR=H.Schellong,Vlotho HXPROGRAM Um die Freeware-Meldung zu unterdrücken: HXPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (HXAUTOR muß hierfür auch gesetzt sein.) Dies gilt nicht für das bish-interne hx. WARNUNG Bei arithmetischen Ausdrücken sollte ein Minuszeichen gegebenenfalls nur vor der letzten Zahl stehen. Sonst gibt es unerwartete Resultate. HINWEISE Die Unteroptionen werden nicht auf Fehlerhaltigkeit geprüft. Es werden von links nach rechts alle bekannten Optionen berücksichtigt, die -gegebenenfalls- vorher angegebene überschreiben oder rücksetzen. Man beachte, daß per Option -b ein und dieselbe Zeile bis zu neunmal in jeweils unterschiedlichem Format ausgegeben werden kann. Die Reihenfolge in den Unteroptionsgruppen wird berücksichtigt. Die zusätzliche Textausgabe per Option -t wird automatisch abgestellt, falls dadurch eine Zeile zu lang würde. Bei Darstellung von Wörtern oder Doppelwörtern kommt es vor, daß zum Schluß in der letzten Zeile weniger als 2 bzw. 4 Bytes pro Einheit vorhanden sind. In diesen Fällen werden auch die unvollständigen Einheiten dargestellt, entsprechend viele Null-Bytes enthaltend. BEISPIELE dd if=fd0: ... | hx -n16x23 Bringt die Daten, die das dd-Kommando ausgibt, in einer lesbaren Form auf den Bildschirm. dd if=fd0: ... | hx | pg Erweitert die Pipeline um das Kommando pg, ein Pager-Programm, das seitenweises Betrachten ermöglicht, ähnlich wie more. hx -n50 datei 0b+000 4c 01 04 00 db 91 e4 30 00 00 00 00 00 00 00 00 L...···0....... 0b+016 1c 00 0f 01 0b 01 00 00 40 11 00 00 6c 02 00 00 ........@...l.. 0b+032 c4 02 00 00 d4 00 00 00 d0 00 00 00 10 02 40 00 ·...·...·.....@ 0b+048 2e 74 .t hx -blh -n50 datei 0b+000 0004014c 30e491db 00000000 00000000 L...···0........ 0b+016 010f001c 0000010b 00001140 0000026c ........@...l... 0b+032 000002c4 000000d4 000000d0 00400210 ·...·...·.....@. 0b+048 0000742e .t DIAGNOSE Fehlermeldungen. EXIT-CODE 0 Kein Fehler. 1 Fehlerhafte Argumentliste. 2 Dateiöffnen fehlgeschlagen. 3 Fehler von Systemfunktion. 4 Fehler beim Dateilesen. SIEHE AUCH bish(K), pg(K), more(DOS), dd(K). AUTOR Dieses Kommando hx wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1995-2016 |
ov(K) ov(K) NAME ov.com - Setzt die Farbe der Overscan-Region des Bildschirms SYNTAX ov [-q] [0...63] prev=`ov #` curr=`ov` BESCHREIBUNG Das Kommando ov setzt die Farbe des äußersten Bildschirmrandes auf den angegebenen Wert. Der vorher eingestellte Wert wird zur Standard-Ausgabe geschrieben, sofern nicht Option -q gegeben ist, bei der der Exit-Wert des Kommandos auf den vorher gültigen Farbwert gesetzt wird. Bei fehlendem Zahlenwert wird lediglich das Setzen auf eine neue Farbe unterlassen. Es werden Werte von 0 bis 255 an die Hardware übermittelt als auch von der Hardware gelesen. Der Wert 63 ist jedenfalls für Standard-VGA der höchste, höherwertige Bits werden hier von der Hardware ignoriert. Das Kommando ist wegen der dort vorhandenen Kommando-Substitution im Zusammenhang mit einem Shell-Programm wie 'bish' nützlich. BEISPIELE ov 22 ov -q 22 Ausgabe des vorherigen Wertes unterdrückt. prev=`ov 9` Vorheriger Wert in Variable prev. curr=`ov` Aktueller Wert in Variable curr. ov -q ; curr=$? dito SIEHE AUCH bish(K) EXIT-CODE 0... Farbwerte bei Option -q AUTOR Das Programm ov wurde entwickelt von: Helmut Schellong, Bad Salzuflen Copyright © 1997 |
pg(K) pg(K) NAME pg.exe - Kommando zum komfortablen Lesen von Textdateien (pager) pgr (intern bish(K)) SYNTAX pgr [-] [-zahl] [-cefns] [ datei(en) ...] BESCHREIBUNG Das Kommando pgr erlaubt die seitenweise Betrachtung der Inhalte vorzugsweise von Textdateien. Wenn die Kommandozeilen-Option '-' und/oder wenn keine Datei angegeben ist, liest pgr von der Standard-Eingabe. Die Ausgabe erfolgt auf die Standard-Ausgabe. Durch Betätigung der <Enter>-Taste wird jeweils die nächste Seite ausgegeben. Mit pgr kann innerhalb eines Dateiinhaltes beliebig vor und zurück gesprungen werden, was ebenfalls für die Suchmuster-Funktion gilt. Aus diesem Grund erzeugt pgr eine temporäre Datei, wenn ein Datenstrom von der Standard-Eingabe gelesen wird. pgr berücksichtigt folgende Shell-Variablen: PGTEMP zur Angabe eines Verzeichnisses für die temporäre Datei. Standard-Verzeichnis ist das bish-Temp-Verzeichnis. PGCOLUMNS Standardwert ist 130. PGLINES Standardwert ist 30. Die Kommandozeilen-Optionen sind: -zahl Anzahl Zeilen, die pro Seite ausgegeben werden. Wegen der Seiten-Eingabeaufforderung (s: ) wird standardmäßig LINES-1 (29) eingestellt. Wenn dieser Wert LINES-1 ist, wird zwar die gewählte Anzahl von Zeilen jedesmal ausgegeben, jedoch wird zuvor um eine Zeile zurückpositioniert, damit die zuvor letzte sichtbare Zeile auf der jetzt aktuellen Seite zuoberst noch einmal sichtbar wird. (siehe Bedienungs-Kommando w) -c Stellt den Cursor nach links oben und löscht den Bildschirm, bevor jeweils eine Seite geschrieben wird. Wird automatisch unterdrückt bei dem Bedienungskommando <l> bzw. <Down>. -e Bei Dateiende entfällt das Prompt (EOF)s: , und wenn die letzte Dateizeile bzw. die letzte Zeile der letzten Datei ausgegeben wurde, beendet pgr automatisch. -f Unterdrückt das Einfügen der Zeichen CR-NL. Ohne diese Option zerschneidet pgr Zeilen, sobald COLUMNS-1 Zeichen gezählt wurden. -n Durch Angabe dieser Option muß die Mehrzahl der Bedienungskommandos nicht mehr durch <Enter> abgeschlossen werden - ein einfacher Tastendruck genügt. Desweiteren werden einige zusätzliche Funktionstasten aktiviert. -s Das Seiten-Prompt erscheint schwarz auf weiß (invers). Zur Bedienung stehen die folgenden Kommandos zur Verfügung: <h> <F1> Zeigen einen Hilfetext. <q> <Q> Beenden pgr. <Enter> < > <PgDown> Eine Seite vor. + +n Eine bzw. n Seiten vor. <PgUp> Eine Seite zurück. - -n Eine bzw. n Seiten zurück. n Zur n-ten Seite. <l> <Down> Eine Zeile vor. <$> <End> Zur letzten Seite. <Home> Zur ersten Seite. /suchmuster Sucht vorwärts nach suchmuster. ?suchmuster Sucht rückwärts nach suchmuster. <N> Sucht nächstes Vorkommen. <n> Zur nächsten Datei. <p> Zur vorherigen Datei. !kommando [arg ...] Führt 'kommando' aus. s datei Aktuelle Datei wird in datei gesichert. Das funktioniert auch mit der temporären Datei, beim Lesen von der Standardeingabe. w[n] Anzahl (n) Zeilen pro Seite. w stellt ein auf LINES-1. (s. Kommandozeilen-Option -zahl) <.> Schreibt aktuelle Seite erneut. Bei Aufruf mit Option -n funktionieren die <Tasten>, ohne daß mit <Enter> abgeschlossen werden muß. Bei Endposition (EOF) sind die Zeichen oder <Tasten> zum Beenden oder Dateiwechsel gesperrt. Es können dann '$' <$> <End> benutzt werden. Dies, damit nicht unabsichtlich aus der Datei 'herausgerutscht' wird. Die Suchmuster-Funktion sucht ab der obersten sichtbaren Zeile vorwärts bzw. rückwärts. Wenn ein Muster gefunden wurde, wird die entsprechende Zeile als oberste Bildschirmzeile geschrieben. Wenn mittels des Kommandos <N> nach weiteren Vorkommen gesucht wird, wird zuvor eine Zeile weiter- bzw. zurückpositioniert. In einem Suchmuster werden diejenigen Zeichen, die unter UNIX zur Dateinamen-Expansion dienen, als Spezialzeichen mit ebensolcher Funktion interpretiert. Zusätzlich haben die Zeichen ^ und $ Sonderbedeutung. Um diese Spezialbedeutung aufzuheben, muß das Zeichen % vorangestellt werden, was auch für % selbst gilt. Das Zeichen % wird als normales Zeichen aufgefaßt, wenn es nicht vor einem Zeichen mit (aktiver) Spezialbedeutung steht. Dabei ist zu beachten, daß ^ und $ nur an bestimmten Positionen Sonderbedeutung haben! Die Begrenzungszeichen / und ? haben nur als erstes Zeichen diese Spezialbedeutung. Sie dienen nur zur Suchrichtungsauswahl und werden nach Erfüllung dieser Aufgabe einfach entfernt. ? Steht für ein beliebiges Zeichen. * Ersetzt beliebig viele beliebige Zeichen, also auch null Zeichen. [...] Zeichenklasse: Ersetzt ein (1) Zeichen, das in der Zeichenklasse vorkommt bzw. nicht vorkommt. Innerhalb einer Zeichenklasse haben nur die Zeichen !, - und ] eine Spezialbedeutung. ! Wenn ! [ direkt folgt ([!...]), werden Zeichen ersetzt, die nicht unter denen in der Klasse angegebenen sind. - Mit - können Zeichenbereiche in Kurzschreibweise definiert werden: [a-fu-zA-C] entspricht [abcdefuvwxyzABC] Das jeweils rechte Zeichen muß bezüglich seiner Position im Zeichensatz gleich oder größer als das linke Zeichen sein. Das Minuszeichen hat nur diese Bedeutung, wenn es nicht am Rand steht, sondern zwischen Zeichen, die als Klassenzeichen interpretiert werden. [--d] ersetzt alle Zeichen von - bis d. [a-d-z] wird als [a-dd-z] interpretiert. [a#--bc] entspricht a oder # bis - oder b oder c. ] Das Zeichen ] ist das Abschlußzeichen einer Zeichenklasse. Wenn es [ oder [! direkt folgt, wird es als Zeichen ohne diese Abschlußwirkung interpretiert. ^ Erzwingt, daß das Suchmuster am Anfang einer Zeile passen muß: /^suchmuster $ Erzwingt, daß das Suchmuster am Ende einer Zeile passen muß: /suchmuster$ /^$ sucht beispielsweise nach Leerzeilen. Diese beiden Zeichen ^ und $ haben nur Spezialbedeutung am Anfang bzw. am Ende eines Suchmusters. pgr ist nicht interaktiv, wenn die Standardausgabe nicht mit einem Terminal/Console/Gerät verbunden ist. Die Zeichen mit den folgenden Dezimalwerten werden von pgr in das Zeichen ~ umgewandelt: 0-31 (außer TAB, CR, NL und ESC), 255 pgr berücksichtigt folgende Umgebungsvariablen (Environment): (nicht bish-intern) PGAUTOR Um die Autoren-Meldung zu unterdrücken: PGAUTOR=H.Schellong,Vlotho PGPROGRAM Um die Freeware-Meldung zu unterdrücken: PGPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (PGAUTOR muß hierfür auch gesetzt sein.) BEISPIELE pgr -nc datei1 datei2 ... pgr < datei dir | pgr -nce type datei1 | pgr -f > datei2 NOTA pgr expandiert grundsätzlich keine Argumente (mit * oder ?), sondern erwartet diesen Service von einem Shell-Programm, wie beispielsweise bish(K). Die erhöhte Funktionalität der unix-typischen "Regulären Ausdrücke" wurde absichtlich nicht implementiert, weil diese im Zusammenhang mit dem Zweck dieses Programms erstens nicht nötig und zweitens, unpraktischer ist, weil komplizierter und langwieriger formuliert werden muß. pgr geht davon aus, daß TABs 8er-Schritte produzieren. Zahlenbereich für LINES : 3...63 Zahlenbereich für COLUMNS: 9...512 pgr kann maximal 33.554.432 Dateizeilen verarbeiten. Unter Windows die Hälfte davon. Das entspricht normalerweise mehr als einem GigaByte Dateigröße. Eine Zeile wird abgeschlossen durch das Zeichen NL oder sobald COLUMNS-1 Zeichen gezählt wurden. (Option -f ist bei dieser Betrachtung bedeutungslos.) pgr fügt ein Zeichen CR am Zeilenende ein, wenn dort nur das Zeichen NL vorgefunden wird und wenn die Standard= ausgabe mit einem Gerät verbunden ist. pgr berücksichtigt Tastenprogrammierungen, die auf Betriebssystemebene mittels Escape-Sequenzen vorgenommen wurden. Wer also beispielsweise eine US-Tastatur hat und <Alt>a = ä programmiert hat, kann dies auch so innerhalb von pgr benutzen. Man beachte bei Verwendung des Kommandos $ oder <End> und gleichzeitigem Lesen von der Standardeingabe, daß der gelesene Datenstrom beliebig groß werden kann! Dieses Programm pgr verarbeitet die Daten mit mehrfach verschachtelter Pufferung und arbeitet u.a. deshalb um ein Vielfaches schneller als die Originale auf verschiedenen UNIX-Systemen. SIEHE AUCH regexp® EXIT-CODE 0 Kein Fehler aufgetreten. 1 Allgemeiner Fehler (Argumente, falsche Datei, etc.) 2 Wenn eine Systemfunktion einen Fehler meldete. AUTOR Dieses Programm pgr wurde entwickelt von: Helmut Schellong, Vlotho Copyright © 1995-2016 |
timex(K) timex(K) NAME timex.exe - Mißt den Zeitbedarf einer Kommandoausführung SYNTAX timex kdo.exe [kdo_args] BESCHREIBUNG Das Kommando timex interpretiert seine Argumente als Name einer ausführbaren Datei, gefolgt von optionalen Argumenten dazu, und bringt das angegebene Kommando zur Ausführung. Die Zeit, die das Kommando benötigte, wird in Sekunden mit zwei Nachkommastellen zur Standard-Ausgabe geschrieben: 'SS.ss' Die Auflösung beträgt 1/100 Sekunde. Wegen der höheren Auflösung wird anstelle eines 'Clock-Ticks' die Systemzeit zur Messung verwendet. Das Zeitnahme-Kommando darf daher nicht die Systemzeit ändern. Die Systemzeit darf während der Messung über 00:00:00 Uhr gehen, da diese Möglichkeit berücksichtigt wurde. timex berücksichtigt die folgenden Umgebungsvariablen (Environment): BSHAUTOR Um die Autoren-Meldung zu unterdrücken: BSHAUTOR=H.Schellong,Vlotho TIMEXPROGRAM Um die Freeware-Meldung zu unterdrücken: TIMEXPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (BSHAUTOR muß hierfür auch gesetzt sein.) BEISPIEL timex hx datei >> sec.tim Die gemessene Zeit wird dem Inhalt von sec.tim hinzugefügt. (timex erhält die Argumente 'hx' und 'datei'.) timex hx datei ">>" sec.tim hx versucht, die Dateien datei, >> und sec.tim zu lesen, was sicher nicht beabsichtigt war. timex command.com /c copy datei \verz DIAGNOSE Bei Fehlern wird keine Zeit ausgegeben. EXIT-CODE 0 Kein Fehler. 1 Fehler bei Zeitnahme oder Kommandoausführung. SIEHE AUCH bish(K). AUTOR Dieses Kommando timex wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
touch(K) touch(K) NAME touch.exe - Setzt Datum und Zeit von Dateien SYNTAX touch [ -amc ] [ /TT[MM[JJ[hh[mm[ss]]]]] ] datei ... touch [ -amc ] [ -MMTThhmm[JJ] ] datei ... BESCHREIBUNG Das Kommando touch setzt die Modifikationszeit von einer oder mehreren Dateien. Angegebene Dateien, die zuvor nicht existieren, werden erzeugt und haben dann eine Größe von 0 Byte. Option -c unterbindet diese Erzeugung von nichtexistenten Dateien. Die Optionen -a -m haben unter DOS keine Wirkung. Für eine fehlende Zeitangabe wird die aktuelle Zeit eingesetzt. Zur Zeitangabe stehen zwei Varianten zur Verfügung: -MM... Kompatibel mit dem UNIX-Original-Kommando. /TT... Datum und Uhrzeit in deutscher Reihenfolge. Bedeutung der Buchstaben in der Zeitangabe: Tag, Monat, Jahr, hour(Stunde), minute, sekunde. Es müssen gegebenenfalls führende Nullen (0) angegeben werden. Bei der Zeitangabe können -von hinten begonnen- bis zu fünf Teilangaben weggelassen werden, wie es durch die eckigen Klammern angedeutet ist. Für fehlende Teilangaben werden dann die entsprechenden Teile der vorhandenen Dateizeit eingesetzt, oder -bei zuvor nichtexistenten Dateien- die entsprechenden Teile der aktuellen Zeit. Als Jahreszahl können Werte von 00 bis 99 angegeben werden. Daraus resultieren die Jahre 1980 bis 2079. (80...99 --> 1980...1999 und 00...79 --> 2000...2079) touch berücksichtigt die folgenden Umgebungsvariablen (Environment): BSHAUTOR Um die Autoren-Meldung zu unterdrücken: BSHAUTOR=H.Schellong,Vlotho TOUCHPROGRAM Um die Freeware-Meldung zu unterdrücken: TOUCHPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung (BSHAUTOR muß hierfür auch gesetzt sein.) BEISPIELE touch /011194223344 datei1 datei2 datei3 datei4 datei5 Setzt die Dateizeiten auf 1.11.1994, 22:33:44 Uhr. touch /010395141000 .\wk??*\??*.exe oder touch -0301141095 .\wk??*\??*.exe Setzt die Zeiten auf 1.3.1995, 14:10 Uhr. Das DIR-Kommando zeigt dann als Uhrzeit 2:10p. Software-Firmen verwenden dies stets als Versionskennzeichnung. Die Argumentbildung kann hier nur mittels bish.exe erfolgen! EXIT-CODE 0 Kein Fehler. 1 Fehler bei den Optionen. 2 Fehler von System-Funktionen. SIEHE AUCH bish(K), mtime(bish(K)), dat(K). AUTOR Dieses Kommando touch wurde entwickelt von: Helmut Schellong, Bad Salzuflen |
======================================================================== -- Editor vi -- DIESE DATEI GEHÖRT NICHT ZUR bish-DOKUMENTATION, SONDERN IST EINE ZUGABE! ======================================================================== <Esc> --> Kommando-Modus ········································································ i --> Schreib-Modus: links einfügen (#i) I --> Schreib-Modus: springt zum sichtb. Zeilenanfang, dann wie i a --> Schreib-Modus: rechts anhängen (#a) A --> Schreib-Modus: springt zum Zeilenende, dann wie a (#A) r --> Schreib-Modus: ein Zeichen überschreiben 3r --> Schreib-Modus: eingegebenes Zeichen 3-mal R --> Schreib-Modus: beliebig viele Zeichen überschreiben 4R --> Schreib-Modus: eingegebene Zeichenfolge 4-mal o --> Schreib-Modus: Anfang nächste Zeile O --> Schreib-Modus: Anfang Zeile darüber cc --> Schreib-Modus: löscht Zeile und geht zum Anfang (#cc) cw --> Schreib-Modus: ändert Wort (3cw = 3 Worte) cW --> Schreib-Modus: dito - Trennzeichen nur noch ' ' C --> Schreib-Modus: ändert bis Zeilenende (#C) c$ --> Schreib-Modus: ändert bis Zeilenende (#c$) c0 --> Schreib-Modus: ändert bis Zeilenanfang c^ --> Schreib-Modus: ändert bis sichtbaren Zeilenanfang c4_ --> Schreib-Modus: ändert die nächsten 4 Zeichen (_ = space) 4c_ --> Schreib-Modus: ändert die nächsten 4 Zeichen (_ = space) cfz --> Schreib-Modus: ändert bis EINschließlich nächstes z 2cfz --> Schreib-Modus: ändert bis EINschließlich übernächstes z c2fz --> Schreib-Modus: dito ctz --> Schreib-Modus: ändert bis AUSschließlich nächstes z s --> Schreib-Modus: ersetzt 1 Zeichen (5s = 5 Zeichen) S --> Schreib-Modus: ändert 1 Zeile (5S = 5 Zeilen) ········································································ <Ctrl><u> Beginnt Schreibvorgang neu (im Schreib-Modus!) <Ctrl><w> Beginnt Schreibvorgang neu (im Schreib-Modus!) <Ctrl><d> Cursor links bei autom. Zeicheneinfügung (set autoindent) ········································································ <Ctrl><v> , <Enter> schreibt z.B. ^M So werden Steuer-Zeichen geschrieben, die sonst aktiv würden. ------------------------------------------------------------------------ <Ctrl><g> Gibt Information über aktuelle Datei (:f = dito) ------------------------------------------------------------------------ AUF VIELFÄLTIGE MÖGLICHKEITEN, KOMMANDOS ZU KOMBINIEREN, ACHTEN. Zahlen lassen sich vor nahezu alle Kommandos setzen, auch wenn hier nicht unbedingt überall angegeben (# ) ! Es handelt sich um Wiederholungsanzahlen oder (Zeilen-)Adressierungen. Viele Kommandos wirken nur in der aktuellen Zeile (z.B. #ctz) ! ------------------------------------------------------------------------ x löscht Zeichen (5x =Fünf Zeichen) X löscht Zeichen, jedoch links vom Cursor (5X) dw löscht Wort (4dw) dW dito - Trennzeichen nur noch ' ' dd löscht Zeile(n) (3dd =Drei Zeilen) D löscht Zeile bis Zeilenende, ab Cursor d$ löscht Zeile bis Zeilenende, ab Cursor (#d$) d0 löscht Zeile bis Zeilenanfang, ab Cursor d^ löscht Zeile bis sichtbaren Zeilenanfang, ab Cursor d5_ löscht 5 Zeichen/Zeilen durch <Space>-drücken, <BackSp>, j oder k 5d_ löscht 5 Zeichen durch <Space>-drücken dtS löscht analog zu ctz, yfs, etc. - also bis ausschl. nächstes S d/wu löscht bis ausschließlich 1. Vorkommen von 'wu'. ········································································ :34d Löscht Zeile 34 :12,14d Löscht Zeilen 12 bis 14 :'a,'bd Löscht Zeilen zwischen den Marken (s.u.) a und b. :12,$d Löscht ab Zeile 12 bis Datei-Ende :.,$d Löscht ab aktueller Zeile bis Datei-Ende :1,$d Löscht gesamte Datei :%d Löscht gesamte Datei (% = 1,$) :g/ABC/d Löscht alle Zeilen, die ABC enthalten :g/^$/d Löscht alle Leerzeilen :12,76s/ABC//g Löscht sämtliche ABC in den Zeilen 12 bis 76 :g/ABC/s/// Löscht jeweils das erste ABC in allen Zeilen :g/ABC/s///g Löscht sämtliche ABC ------------------------------------------------------------------------ J Zeile unter der aktuellen wird an aktuelle angehängt 1J,2J dito, verketten 2 Zeilen 4J Jetzt werden 4 verkettet, also 3 an die aktuelle gehängt. <Enter> beim Schreiben ist Zeilenbrechen und damit Rückgängigmachung (siehe auch <r><Enter>) ! ~ Ändert von Kleinschreibung zu Großschreibung und umgekehrt 8~ dito - jetzt aber 8 Zeichen . Wiederholt letzten Schreib- oder Löschvorgang inklusive <Esc> (auch z.B. "aP ; Wirkung nach u beachten) (#.) 3. Wiederholt 3-mal u Macht letztes Kommando rückgängig (Text löschen oder erzeugen) U Restauriert die aktuelle beliebig (oft) bearbeitete Zeile ------------------------------------------------------------------------ ------------------------------------------------------------------------ $ Geht zum Zeilenende 0 Geht zum Zeilenanfang ^ Geht zum ersten sichtbaren Zeichen der Zeile 12| Geht zum 12. Zeichen in aktueller Zeile w Geht zu Wortanfängen (#w) W Geht zu Wortanfängen (#W) (andere Stop-Bewertung) b Geht zu Wortanfängen, rückwärts (#b) B Geht zu Wortanfängen, rückwärts (#B) (andere Stop-Bewertung) e Geht zu Wortenden (#e) E Geht zu Wortenden (#E) (andere Stop-Bewertung) fx Geht zum nächsten x (#fx) Fx Geht zum nächsten x, rückwärts (#Fx) tz Geht bis vor nächstes z (#tz) Tz Geht bis vor nächstes z, rückwärts (#Tz) ; , betreffen f, F, t, T : springen zu weiteren Antreffen (#;,) ········································································ % Geht zu Klammern, wenn man dazwischen oder drauf ist. () [] {} ( ) Geht zum Anfang/Ende von Sätzen, die mit . ? ! und ' ' enden. { } Geht zum Anfang/Ende von Paragraphen (leere Zeilen, u.a.) [[ ]] Geht zum Anfang/Ende von Sektionen (^L oder { am ZA, u.a.) ········································································ 123G Geht zur Zeile 123 G Geht zum Datei-Ende 100+ Geht 100 Zeilen vor 100- Geht 100 Zeilen zurück :1 Geht zur ersten Zeile = Datei-Anfang (:0 = dito) :123 Geht zur Zeile 123 :$ Geht zum Datei-Ende ········································································ ma markiert aktuelle Stelle und benamt sie mit a (a-z) `a springt zur markierten Stelle a 'a springt zur markierten Stelle a, jedoch an den Zeilen-Anfang `` springt stets zum letzten Aufenthaltsort '' springt stets zum letzten Aufenthaltsort, jedoch an den ZA ········································································ z. Stellt Cursor-Position auf Bildschirm-Mitte und zieht Text mit. z8. Reduziert Fenster auf 8 Zeilen und stellt Cursor auf Bildmitte. ········································································ <Pfeil> Vier Pfeiltasten zur Bewegung, AUCH im Schreib-Modus. 4<Pfeil> Bewegung um 4 Zeichen/Zeilen. <BackSp> o. h Bewegt nach links <Space> o. l Bewegt nach rechts <Enter> o. + Bewegt nach unten, aber Cursor immer am ersten Zeichen j Bewegt nach unten k Bewegt nach oben - Bewegt nach oben, aber Cursor immer am ersten Zeichen 6- Bewegt 6 Zeilen aufwärts <Page Up> Eine Seite hoch <Page Down> Eine Seite runter <Ctrl><b> Eine Seite hoch 3<Ctrl><f> Drei Seiten runter 4<Ctrl><u> (Halbe) Seite hoch (Zahl davor bleibt in Erinnerung!) 8<Ctrl><d> (Halbe) Seite runter ( " ) <Home> Cursor nach links oben in die Ecke (<H> = dito) 4H Wie Home, jedoch in die vierte Bildzeile von oben 7L Wie H, jedoch in die siebte Bildzeile von unten M Cursor auf mittlere Bildzeile ········································································ n Geht zum nächsten Suchmuster N Geht zum nächsten Suchmuster, rückwärts /suchmuster Geht zum 'suchmuster' :/suchmuster Geht zum 'suchmuster' :/such muster Geht zum 'such muster' :/such muster/ Geht zum 'such muster' /such muster/2+3 Geht zum 2. Vorkommen und dann 3 Zeilen tiefer ?such muster? Geht zum 'such muster', aber sucht rückwärts :?such muster? Geht zum 'such muster', aber sucht rückwärts :g/suchmuster/p Druckt alle Zeilen mit 'suchmuster' :23,44g/suchmuster/p dito, aus Zeilen 23-44 :g!/suchmuster/p Druckt alle Zeilen, mit NICHT 'suchmuster' :v/suchmuster/p dito Bei /... und ?... ist ':'(ex-Editor) nicht nötig! ········································································ Suchmuster bleibt während vi-Sitzung erhalten. (n N :n) ------------------------------------------------------------------------ ------------------------------------------------------------------------ yy Kopiert aktuelle Zeile in unbenamten Speicher 0 (yy == 1yy) 12yy Kopiert 12 Zeilen ab und einschl. akt. in unbenamten Speicher 0 y3j Kopiert akt. Zeile und 3 darunter in unbenamten Speicher 0 y3+ dito y4k Kopiert akt. Zeile und 4 darüber in unbenamten Speicher 0 y4- dito 3yw Kopiert 3 Worte in Speicher 0 y3w Kopiert 3 Worte in Speicher 0 yL Kopiert akt. Zeile und alle bis Bildende in unbenamten Speicher 0 y'o Kopiert Zeile mit Marke o bis akt. Zeile bzw. umgekehrt y`o Kopiert Zeichen von Marke o bis akt. Zeichen bzw. umgekehrt "byH Kopiert akt. Zeile und alle bis Bildanfang in den Speicher b "by'o Kopiert in den Speicher b (siehe y`o und ma) "ay3+ Kopiert 4 Zeilen in mit a benamten Speicher "a4yy Kopiert 4 Zeilen in mit a benamten Speicher "A2yy Kopiert 2 Zeilen in a. Hängt hinten an !! (a-z) >>(A-Z) ········································································ p Kopiert yy-Zeile(n) hinter aktuelle Zeile, aus dem Speicher 0 P Kopiert yy-Zeile(n) vor aktuelle Zeile, aus dem Speicher 0 "ap Kopiert yy-Zeile(n) hinter aktuelle Zeile, aus dem Speicher a "aP Kopiert yy-Zeile(n) vor aktuelle Zeile, aus dem Speicher a "4p Kopiert yy-Zeile(n) hin. aktuelle Zeile, aus dem Speicher 4 (1-9) "6P Kopiert yy-Zeile(n) vor aktuelle Zeile, aus dem Speicher 6 (1-9) ········································································ Nur die Inhalte von a-z bleiben erhalten, solange man im vi ist! Löschspeicher 0 und 1-9 sind permanent vorhanden, aber man sollte nicht in sie schreiben, weil es ein Stack ist, der sich laufend verändert. Aber man kann vor einigen Aktionen Gelöschtes wieder auffinden. ········································································ @a Meldet, falls Speicher a leer ist, sonst undefiniertes Verhalten. (a-zA-Z). Undokumentiert! Sollte nicht benutzt werden! ------------------------------------------------------------------------ :m16 Bewegt aktuelle Zeile hinter Zeile 16. :19m16 Bewegt Zeile 19 hinter Zeile 16. :12,14m17 Bewegt Zeilen 12 bis 14 hinter Zeile 17 :m+ Vertauscht aktuelle Zeile mit der darunter. :m-2 Vertauscht aktuelle Zeile mit der darüber. :m3+2 Bewegt aktuelle Zeile hinter Zeile 5. :g/^X.*D.*[0-9]/m0 Die Zeilen, die mit X beginnen, dann nach beliebigen Zeichen D und dann nach beliebigen Zeichen eine Zahl 0 bis 9 enthalten, werden nach Zeile 0 bewegt. :'a,'bm. Zeilen von a- bis b-Marke (<m><a> <m><b>) werden hinter die aktuelle Zeile bewegt. :12,14co0 Kopiert Zeilen 12 bis 14 hinter Zeile 0, also vor 1. :g/xABCy/co28 Alle Zeilen, die xABCy enthalten, werden hinter Zeile 28 kopiert. :3,72g/xABCy/co$ dito, beschränkt auf Zeilen 3-72, co>>Dateiende :12p Zeigt Zeile 12 :12,23p Zeigt Zeilen 12 bis 23 ········································································ Unterschied zwischen Vorwärts- und Rückwärts-Kopieren (co0, co$): nämlich die dann vorliegende Reihenfolge der Zeilen! (co$ behält bei) ES GIBT DIE ZEILE 0 = Puffer-Anfang! EIN PUNKT '.' (:.) adressiert stets die aktuelle Zeile! ········································································ :> Schiebt aktuelle Zeile um 'shiftwidth' nach rechts :>>>> Um 4mal 'shiftwidth' (i.d.R. = 8; siehe ':set all') :<<<< dito, nach links :108> Zeile 108 nach rechts :44,69> Zeilen 44 bis 69 nach rechts >4j Aktuelle und 4 weitere Zeilen darunter nach rechts 4>j dito (siehe Kommandos: c, y, j, k, etc.) 4>+ dito (siehe Kommandos: c, y, j, k, etc.) 4>> Vier Zeilen nach rechts, ab aktueller 4<< dito, nach links ------------------------------------------------------------------------ ------------------------------------------------------------------------ :12,17s/ABC/CBA/ Ersetzt in Zeilen 12 bis 17 'ABC' durch 'CBA' (nur jeweils erstes Vorkommen in den Zeilen) :12,17s/ABC/CBA/g Ersetzt in Zeilen 12 bis 17 'ABC' durch 'CBA' (g = jeweils jedes Vorkommen in den Zeilen) :2,333s/^/** / Fügt an den Zeilenanfängen 2 bis 333 '** ' ein. :g/^/s// w / Fügt an allen Zeilenanfängen ' w ' ein. :g/$/s// w / Hängt an alle Zeilenenden ' w ' an. :g/xyz$/s//XYZ/ Ersetzt alle 'xyz' durch 'XYZ', aber nur die 'xyz' direkt an Zeilenenden. (Spezielle Bedeutung von '^' und '$' !) :g/ABC/s//CBA/g Ersetzt in der ganzen Datei 'ABC' durch 'CBA' :45,$g/ABC/s//CBA/g Wie zuvor, jedoch erst ab Zeile 45. :g/ABC/s//CBA/gp Ersetzt in der ganzen Datei 'ABC' durch 'CBA' (p = Zeilen dabei herzeigen) (jeweils jedes Vorkommen in den Zeilen) :g/ABC/s//CBA/gc Ersetzt in der ganzen Datei 'ABC' durch 'CBA' (jeweils jedes Vorkommen in den Zeilen) (und mit Erlaubniseinholung jeweils) (<Delete> bricht ab) :g/QQQ/s/CBA/WWW/g In allen Zeilen, in denen QQQ vorkommt, wird jedes CBA durch WWW ersetzt. :4,79g/QQ/s/CB/WW/c dito, beschränkt auf Zeilen 4-79 :g/ABC/s//xx&&&yy/g Macht überall aus 'ABC' 'xxABCABCABCyy', '&' steht (rechts) für das, was links resultiert. ABC (links) könnte auch / *[^s]printf/ sein! :g//s//~/gc '~' wirkt wie '&', erinnert sich jedoch an den Ersatztext (rechts), der zuvor eingesetzt wurde. g// setzt vorhergehendes Suchmuster ein. :g/[^S]TUV/p Alle Zeilen mit TUV aber nicht S davor werden angezeigt. :g/\<TUV/p Alle Zeilen mit TUV, aber nur, wo TUV der Anfang eines Wortes oder Zeilenanfang ist. :g/TUV\>/p Alle Zeilen mit TUV, aber nur, wo TUV das Ende eines Wortes oder Zeilenende ist. :/[abcf]xyz Sucht xyz mit einem der Zeichen a,b,c oder f davor. :/[a-h]xyz Hier mit einem der Zeichen a bis h. :/a[^bcd]z Hier alle 'a?z', aber nicht abz, acz und adz. :/[^A-Z] Hier alle Zeichen, aber keine Großbuchstaben. :/[h-k]*swq/ Hier kann das, was [] beschreibt, beliebig oft vorkommen, also auch nullmal. :/[h-k][h-k]*swq/ Hier kann das, was [] beschreibt, >=1mal vorkommen. :/qas...sdd Hier stehen die Punkte für drei beliebige Zeichen. :g/[0-9][0-9].*XYZ/s// XYZ/ Überall, wo zwei Zeichen '0-9''0-9' und danach beliebige Zeichen (.) in beliebiger Menge (*) stehen, gefolgt von 'XYZ', kommt hin: ' XYZ'. :g/^$/s/^M^M/ Wo vorher 1 Leerzeile war sind jetzt 3. ('^M'!) ········································································ Spezial-Operatoren: \( \) \1 \2 ... \9 abcdefghijklm steht in Zeile 178. :178s/a\(bcd\(ef\)gh\)i/A\1B\1C\2\2\2\2D/ Dieses Kommando AbcdefghBbcdefghCefefefefDjklm macht <-- daraus ! A bcd ef gh B bcd ef gh C ef ef ef ef D jklm Das hat was mit 1. und 2. Klammerebene zu tun. (bis 9 Ebenen) Die Klammer-Paare müssen nicht verschachtelt sein. Auch bei nebeneinander stehenden zählt die öffnende Klammer \( jeweils um eins weiter: FTp[ix++][2]; FTp[NFND][0]; FTp[ifno][1]; :g/FTp\[\(....\)\]\[\([012]\)\]/s//FTp[\2][\1]/g FTp[2][ix++]; FTp[0][NFND]; FTp[1][ifno]; ist das Ergebnis. ········································································ ed und sed können auch: s/\([^ ]\)\1\1\1/\1/g (\1 linksstehend!) Alle Zeichen !=' ' 4-fach-gleich z.B. 'AAAA' werden vereinzelt:==> 'A'. Weiterhin: \{n\} \{n,\} \{n,m\} (?-mal 1-char-expr.) ········································································ :g/Hier/s//\UHier/ Macht aus Hier HIER. '\U' schaltet auf Uppercase. :g/Hier/s//\U&/ dito ! :g/HIER/s//\Uh\LIER/ Macht aus HIER Hier. '\L' schaltet auf Lowercase. '\u' und '\l' müssen von einem Buchstaben direkt gefolgt werden, für den das dann gelten soll. '\E' oder '\e' schaltet '\U' und '\L' ab. ········································································ Steuerzeichen: ^, $, /, &, [, ], \, ., *, ~, ? Diese müssen -links stehend- mit \ maskiert werden. Das heißt, wenn sie als normale Zeichen aufgefaßt werden sollen. (also: '\$'='$', usw.) (zwar nicht alle - aber sicher ist sicher!) Für \, &, ~ und / gilt das auch rechts. ········································································ Mit // und ?? kann man sich auf ein vorangegangenes Muster beziehen. Dabei ist das einzige oder aber das linke Muster gemeint. Also g//p wiederholt g/abc/p oder auch andere Sequenzen mit /abc/. ------------------------------------------------------------------------ Bei Eingabefehlern (:asbw76@4#,) : <Delete> oder mit <BackSp> zurück bis über ':' hinweg. Bei dd z.B. kann man das erste d noch mit <Esc> löschen, wenn man es sich anders überlegt hat. ------------------------------------------------------------------------ ------------------------------------------------------------------------ :w Bisherigen Zustand zur Festplatte schreiben. Die wirkliche aktuelle Datei wird (zwischendurch) aktualisiert. Quasi wie :x - jedoch ohne vi zu verlassen. :w! Bisherigen Zustand zur Festplatte schreiben. Überwindet Schreibschutz (Read only)! :w b Wenn Editor mit 'vi a' gestartet wurde, wird der Inhalt des vi-Puffers in b geschrieben, wobei b dazu erzeugt wird. Wenn nur mit 'vi' begonnen wurde, wird b erzeugt. Wenn b bereits existiert, gibt's eine Warnung! :w! b Wenn b bereits existiert, wird b überschrieben! Überwindet also Warnungen! :w>>b Hängt vi-Puffer-Inhalt an existierenden Datei-Inhalt von b an. (es darf auch ein Leerzeichen (Space) vor b stehen.) :w !cmd Schreibt Puffer-Inhalt zu einem UNIX-Kommando. :160,175w b Schreibt Puffer-Zeilen 160 bis 175 in b. (siehe ':w b') :160,175w>>b Schreibt Puffer-Zeilen 160 bis 175 ans Ende von b. :160,175w !cmd Schreibt Puffer-Zeilen 160 bis 175 zu einem UNIX-Kommando. :1,15w !more BEISPIEL: übergibt Zeilen 1 bis 15 an 'more'. :160,185 !cmd Übergibt die Zeilen an 'cmd', löscht diese Zeilen (!), und fügt die Ausgabe von 'cmd' dort ein. :50,70 !sort sortiert die Zeilen 50 bis 70 ! (Argumente und shell-metachars sind erlaubt) :%!sort Sortiert gesamten Pufferinhalt. (% = 1,$) Nach % kein Leerzeichen! :160,185 !tr "m" "\234" (PC8-Zeichensatz) Ersetzt von 160-185 'm' durch '£' (siehe 'man tr') ········································································ :n Zur nächsten Datei gehen (bei mehreren gleichzeitig) (Gegenwärtige Einstellung macht vorher automatisch :w !) :n! Überwindet Warnungen, daß :w nicht benutzt wurde. :n e f Bearbeitet eine neue Datei-Liste, bestehend aus den Dateien e und f. Die alte Liste wird verlassen. :args Zeigt aktuelle Datei-Liste an, mit Markierung der gerade in Arbeit befindlichen. :n und :args haben zueinander Bezug, nicht jedoch mit :f (s.u.). :rew Geht zur ersten Datei in der args-Liste. :rew! Überwindet Warnungen, daß :w nicht benutzt wurde. ········································································ :e g Eine andere Datei g wird editiert, ggf. zuvor erzeugt. Man kann zwar so zu beliebig vielen Dateien springen, aber der vi behält nur zwei gleichzeitig 'in sich'. :e# Springt zur vorherigen zurück, und wieder zurück, usw. :e% Bezieht sich auf die gegenwärtige (:f), löscht den ':e#'-Bezug, und liest die aktuelle Datei (:f) (neu) in den Puffer ein. Hat generell keinen Bezug zur :args-Liste mit 'a [b] c d ...'. :e! g Überwindet Warnungen, daß :w nicht benutzt wurde. (siehe :e g) :f Gibt Informationen über Datei :f nn Gibt aktuellem Pufferinhalt neuen Namen (nn), also einen anderen als den, mit dem man vi aufrief: vi aaa ; jetzt: aaa --> nn Datei aaa existiert aber weiter, jedoch was ihren Inhalt angeht, bleibt dieser uneditiert, wenn nicht :w gemacht wurde, bevor :f nn gegeben wurde ! Es ist also eine Übernahme des Inhalts von aaa in eine neue Datei nn hinein, um in dieser neuen weiterzueditieren. Und man muß den Puffer ausschreiben, damit nn auch existiert. Es sei denn, nn war vorher schon existent. ········································································ :r d Holt angegebene Datei 'd' hinter aktuelle Zeile herein :12r d Holt angegebene Datei 'd' hinter Zeile 12 herein :0r d Holt angegebene Datei 'd' an den Puffer-Anfang herein :$r d Holt angegebene Datei 'd' an das Puffer-Ende herein (Bei Start mit 'vi' und leerem Puffer editiert man dann quasi d.) :r !cmd Holt die Ausgabe eines UNIX-Kommandos hinter aktuelle Zeile. BEISPIEL: :$r !find . -print schreibt die von 'find' gefundenen Dateinamen im aktuellen Directory (.) an's Puffer-Ende. !!cmd Die Ausgabe eines UNIX-Kommandos ERSETZT die aktuelle Zeile. 3!!cmd Die Ausgabe eines UNIX-Kommandos ERSETZT aktuelle +2 Zeilen. !!cc -Zs % Für % wird der aktuelle Dateiname eingesetzt. ------------------------------------------------------------------------ ------------------------------------------------------------------------ vi Startet vi-Editor nur im 'unsichtbaren' Puffer vi d Startet vi-Editor mit Datei d vi a b c Startet vi-Editor mit Dateien a, b und c (siehe :n) vi *.c Startet vi-Editor mit allen c-Dateien im Directory vi -R d Startet vi-Editor mit Datei d und nur Lesen ist erlaubt vi -L Listet alle nach einem Crash gesicherten Dateien vi -r f Nach einem Crash kann man hiermit Datei f herholen. (siehe auch :preserve und :recover) vi -w10 f Macht Fenster nur 10 Zeilen groß. :!vi s Startet vi nochmal aus vi heraus - als weiteren Prozeß ! :!cmd Führt UNIX-Kommando 'cmd' aus (z.B.: :!cp engl.c /u/gabi) (Gegenwärtige Einstellung macht vorher automatisch :w !) :!csh Startet eine neue C-Shell. Ende durch <Ctrl><d> oder 'exit'. :!sh Startet eine neue Bourne-Shell. Ende wie oben. :sh Startet eine neue Shell. (sh/csh/ksh gemäß :setall-shell) :cd d Wechselt das Directory nach d. (And. Wrkg. als bei ':!cd d') ········································································ :x Editor beenden, mit Aktualisierung der 'echten' Datei. ZZ dito :x a Editor beenden, mit Puffer-Schreiben zur Datei a. (vi-Warnung, falls a existiert.) :q Editor beenden, ohne Änderungen zu berücksichtigen (vi-Warnung) :q! Editor beenden, ohne Änderungen zu berücksichtigen Überwindet Warnungen! :wq Wie :w und dann :q oder auch wie :x :wq! Wie :w! und dann :q. Überwindet auch 'Read only' (Nur lesen) ! :wq b Wie ':w b' und dann :q. (vi-Warnung) :wq! b Wie ':w! b' und dann :q. (vi-Warnung) Q Geht in den ex-Editor bzw. zeilen-orientierten Modus; :vi geht wieder zum bildschirm-orientierten Modus zurück. ------------------------------------------------------------------------ := Zeigt aktuelle Anzahl Zeilen im Puffer an. :nu Zeigt aktuelle Zeile mit deren Nummer :1,10nu Zeigt Zeilen 1-10 mit deren Nummern :preserve Sichert Puffer in schlimmen Situationen (mail-Paket muß installiert sein!) :recover d Holt Datei d von dem Absicherungsbereich ········································································ :set all Zeigt alle Einstell-Optionen, jedoch nicht die Abkürzungen :set Zeigt alle, die von der Standardeinstellung abweichen :set ai? Zeigt den Zustand von ai an :set nonu Schaltet Zeilen-Numerierung ab (nonumber) :set nu Schaltet Zeilen-Numerierung ein (number) :set ai Erzeugt automatische Absatz-Einfügung (autoindent) Es werden Leerzeichen und Tabs eingefügt. :set noai Stellt wieder Normal ein (noautoindent) :set list Macht Tabs und Zeilenenden sichtbar :set nolist ... Siehe Datei /u/sc/.exrc (vi-Konfigurations-Datei): set, map, map!, abbr :map @ A;^[ :map! oe ö Schreibmodus-map! Bei 2 Zeichen diese schnell drücken! :unmap ^T :unmap! oe|ö :unabbr vvv Machen rückgängig. Folgende Zeichen sind im Kommandomodus nicht belegt: g q v K V ^A ^C ^K ^O ^Q ^T ^V ^W ^X ^Z (^=<Ctrl>) - können also gemapt werden! ------------------------------------------------------------------------ AUTOR Helmut Schellong, Bad Salzuflen |
bish(V) bish(V) NAME bish.mnv - Vergleichsbetrachtungen zum Shell-Programm bish BESCHREIBUNG Diese Datei vergleicht bish mit anderen Shell-Programmen. Dies erlaubt eine Eignungs- und Leistungsbeurteilung. | Einordnung der bish | Herkunft und Zielrichtung der bish | Geschwindigkeits-Vergleiche bish:ksh:zsh:bash:csh:sh:4dos.com Einordnung von bish unter andere Shell-Programme: =================================================== Umfang ^ bish+i Leistg.| zsh [perl] | | ksh | bash tcsh | bish | | csh | | sh | 4DOS.COM | | | | | COMMAND.COM ---------------------------------------------------------> Ähnlichkeit []:Keine Shell, sondern reine Script-Sprache bish+i: inklusive aller internen Kommandos. Bezüglich der Arbeitsgeschwindigkeit ist die bish anderen Shells bis zu hundertefach überlegen - im Mittel glatt um 1000 Prozent! Deshalb und wegen der zahlreichen internen Kommandos ist die bish -insgesamt- das leistungsfähigste existierende Shell-Programm. Herkunft und Zielrichtung der bish: =================================== |-----------DOS-----------| | | |command.com --> 4dos.com <---Div. | ndos.com | |------UNIX-------| | | | | | bish.exe <----------------- ksh <-- sh | | | | | zsh, bash; perl| |-------------------------| | | tcsh <-- csh | | | bish | OS/2 bish <-----------| |---|-------------| W-NT bish <-----------| | ---->---| Die bish holt die mächtigste Script-Sprache nach DOS, wo standardmäßig das Gegenteil, nämlich die einfachste Script-Sprache vorhanden ist. Dazwischen liegen OS/2 und Windows-NT. Geschwindigkeits-Vergleiche bish:ksh:zsh:bash:csh:sh:4dos.com =============================================================== Die folgenden Messungen wurden unter gleichen Bedingungen vorgenommen. Zugehörige Shell-Scripts -die Meßobjekte- folgen nach den Zeitwerten. Diese Zeitvergleiche sind insbesondere deshalb aufgeführt, weil die bish derartig schnell ist, daß man fast von "interpreter-untypisch" sprechen darf und daher mit der bish Aufgaben angehen kann, die man normalerweise nicht mit Shell-Programmen erledigt. Zu Zeiten, wo der Vorsprung neuer Prozessorgenerationen zumeist doch unterhalb von 100 Prozent liegt, sind Geschwindigkeitsunterschiede von 1000 Prozent und (viel) mehr von sehr erheblicher Bedeutung. Unter insgesamt 7 getesteten Shells war bisher nur eine, die ungefähr so schnell ist wie die bish, und zwar die ksh unter SCO-Unix. Ihre Arithmetik und Programmablaufsteuerung arbeiten bei kleinen Ausdrücken fast so schnell wie die der bish. --- Ein Vorabnachteil der bish hinsichtlich Tempo ist ihre totale Portabilität. Sie ist auch für DOS konzipiert, arbeitet stark datei-orientiert, ist ein ganz 'reiner' Interpreter und hat keine compiler-ähnlichen Arbeits= weisen, wie sie andeutungsweise/möglicherweise diese ksh hat. Die bish muß auch mehr Kommandonamen suchen - das kostet Zeit. Ein Schwerpunkt der bish sind die zahlreichen internen, echten Arbeits-Kommandos. Trotz all dieser Erschwernisse ist die bish die schnellste Shell. Geschwindigkeitsunterschiede bis etwa 70% sind allerdings unerheblich. Es geht hier darum, aufzuzeigen, daß die bish -und auch diese ksh- dutzendfach und mehr schneller sind als die anderen Shells ... ! Es wurde mehrere hundertfach(!!!) höherer Zeitbedarf festgestellt. Ob ein Skript 3 Sekunden oder zehn Minuten läuft - das ist schon wichtig! bish und SCO-ksh hängen auch die modernen zsh und bash ungefähr um einen Faktor 10-20 ab. Gemessen wurde unter UNIX - wenn nicht anders angegeben. Unter DOS ist bish meistens um 15-45 Prozent langsamer, in Spezialfällen um einen Faktor 30-50 (System!) langsamer. Als Hardware wurde ein Pentium60-PC benutzt. ====================================================================== T A B E L L E über Arbeitstempo und zugehörige Zeitfaktoren ====================================================================== bish ************************************************************ ksh ******************************************* zsh ***** bash *** csh ** 4dos * sh - ---------------------------------------------------------------------- Script bish ksh zsh bash csh sh 4dos.com ---------------------------------------------------------------------- loop 1 1.11 11.4 19.4 39.0 205. 37.2 loop 1 1.07 9.1 19.3 30.6 33.9 27.0 s70 1 1.64 12.9 ---- 29.3 265. 52.2 s70 1 1.64 12.7 ---- 29.1 51.8 47.2 ---------------------------------------------------------------------- bish und SCO-ksh verweisen alle anderen auf die Plätze! ---------------------------------------------------------------------- Celeron366: bish: 0.055 (loop) ksh : 0.085 (loop) timex bish -p loop.bish # bish 9000 # Ausgabe des Scripts # Ausgabe des Zeitnahme-Kommandos: real 0.73 # 1.0 (Zeitfaktor) user 0.70 # 1.0 (Zeitfaktor) sys 0.03 real 0.99 # 1.0 timex-Messung unter DOS timex ksh -p loop.ksh # ksh (SCO-Unix) 9000 real 0.81 # 1.11 (Zeitfaktor) user 0.75 # 1.07 (Zeitfaktor) sys 0.06 timex zsh loop.ksh # zsh (GNU) 9000 real 8.29 # 11.4 (Zeitfaktor) user 6.35 # 9.07 (Zeitfaktor) sys 1.94 timex bash loop.ksh # bash (BourneAgainShell) 9000 real 14.19 # 19.4 (Zeitfaktor) user 13.54 # 19.3 (Zeitfaktor) sys 0.65 timex csh -f loop.csh # csh 9000 real 28.44 # 39.0 (Zeitfaktor) user 21.44 # 30.6 (Zeitfaktor) sys 6.99 timex sh loop.sh # sh (Bourne-Shell) 9000 real 2:29.76 # 205 (Zeitfaktor) user 23.72 # 33.9 (Zeitfaktor) sys 1:57.06 timex 4dos /c loop.bat # 4dos.com ; Messung unter DOS! 9000 real 36.80 # 37.2 (Zeitfaktor) = 36.8/0.99 timex 4dos /c loop.btm # 4dos.com ; Messung unter DOS! real 26.75 # 27.0 (Zeitfaktor) = 26.75/0.99 timex bish -p s70.bish 1111111111 # bish Fr, 18.3.2005 1:58:31 # Ausgabe des Scripts real 0.014 # 1.0 (10xMessung) user 0.011 # 1.0 sys 0.003 real 0.022 # timex-Messung unter DOS timex ksh -p s70.ksh 1111111111 # ksh (SCO-Unix) Fr, 18.3.2005 1:58:31 # Ausgabe des Scripts real 0.023 # 1.64 (10xMessung) user 0.018 # 1.64 sys 0.006 timex zsh s70.ksh 1111111111 # zsh (GNU) Do, 18.4.2005 1:58:0 # Ausgabe des Scripts real 0.18 # 12.9 user 0.14 # 12.7 sys 0.04 timex csh -f s70.csh 1111111111 # csh Fr, 18.3.2005 1:58:31 real 0.41 # 29.3 user 0.32 # 29.1 sys 0.04 timex sh s70.sh 1111111111 # sh Fr, 18.3.2005 1:58:31 real 3.71 # 265-mal langsamer! user 0.57 # 51.8 (haupts.wg. `expr ...`) sys 3.01 # Haupts.wg. expr=externes Kommando. timex 4dos /E:2000 /C s70.bat 1111111111 " Fr, 18.3.2005 1:58:31" # Ausgabe des Scripts real 1.148 # 52.2 (10xMessung unter DOS) timex 4dos /E:2000 /C s70.btm 1111111111 " Fr, 18.3.2005 1:58:31" # Ausgabe des Scripts real 1.038 # 47.2 (10xMessung unter DOS) timex ksh -p s70.sh 1111111111 # ksh: s70.sh !!! Fr, 18.3.2005 1:58:31 real 6.33 # 452 user 1.66 # 151 (haupts.wg. `expr ...`) sys 4.63 # Haupts.wg. expr=externes Kommando. Für die vorstehenden Zeitmessungen wurden Scripts verwendet, die sich möglichst wenig an das System wenden, denn es sollten die Shells selbst verglichen werden und nicht die Systemdienste. Folgendes Beispiel zeigt, daß die Systemfunktionen und/oder das DOS-System zumindest bei doppelter Umlenkung ganz außerordentlich langsam sind. Datei = 100KB: DOS: tr abc ABC < Datei > DateiUC : 4.78 sec UNIX: tr abc ABC < Datei > DateiUC : 0.10 sec Bei Dateizugriffen ohne Umlenkung gibt es kaum Unterschiede. #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #loop.bish typeset -i10 A for A to 10000 repeat do (( A==9000 )) && echo $A done #----------------------------------------------------------------------- #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #loop.csh @ A = 1 while ( $A <= 10000 ) if ( $A == 9000 ) echo $A @ A++ end #----------------------------------------------------------------------- #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #loop.ksh typeset -i10 A=1 while (( A<=10000 )) do (( A==9000 )) && echo $A ((A+=1)) done #----------------------------------------------------------------------- #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #loop.sh A=1 while [ $A -le 10000 ] do test $A -eq 9000 && echo $A A=`expr $A + 1` done #----------------------------------------------------------------------- #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: REM loop.bat/loop.btm:4dos.com @echo off do A = 1 to 10000 if %A eq 9000 echo %A enddo #----------------------------------------------------------------------- Die folgenden fünf Shell-Scripts erzeugen Wochentag, Datum und Uhrzeit aufgrund einer Zeitangabe in Anzahl Sekunden. Sie sind Grundlage für obenstehende Zeitmeßwerte. #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #!/u/bin/bish [ $# -lt 1 ] && echo " Argument: Sekunden seit 1.1.1970 00:00:00" [ $# -lt 1 ] && exit 1 [ "$1" = -h ] && echo " Argument: Sekunden seit 1.1.1970 00:00:00" && exit typeset -i10 corr j sec SPT m cjsj typeset -i10 tm_mday tm_hour tm_min tm_wday tm_sec tm_mon tm_year sec=$1 ((SPT=24*3600)) array MA $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT (( MA1*=31, MA2*=28, MA3*=31, MA4*=30, MA5*=31, MA6*=30, MA7*=31, MA8*=31, MA9*=30, MA10*=31, MA11*=30, MA12*=31 )) #MA[1]*=31, etc., ist auch möglich array WA So Mo Di Mi Do Fr Sa j=1970 repeat do (( cjsj=0, corr= SPT*365 + (j%4==0&&j%100||j%400==0 ? (++cjsj,SPT) : 0), sec<corr )) && break (( sec-=corr, ++j )) done m=1 repeat do array corr=MA m (( corr+= m==2&&cjsj ? SPT : 0, sec<corr )) && break (( sec-=corr, ++m )) done (( tm_mday=sec/SPT+1, sec%=SPT, tm_hour=sec/3600, sec%=3600, tm_min=sec/60, sec%=60 )) let "tm_wday=( $1 %% (SPT*7) )/SPT+4" #1.1.1970=Do=4 (( tm_wday-= tm_wday>6?7:0, ++tm_wday )) tm_sec=$sec tm_mon=$m tm_year=$j # tm_yday=0 tm_isdst=0 array WAwd=WA $tm_wday echo " $WAwd, $tm_mday.$tm_mon.$tm_year $tm_hour:$tm_min:$tm_sec" #----------------------------------------------------------------------- #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #!/bin/csh #s70.csh if ( $#argv < 1 ) echo " Argument: Sekunden seit 1.1.1970 00:00:00" if ( $#argv < 1 ) exit (1) if ($argv[1] == -h) then echo " Argument: Sekunden seit 1.1.1970 00:00:00" ; exit endif # set sec=$1 @ SPT = 24 * 3600 set MA=($SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT) @ MA[1] *= 31 ; @ MA[2] *= 28 ; @ MA[3] *= 31 ; @ MA[4] *= 30 ; @ MA[5] *= 31 ; @ MA[6] *= 30 ; @ MA[7] *= 31 ; @ MA[8] *= 31 ; @ MA[9] *= 30 ; @ MA[10] *= 31 ; @ MA[11] *= 30 ; @ MA[12] *= 31 ; set WA=(So Mo Di Mi Do Fr Sa) # @ j = 1970 while ( 1 ) @ cjsj = 0 if ( ! ($j % 4) && ($j % 100) || ! ($j % 400) ) @ cjsj = 1 @ corr = $SPT * 365 if ( $cjsj ) @ corr += $SPT if ( $sec < $corr ) break @ sec -= $corr @ j++ end @ m = 1 while ( 1 ) @ corr = $MA[$m] if ( $m == 2 && $cjsj ) @ corr += $SPT if ( $sec < $corr ) break @ sec -= $corr @ m++ end # @ tm_mday = $sec / $SPT + 1 @ sec %= $SPT @ tm_hour = $sec / 3600 @ sec %= 3600 @ tm_min = $sec / 60 @ sec %= 60 # @ tm_wday = ($1 % ($SPT * 7)) / $SPT + 4 #1.1.1970=Do=4 if ($tm_wday > 6) @ tm_wday -= 7 @ tm_wday++ # @ tm_sec = $sec ; @ tm_mon = $m ; @ tm_year = $j # @ tm_yday = 0 ; @ tm_isdst = 0 # echo " $WA[$tm_wday], $tm_mday.$tm_mon.$tm_year ${tm_hour}:${tm_min}:$tm_sec" #----------------------------------------------------------------------- #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #!/bin/ksh [[ $# -lt 1 ]] && echo " Argument: Sekunden seit 1.1.1970 00:00:00" [[ $# -lt 1 ]] && exit 1 [[ "$1" = -h ]] && echo " Argument: Sekunden seit 1.1.1970 00:00:00" && exit typeset -i10 corr=0 j=0 sec=0 SPT=0 m=0 cjsj=0 typeset -i10 tm_mday tm_hour tm_min tm_wday tm_sec tm_mon tm_year sec=$1 ((SPT=24*3600)) set -A MA 1 $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT (( MA[1]*=31 )) ; (( MA[2]*=28 )) ; (( MA[3]*=31 )) (( MA[4]*=30 )) ; (( MA[5]*=31 )) ; (( MA[6]*=30 )) (( MA[7]*=31 )) ; (( MA[8]*=31 )) ; (( MA[9]*=30 )) (( MA[10]*=31 )) ; (( MA[11]*=30 )) ; (( MA[12]*=31 )) j=1970 while : do cjsj=0 (( j%4==0 && j%100 || j%400==0 )) && cjsj=1 ((corr=SPT*365)) (( cjsj>0 )) && ((corr+=SPT)) (( sec<corr )) && break ((sec-=corr)) ; ((j+=1)) done m=1 while : do corr=${MA[$m]} (( m==2 && cjsj )) && (( corr+=SPT )) (( sec<corr )) && break (( sec-=corr )) ; (( m+=1 )) done (( tm_mday=sec/SPT+1 )) ; (( sec%=SPT )) (( tm_hour=sec/3600 )) ; (( sec%=3600 )) (( tm_min=sec/60 )) ; (( sec%=60 )) let "tm_wday=( $1 % (SPT*7) )/SPT+4" #1.1.1970=Do=4 (( $tm_wday>6 )) && (( tm_wday-=7 )) (( tm_wday+=1 )) tm_sec=$sec tm_mon=$m tm_year=$j # tm_yday=0 tm_isdst=0 set -A WTA sa so Mo Di Mi Do Fr Sa So WAwd=${WTA[$tm_wday]} echo " $WAwd, $tm_mday.$tm_mon.$tm_year $tm_hour:$tm_min:$tm_sec" #----------------------------------------------------------------------- #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #!/bin/sh #s70.sh [ $# -lt 1 ] && echo " Argument: Sekunden seit 1.1.1970 00:00:00" [ $# -lt 1 ] && exit 1 [ "$1" = -h ] && echo " Argument: Sekunden seit 1.1.1970 00:00:00" && exit sec=$1 SPT=`expr 24 '*' 3600` MA1=$SPT MA2=$SPT MA3=$SPT MA4=$SPT MA5=$SPT MA6=$SPT MA7=$SPT MA8=$SPT MA9=$SPT MA10=$SPT MA11=$SPT MA12=$SPT MA1=`expr $MA1 '*' 31`; MA2=`expr $MA2 '*' 28`; MA3=`expr $MA3 '*' 31` MA4=`expr $MA4 '*' 30`; MA5=`expr $MA5 '*' 31`; MA6=`expr $MA6 '*' 30` MA7=`expr $MA7 '*' 31`; MA8=`expr $MA8 '*' 31`; MA9=`expr $MA9 '*' 30` MA10=`expr $MA10 '*' 31`;MA11=`expr $MA11 '*' 30`;MA12=`expr $MA12 '*' 31` WA1=So WA2=Mo WA3=Di WA4=Mi WA5=Do WA6=Fr WA7=Sa j=1970 while : do cjsj=0 [ `expr $j % 4` -eq 0 -a `expr $j % 100` -ne 0 -o `expr $j % 400` -eq 0 ] && cjsj=1 corr=`expr $SPT '*' 365` [ $cjsj -gt 0 ] && corr=`expr $corr + $SPT` [ $sec -lt $corr ] && break sec=`expr $sec - $corr`; j=`expr $j + 1` done m=1 while : do eval 'corr=$MA'$m [ $m -eq 2 -a $cjsj -ne 0 ] && corr=`expr $corr + $SPT` [ $sec -lt $corr ] && break sec=`expr $sec - $corr` ; m=`expr $m + 1` done tm_mday=`expr $sec / $SPT + 1` ; sec=`expr $sec % $SPT` tm_hour=`expr $sec / 3600` ; sec=`expr $sec % 3600` tm_min=`expr $sec / 60` ; sec=`expr $sec % 60` tm_wday=`expr \( $1 % \( $SPT \* 7 \) \) / $SPT + 4` #1.1.1970=Do=4 [ $tm_wday -gt 6 ] && tm_wday=`expr $tm_wday - 7` tm_wday=`expr $tm_wday + 1` tm_sec=$sec tm_mon=$m tm_year=$j # tm_yday=0 tm_isdst=0 eval 'WAwd=$WA'$tm_wday echo " $WAwd, $tm_mday.$tm_mon.$tm_year $tm_hour:$tm_min:$tm_sec" #----------------------------------------------------------------------- #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: @echo off Rem 4dos.com Rem loadbtm on if %# LT 1 (echo " Argument: Sekunden seit 1.1.1970 00:00:00" ^ exit 1) if "%1"=="-h" (echo " Argument: Sekunden seit 1.1.1970 00:00:00" ^ exit) setdos /F0.0 set corr=0 ^ set j=0 ^ set sec=0 ^ set SPT=0 ^ set m=0 ^ set cjsj=0 set tm_mday=0 ^ set tm_hour=0 ^ set tm_min=0 ^ set tm_wday=0 set tm_sec=0 ^ set tm_mon=0 ^ set tm_year=0 do 10 set sec=%1 set SPT=%@eval[24*3600] set MA1=%@eval[%SPT * 31] ^ set MA2=%@eval[%SPT * 28] set MA3=%@eval[%SPT * 31] ^ set MA4=%@eval[%SPT * 30] set MA5=%@eval[%SPT * 31] ^ set MA6=%@eval[%SPT * 30] set MA7=%@eval[%SPT * 31] ^ set MA8=%@eval[%SPT * 31] set MA9=%@eval[%SPT * 30] ^ set MA10=%@eval[%SPT * 31] set MA11=%@eval[%SPT * 30] ^ set MA12=%@eval[%SPT * 31] set WA1=So ^ set WA2=Mo ^ set WA3=Di ^ set WA4=Mi set WA5=Do ^ set WA6=Fr ^ set WA7=Sa set j=1970 do forever set cjsj=0 if %@eval[%j %% 4] EQ 0 .AND. %@eval[%j %% 100] NE 0 set cjsj=1 if %@eval[%j %% 400] EQ 0 set cjsj=1 set corr=%@eval[%SPT * 365 + %cjsj * %SPT] if %sec LT %corr leave set sec=%@eval[%sec - %corr] ^ set j=%@inc[%j] enddo Rem array corr=MA m set m=1 do forever set corr=%[MA%m] if %m EQ 2 .AND. %cjsj NE 0 set corr=%@eval[%corr + %SPT] if %sec LT %corr leave set sec=%@eval[%sec - %corr] ^ set m=%@inc[%m] enddo set tm_mday=%@eval[%sec \ %SPT + 1] ^ set sec=%@eval[%sec %% %SPT] set tm_hour=%@eval[%sec \ 3600] ^ set sec=%@eval[%sec %% 3600] set tm_min=%@eval[%sec \ 60] ^ set sec=%@eval[%sec %% 60] set tm_wday=%@eval[ ( %1 %% (%SPT * 7) ) \ %SPT + 4] Rem 1.1.1970=Do=4 if %tm_wday GT 6 set tm_wday=%@eval[ %tm_wday - 7 ] set tm_wday=%@inc[%tm_wday] set tm_sec=%sec ^ set tm_mon=%m ^ set tm_year=%j Rem tm_yday=0 tm_isdst=0 set WAwd=%[WA%tm_wday] echo " %WAwd, %tm_mday.%tm_mon.%tm_year %tm_hour:%tm_min:%tm_sec" enddo #----------------------------------------------------------------------- AUTOR Helmut Schellong, Bad Salzuflen |