Sebbene sia vero che alcuni builtin della shell potrebbero avere una scarsa visualizzazione in un manuale completo, specialmente per quei bash
builtin specifici che è probabile che tu utilizzi solo su un sistema GNU (la gente GNU, di regola, non crede man
e preferiscono le proprie info
pagine) - la stragrande maggioranza delle utility POSIX - shell incorporate o altro - sono ben rappresentate nella Guida del programmatore POSIX.
Ecco un estratto dal fondo del mio man sh
(che probabilmente è lungo circa 20 pagine ...)
Tutti questi sono lì, e gli altri non menzionati, come set
, read
, break
... beh, non ho bisogno di nominarli tutti. Ma nota (1P)
in basso a destra - indica la serie di manuali POSIX categoria 1 - quelle sono le man
pagine di cui sto parlando.
Potrebbe essere che hai solo bisogno di installare un pacchetto? Questo sembra essere molto promettente per un sistema Debian. Sebbene help
sia utile, se riesci a trovarlo, dovresti assolutamente ottenere quella POSIX Programmer's Guide
serie. Può essere estremamente utile. E le sue pagine costitutive sono molto dettagliate.
A parte questo, i builtin della shell sono quasi sempre elencati in una sezione specifica del manuale specifico della shell. zsh
, per esempio, ha un'intera man
pagina separata per questo - (penso che ammonti a 8 o 9 o più zsh
pagine singole - incluso zshall
che è enorme.)
grep
man
Ovviamente puoi semplicemente :
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
... che è abbastanza vicino a quello che facevo quando cercavo una man
pagina di shell . Ma help
è abbastanza buono bash
nella maggior parte dei casi.
Ho lavorato a una sed
sceneggiatura per gestire questo tipo di cose di recente. È come ho afferrato la sezione nella foto sopra. È ancora più lungo di quanto mi piaccia, ma sta migliorando - e può essere molto utile. Nella sua attuale iterazione estrarrà in modo abbastanza affidabile una sezione di testo sensibile al contesto abbinata a una sezione o un'intestazione di sottosezione basata su [a] pattern [s] forniti nella riga di comando. Colora il suo output e stampa su stdout.
Funziona valutando i livelli di rientro. Le righe di input non vuote vengono generalmente ignorate, ma quando incontra una riga vuota inizia a prestare attenzione. Raccoglie le linee da lì fino a quando non ha verificato che la sequenza corrente rientra decisamente più in profondità rispetto alla prima riga prima che si verifichi un'altra riga vuota, altrimenti lascia cadere il thread e attende il vuoto successivo. Se il test ha esito positivo, tenta di far corrispondere la linea guida ai suoi argomenti della riga di comando.
Ciò significa che una partita di pattern partita:
heading
match ...
...
...
text...
..e..
match
text
..ma no..
heading
match
match
notmatch
..o..
text
match
match
text
more text
Se si può avere una corrispondenza, inizia a stampare. Spoglia gli spazi vuoti iniziali della linea abbinata da tutte le linee che stampa - quindi, indipendentemente dal livello di rientro che ha trovato quella linea su di essa, la stampa come se fosse in alto. Continuerà a stampare fino a quando non incontra un'altra riga a un livello uguale o inferiore al rientro rispetto alla riga corrispondente - quindi intere sezioni vengono acquisite con solo una corrispondenza di intestazione, inclusi eventuali sottotitoli, tutti i paragrafi che potrebbero contenere.
Quindi, fondamentalmente, se gli chiedi di abbinare uno schema, lo farà solo contro un titolo del soggetto di qualche tipo e colorerà e stamperà tutto il testo che trova nella sezione diretta dalla sua corrispondenza. Nulla viene salvato mentre lo fa tranne il rientro della prima riga, quindi può essere molto veloce e gestire \n
input separati da ewline praticamente di qualsiasi dimensione.
Mi ci è voluto un po 'per capire come ricorrere a sottotitoli come i seguenti:
Section Heading
Subsection Heading
Ma alla fine l'ho risolto.
Ho dovuto rielaborare il tutto per semplicità, però. Mentre prima avevo diversi piccoli loop che facevano principalmente le stesse cose in modi leggermente diversi per adattarsi al loro contesto, variando i loro mezzi di ricorsione sono riuscito a de-duplicare la maggior parte del codice. Ora ci sono due anelli: uno stampa e uno rientra i segni di spunta. Entrambi dipendono dallo stesso test: il ciclo di stampa inizia quando il test viene superato e il ciclo di rientro subentra quando fallisce o inizia su una riga vuota.
L'intero processo è molto veloce perché la maggior parte delle volte /./d
elimina qualsiasi riga non vuota e passa alla successiva - anche i risultati di zshall
popolano lo schermo all'istante. Questo non è cambiato.
Comunque, finora è molto utile. Ad esempio, la read
cosa sopra può essere fatta come:
mansed bash read
... e ottiene l'intero blocco. Può accettare qualsiasi modello o qualunque cosa, o più argomenti, sebbene il primo sia sempre la man
pagina in cui dovrebbe cercare. Ecco una foto di alcuni dei suoi risultati dopo che l'ho fatto:
mansed bash read printf
... entrambi i blocchi vengono restituiti interi. Lo uso spesso come:
mansed ksh '[Cc]ommand.*'
... per il quale è abbastanza utile. Inoltre, ottenere lo SYNOPS[ES]
rende davvero utile:
Eccolo se vuoi fare un giro - non ti biasimerò se non lo fai.
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
");}
In breve, il flusso di lavoro è:
- qualsiasi riga che non è vuota e che non contiene un
\n
carattere di ewline viene eliminata dall'output.
\n
i caratteri di ewline non si verificano mai nello spazio del motivo di input. Possono essere ottenuti solo come risultato di una modifica.
:print
e :indent
sono entrambi circuiti chiusi reciprocamente dipendenti e sono l'unico modo per ottenere una \n
ewline.
:print
Il ciclo del ciclo inizia se i caratteri \n
iniziali su una riga sono una serie di spazi vuoti seguiti da un carattere ewline.
:indent
Il ciclo inizia su righe vuote - o su :print
linee cicliche che non riescono #test
- ma :indent
rimuove \n
dal suo output tutte le sequenze principali di bianco + ewline.
- una volta
:print
iniziato, continuerà a inserire le righe di input, rimuovere gli spazi bianchi iniziali fino alla quantità trovata sulla prima riga del suo ciclo, tradurre la sovraincisione e minimizzare le escape di backspace in escape di terminali di colore e stampare i risultati fino a quando #test
non riesce.
- prima di
:indent
iniziare, controlla innanzitutto lo h
spazio vecchio per l'eventuale continuazione del rientro (come una sottosezione) , quindi continua a inserire l'input fino a quando #test
non riesce e qualsiasi riga successiva alla prima continua a corrispondere [-
. Quando una riga dopo la prima non corrisponde a quel modello, viene eliminata - e successivamente lo sono anche tutte le righe seguenti fino alla riga vuota successiva.
#match
e #test
getti un ponte sui due anelli chiusi.
#test
passa quando la serie principale di spazi vuoti è più corta della serie seguita dall'ultima \n
ewline in una sequenza di linee.
#match
antepone le \n
linee guida principali necessarie per iniziare un :print
ciclo a una qualsiasi delle :indent
sequenze di output che conducono con una corrispondenza a qualsiasi arg della riga di comando. Quelle sequenze che non vengono rese vuote e la riga vuota risultante viene restituita a :indent
.