Es ist zwar richtig, dass einige Shell - Buildins in einem vollständigen Handbuch nur einen geringen Umfang aufweisen können - insbesondere für diejenigen - bash
spezifischen Buildins, die Sie wahrscheinlich nur auf einem GNU - System verwenden (die GNU - Leute glauben in der Regel nicht an man
und) bevorzugen ihre eigenen info
Seiten) - die überwiegende Mehrheit der POSIX-Dienstprogramme - Shell-Builtins oder andere - sind im POSIX-Programmierhandbuch sehr gut vertreten.
Hier ist ein Auszug aus dem unteren Teil von meinem man sh
(der wahrscheinlich 20 Seiten lang ist oder so ...)
Alle diese sind da, und andere wie nicht erwähnt set
, read
, break
... na ja, brauche ich nicht , sie alle zu nennen. Beachten Sie jedoch die (1P)
unten rechts angezeigte POSIX-Handbuchserie der Kategorie 1 - das sind die man
Seiten, über die ich spreche.
Es kann sein, dass Sie nur ein Paket installieren müssen? Dies sieht für ein Debian-System vielversprechend aus. Während help
es nützlich ist, wenn Sie es finden können, sollten Sie auf jeden Fall diese POSIX Programmer's Guide
Serie bekommen. Das kann sehr hilfreich sein. Die einzelnen Seiten sind sehr detailliert.
Abgesehen davon werden Shell-Builtins fast immer in einem bestimmten Abschnitt des jeweiligen Shell-Handbuchs aufgeführt. zsh
Zum Beispiel hat eine ganze separate man
Seite dafür - (ich denke, es summiert sich auf 8 oder 9 oder so einzelne zsh
Seiten - einschließlich der, zshall
die riesig ist.)
Sie können nur grep
man
natürlich nur:
man bash 2>/dev/null |
grep '^[[:blank:]]*read [^`]*[-[]' -A14
read [-ers] [-a aname] [-d delim] [-i text] [-n
nchars] [-N nchars] [-p prompt] [-t timeout] [-u
fd] [name ...]
One line is read from the standard input, or
from the file descriptor fd supplied as an
argument to the -u option, and the first
word is assigned to the first name, the sec‐
ond word to the second name, and so on, with
leftover words and their intervening separa‐
tors assigned to the last name. If there
are fewer words read from the input stream
than names, the remaining names are assigned
empty values. The characters in IFS are
used to split the line into words using the
same rules the shell uses for expansion
... was ziemlich genau dem entspricht, was ich früher beim Durchsuchen einer Shell gemacht habe man
Seite gemacht habe. Aber help
ist ziemlich gut in bash
in den meisten Fällen.
Ich habe in sed
letzter Zeit tatsächlich an einem Skript gearbeitet, um mit solchen Dingen umzugehen. So habe ich den Abschnitt im Bild oben aufgenommen. Es ist immer noch länger als ich es mag, aber es verbessert sich - und es kann ziemlich praktisch sein. In seiner aktuellen Iteration wird es einen kontextsensitiven Textabschnitt ziemlich zuverlässig extrahieren, der mit einem Abschnitt oder einer Unterabschnittsüberschrift übereinstimmt, basierend auf [a] pattern [s], das es in der Befehlszeile gibt. Es färbt seine Ausgabe und druckt nach Standard.
Es funktioniert durch Auswerten von Einzugsebenen. Nicht-leere Eingabezeilen werden im Allgemeinen ignoriert, aber wenn sie auf eine leere Zeile treffen, beginnt sie zu achten. Von dort sammelt es Zeilen, bis es überprüft hat, dass die aktuelle Sequenz definitiv weiter eingerückt ist als die erste Zeile, bevor eine weitere Leerzeile auftritt, oder es löscht den Thread und wartet auf das nächste Leerzeichen. Wenn der Test erfolgreich ist, wird versucht, die Führungslinie mit ihren Befehlszeilenargumenten abzugleichen.
Dies bedeutet, dass ein Übereinstimmungsmuster übereinstimmt mit:
heading
match ...
...
...
text...
..und..
match
text
..aber nicht..
heading
match
match
notmatch
..oder..
text
match
match
text
more text
Wenn eine Übereinstimmung gefunden werden kann, wird der Druckvorgang gestartet. Dabei werden die führenden Leerzeichen der übereinstimmenden Zeile aus allen gedruckten Zeilen entfernt. Unabhängig von der Einrückungsstufe wird diese Zeile so gedruckt, als befänden sie sich oben. Es wird so lange gedruckt, bis es auf eine andere Zeile stößt, deren Einzug gleich oder geringer ist als der der übereinstimmenden Zeile. Daher werden ganze Abschnitte mit nur einer Überschriftenübereinstimmung erfasst, einschließlich aller Unterabschnitte und Absätze, die sie möglicherweise enthalten.
Wenn Sie also darum bitten, ein Muster abzugleichen, wird dies nur für eine Betreff-Überschrift durchgeführt und der gesamte Text innerhalb des Abschnitts mit der Überschrift für die Übereinstimmung wird gefärbt und gedruckt. Dabei wird nichts außer dem Einzug der ersten Zeile gespeichert. Dies ist sehr schnell und ermöglicht die Verarbeitung von \n
E-Line-getrennten Eingaben in praktisch jeder Größe.
Es dauerte eine Weile, bis ich herausgefunden hatte, wie ich mich in Unterüberschriften wie die folgenden einteilen konnte:
Section Heading
Subsection Heading
Aber ich habe es irgendwann geklärt.
Der Einfachheit halber musste ich das Ganze jedoch überarbeiten. Während ich zuvor mehrere kleine Schleifen hatte, die zumeist die gleichen Dinge auf etwas unterschiedliche Weise taten, um ihrem Kontext zu entsprechen, gelang es mir, durch Variation der Rekursionsmethoden den größten Teil des Codes zu de-duplizieren. Jetzt gibt es zwei Schleifen - eine druckt und eine prüft den Einzug. Beide hängen von demselben Test ab - die Druckschleife startet, wenn der Test bestanden wird, und die Einrückschleife übernimmt, wenn der Test fehlschlägt oder in einer leeren Zeile beginnt.
Der gesamte Vorgang ist sehr schnell, da in den meisten /./d
Fällen nur nicht leere Zeilen entfernt und zur nächsten Zeile gewechselt werden. Dies ergibt sich sogar aus zshall
dem sofortigen Auffüllen des Bildschirms. Das hat sich nicht geändert.
Sowieso ist es bis jetzt sehr nützlich. Zum Beispiel kann das read
oben Gesagte so gemacht werden:
mansed bash read
... und es wird der ganze Block. Es kann ein beliebiges Muster oder was auch immer oder mehrere Argumente annehmen, obwohl das erste immer die man
Seite ist, auf der gesucht werden soll. Hier ist ein Bild von einigen seiner Ausgaben, nachdem ich es getan habe:
mansed bash read printf
... beide Blöcke werden als Ganzes zurückgegeben. Ich benutze es oft wie:
mansed ksh '[Cc]ommand.*'
... wofür es ganz nützlich ist. Außerdem SYNOPS[ES]
macht das Erhalten es wirklich praktisch:
Hier ist es, wenn Sie es versuchen wollen - ich werde Ihnen keine Vorwürfe machen, wenn Sie es nicht tun.
mansed() {
MAN_KEEP_FORMATTING=1 man "$1" 2>/dev/null | ( shift
b='[:blank:]' s='[:space:]' bs=$(printf \\b) esc=$(printf '\033\[') n='\
' match=$(printf "\([${b}]*%s[${b}].*\)*" "$@")
sed -n "1p
/\n/!{ /./{ \$p;d
};x; /.*\n/!g;s///;x
:indent
/.*\n\n/{s///;x
};n;\$p;
/^\([^${s}].*\)*$/{s/./ &/;h; b indent
};x; s/.*\n[^-[]*\n.*//; /./!x;t
s/[${s}]*$//; s/\n[${b}]\{2,\}/${n} /;G;h
};
#test
/^\([${b}]*\)\([^${b}].*\n\)\1\([${b}]\)/!b indent
s//\1\2.\3/
:print
/^[${s}]*\n\./{ s///;s/\n\./${n}/
/${bs}/{s/\n/ & /g;
s/\(\(.\)${bs}\2\)\{1,\}/${esc}38;5;35m&${esc}0m/g
s/\(_${bs}[^_]\)\{1,\}/${esc}38;5;75m&${esc}0m/g
s/.${bs}//g;s/ \n /${n}/g
s/\(\(${esc}\)0m\2[^m]*m[_ ]\{,2\}\)\{2\}/_/g
};p;g;N;/\n$/!D
s//./; t print
};
#match
s/\n.*/ /; s/.${bs}//g
s/^\(${match}\).*/${n}\1/
/../{ s/^\([${s}]*\)\(.*\)/\1${n}/
x; s//${n}\1${n}. \2/; P
};D
");}
Kurz gesagt, der Workflow ist:
- Jede Zeile, die nicht leer ist und kein
\n
ewline-Zeichen enthält, wird aus der Ausgabe gelöscht.
\n
ewline-Zeichen kommen im Eingabemusterraum nie vor. Sie können nur als Ergebnis einer Bearbeitung erhalten werden.
:print
und :indent
sind beide voneinander abhängige geschlossene Schleifen und der einzige Weg, eine \n
ewline zu erhalten .
:print
Der Schleifenzyklus von beginnt, wenn die führenden Zeichen in einer Zeile eine Reihe von Leerzeichen gefolgt von einem \n
ewline-Zeichen sind.
:indent
Der Zyklus beginnt in Leerzeilen - oder in :print
Zykluszeilen, die fehlschlagen #test
-, :indent
entfernt jedoch alle führenden Leerzeichen + \n
ewline-Sequenzen aus der Ausgabe.
- Sobald der
:print
Vorgang beginnt, werden die Eingabezeilen weiter eingezogen, führende Leerzeichen werden bis zu dem in der ersten Zeile des Zyklus angegebenen Wert entfernt, Über- und Unterstriche werden in Farbausblendungen umgewandelt und die Ergebnisse werden gedruckt, bis der #test
Vorgang fehlschlägt.
- before
:indent
starts prüft zuerst den h
alten Speicherplatz auf mögliche Einrückungsfortsetzungen (z. B. einen Unterabschnitt) und zieht dann die Eingabe weiter ein, solange dies #test
fehlschlägt und jede Zeile, die auf die erste folgt, weiterhin übereinstimmt [-
. Wenn eine Zeile nach der ersten nicht mit diesem Muster übereinstimmt, wird sie gelöscht. Anschließend werden alle folgenden Zeilen bis zur nächsten leeren Zeile gelöscht.
#match
und #test
überbrücken Sie die beiden geschlossenen Schleifen.
#test
wird ausgeführt, wenn die führende Reihe von Leerzeichen kürzer ist als die Reihe, gefolgt von der letzten \n
ewline in einer Zeilenfolge.
#match
Stellt die führenden \n
E- Zeilen, die zum Starten eines :print
Zyklus benötigt werden, vor die :indent
Ausgabesequenzen, die zu einer Übereinstimmung mit einem Befehlszeilenargument führen. Die Sequenzen, die nicht leer gerendert werden - und die resultierende Leerzeile wird an zurückgegeben :indent
.