Embora seja verdade que alguns componentes internos do shell podem ter pouca exibição em um manual completo - especialmente para aqueles bash
componentes específicos que você provavelmente só usa em um sistema GNU (o pessoal do GNU, por via de regra, não acredita man
e preferem suas próprias info
páginas) - a grande maioria dos utilitários POSIX - embutidos no shell ou outros - estão muito bem representados no Guia do Programador do POSIX.
Aqui está um trecho da parte inferior do meu man sh
(que provavelmente tem 20 páginas ou mais ...)
Todos esses estão lá, e outros não mencionados, como set
, read
, break
... bem, eu não preciso nomeá-los todos. Mas observe o (1P)
canto inferior direito - denota a série de manuais da categoria 1 do POSIX - são essas as man
páginas das quais estou falando.
Pode ser que você só precise instalar um pacote? Isso parece promissor para um sistema Debian. Embora help
seja útil, se você puder encontrá-lo, definitivamente deverá obter essa POSIX Programmer's Guide
série. Pode ser extremamente útil. E suas páginas constituintes são muito detalhadas.
Além disso, os buildins do shell quase sempre são listados em uma seção específica do manual do shell específico. zsh
, por exemplo, tem uma man
página inteira separada para isso (acho que totaliza 8 ou 9 zsh
páginas individuais ), incluindo o zshall
que é enorme.
Você pode, é grep
man
claro:
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
... o que é bem parecido com o que costumava fazer ao pesquisar uma man
página de shell . Mas help
é muito bom bash
na maioria dos casos.
Na verdade, eu tenho trabalhado em um sed
script para lidar com esse tipo de coisa recentemente. Foi assim que peguei a seção na foto acima. Ainda é mais longo do que eu gosto, mas está melhorando - e pode ser bastante útil. Em sua iteração atual, ele extrai de maneira bastante confiável uma seção de texto sensível ao contexto, correspondente a uma seção ou cabeçalho de subseção com base nos [a] padrões [s] dados na linha de comando. Ele colore sua saída e imprima em stdout.
Ele funciona avaliando os níveis de recuo. Linhas de entrada não em branco geralmente são ignoradas, mas quando encontra uma linha em branco, começa a prestar atenção. Ele reúne linhas a partir daí até verificar que a sequência atual definitivamente recua ainda mais do que sua primeira linha antes que outra linha em branco ocorra, ou então deixa cair o segmento e aguarda o próximo espaço em branco. Se o teste for bem-sucedido, ele tenta combinar a linha de chumbo com seus argumentos da linha de comando.
Isto significa que um jogo padrão irá corresponder:
heading
match ...
...
...
text...
..e..
match
text
..mas não..
heading
match
match
notmatch
..ou..
text
match
match
text
more text
Se houver uma correspondência, ela começa a imprimir. Ele removerá os espaços em branco principais da linha correspondente de todas as linhas impressas - portanto, não importa o nível de indentação encontrado, a linha impressa como se estivesse no topo. Ele continuará sendo impresso até encontrar outra linha em um nível igual ou inferior ao recuo que sua linha correspondente - para que seções inteiras sejam agarradas apenas com uma correspondência de cabeçalho, incluindo todas / todas as subseções, parágrafos que possam conter.
Então, basicamente, se você solicitar que ele corresponda a um padrão, ele o fará apenas contra um cabeçalho de assunto de algum tipo e colorirá e imprimirá todo o texto encontrado na seção encabeçada por sua correspondência. Nada é salvo assim, exceto o recuo da primeira linha - e, portanto, pode ser muito rápido e lidar com \n
entradas separadas por linha de ew de praticamente qualquer tamanho.
Levei um tempo para descobrir como recursar em subtítulos como o seguinte:
Section Heading
Subsection Heading
Mas eu resolvi isso eventualmente.
Eu tive que refazer a coisa toda por uma questão de simplicidade, no entanto. Embora antes eu tivesse vários pequenos loops fazendo basicamente as mesmas coisas de maneiras ligeiramente diferentes para se ajustarem ao seu contexto, variando seus meios de recursão, eu consegui desduplicar a maioria do código. Agora existem dois loops - um imprime e um verifica recuo. Ambos dependem do mesmo teste - o loop de impressão inicia quando o teste passa e o loop de recuo assume o controle quando falha ou inicia em uma linha em branco.
Todo o processo é muito rápido, porque na maioria das vezes /./d
elimina qualquer linha que não esteja em branco e passa para a próxima - resulta mesmo de zshall
preencher a tela instantaneamente. Isso não mudou.
De qualquer forma, é muito útil até agora, no entanto. Por exemplo, a read
coisa acima pode ser feita como:
mansed bash read
... e fica com o bloco inteiro. Pode levar qualquer padrão ou qualquer outra coisa, ou vários argumentos, embora o primeiro seja sempre a man
página na qual ele deve pesquisar. Aqui está uma imagem de alguns de seus resultados depois que eu fiz:
mansed bash read printf
... os dois blocos são retornados inteiros. Costumo usá-lo como:
mansed ksh '[Cc]ommand.*'
... para o qual é bastante útil. Além disso, obter o SYNOPS[ES]
torna realmente útil:
Aqui está, se você quiser dar uma guinada - não vou te culpar se não o fizer.
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
");}
Resumidamente, o fluxo de trabalho é:
- qualquer linha que não esteja em branco e que não contenha um
\n
caractere ewline será excluída da saída.
\n
Os caracteres ewline nunca ocorrem no espaço do padrão de entrada. Eles só podem ser obtidos como resultado de uma edição.
:print
e :indent
são loops fechados mutuamente dependentes e são a única maneira de obter uma linha de \n
ew.
:print
O ciclo de loop do começa se os caracteres \n
iniciais de uma linha são uma série de espaços em branco seguidos por um caractere de linha de ew.
:indent
O ciclo começa em linhas em branco - ou em :print
linhas de ciclo que falham #test
- mas :indent
remove todas as principais \n
seqüências em branco + linha de linha de saída de sua saída.
- uma vez
:print
iniciado, ele continuará puxando as linhas de entrada, eliminando os espaços em branco até a quantidade encontrada na primeira linha do seu ciclo, convertendo escapamentos de overstrike e understrike em backspace em escapes terminais coloridos e imprimindo os resultados até #test
falhar.
- antes do
:indent
início, ele primeiro verifica o h
espaço antigo quanto a qualquer possível continuação de recuo (como uma subseção) e continua a receber entradas desde que #test
falhe e qualquer linha após a primeira continua a corresponder [-
. Quando uma linha após a primeira não corresponde a esse padrão, ela é excluída - e, posteriormente, todas as linhas seguintes são seguidas até a próxima linha em branco.
#match
e #test
colmatar os dois loops fechados.
#test
passa quando a série principal de espaços em branco é menor que a série seguida pela última \n
linha de ew em uma sequência de linhas.
#match
\n
precede as linhas de linha principais necessárias para iniciar um :print
ciclo para qualquer uma das :indent
seqüências de saída que levam uma correspondência a qualquer argumento da linha de comando. Aquelas seqüências que não são renderizadas em branco - e a linha em branco resultante é passada de volta para :indent
.