Si bien es cierto que algunos componentes integrados de shell pueden tener una escasa presentación en un manual completo, especialmente para aquellos bash
componentes específicos que solo es probable que use en un sistema GNU (la gente de GNU, por regla general, no cree man
y prefieren sus propias info
páginas) - la gran mayoría de las utilidades POSIX - shell incorporadas o no - están muy bien representadas en la Guía del Programador POSIX.
Aquí hay un extracto de la parte inferior de mi man sh
(que probablemente tenga más de 20 páginas ...)
Todos los que están allí, y otros no mencionados, como set
, read
, break
..., bueno, no necesito nombrarlos a todos. Pero tenga (1P)
en cuenta que en la parte inferior derecha, denota la serie de manuales POSIX categoría 1, esas son las man
páginas de las que estoy hablando.
¿Puede ser que solo necesites instalar un paquete? Esto parece prometedor para un sistema Debian. Si bien help
es útil, si puede encontrarlo, definitivamente debería obtener esa POSIX Programmer's Guide
serie. Puede ser extremadamente útil. Y sus páginas constituyentes son muy detalladas.
Aparte de eso, los componentes integrados de shell se enumeran casi siempre en una sección específica del manual de shell específico. zsh
, por ejemplo, tiene una man
página completa para eso (creo que totaliza 8 o 9 zsh
páginas individuales , incluida la zshall
que es enorme).
Por grep
man
supuesto, puedes :
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
... que está bastante cerca de lo que solía hacer cuando buscaba en una man
página de shell . Pero help
es bastante bueno bash
en la mayoría de los casos.
De hecho, he estado trabajando en un sed
script para manejar este tipo de cosas recientemente. Así es como agarré la sección en la imagen de arriba. Todavía es más largo de lo que me gusta, pero está mejorando y puede ser bastante útil. En su iteración actual, extraerá de manera bastante confiable una sección de texto sensible al contexto que coincida con un encabezado de sección o subsección basado en [a] patrón [s] dado en la línea de comando. Colorea su salida e imprime en stdout.
Funciona evaluando los niveles de sangría. Las líneas de entrada no en blanco generalmente se ignoran, pero cuando encuentra una línea en blanco comienza a prestar atención. Reúne líneas desde allí hasta que verifica que la secuencia actual definitivamente sangra más de lo que lo hizo su primera línea antes de que ocurra otra línea en blanco o de lo contrario deja caer el hilo y espera el siguiente espacio en blanco. Si la prueba es exitosa, intenta hacer coincidir la línea principal con sus argumentos de línea de comando.
Esto significa que un partido de patrón que coincida con:
heading
match ...
...
...
text...
..y..
match
text
..pero no..
heading
match
match
notmatch
..o..
text
match
match
text
more text
Si se puede encontrar una coincidencia, comienza a imprimirse. Eliminará los espacios en blanco iniciales de la línea coincidente de todas las líneas que imprime, por lo que, sin importar el nivel de sangría, encontró que la línea en ella la imprime como si estuviera en la parte superior. Continuará imprimiendo hasta que encuentre otra línea en un nivel de sangría igual o menor que su línea coincidente, por lo que secciones enteras se capturan con solo una coincidencia de encabezado, incluidas cualquiera / todas las subsecciones, párrafos que pueden contener.
Básicamente, si le pide que coincida con un patrón, solo lo hará contra un encabezado de tema de algún tipo y coloreará e imprimirá todo el texto que encuentre dentro de la sección encabezada por su coincidencia. Nada se guarda mientras lo hace, excepto la sangría de su primera línea, por lo que puede ser muy rápido y manejar \n
entradas separadas por línea de línea de prácticamente cualquier tamaño.
Me tomó un tiempo descubrir cómo recurrir a subtítulos como el siguiente:
Section Heading
Subsection Heading
Pero lo resolví eventualmente.
Sin embargo, tuve que volver a trabajar todo por simplicidad. Mientras que antes tenía varios bucles pequeños que realizaban principalmente las mismas cosas de maneras ligeramente diferentes para adaptarse a su contexto, al variar sus medios de recursión, logré eliminar la duplicación de la mayoría del código. Ahora hay dos bucles: uno imprime y otro comprueba la sangría. Ambos dependen de la misma prueba: el ciclo de impresión comienza cuando pasa la prueba y el ciclo de sangría se hace cargo cuando falla o comienza en una línea en blanco.
Todo el proceso es muy rápido porque la mayoría de las veces solo /./d
elige cualquier línea que no esté en blanco y pasa a la siguiente, incluso los resultados de zshall
llenar la pantalla al instante. Esto no ha cambiado.
De todos modos, hasta ahora es muy útil. Por ejemplo, read
lo anterior se puede hacer como:
mansed bash read
... y obtiene todo el bloque. Puede tomar cualquier patrón o lo que sea, o múltiples argumentos, aunque el primero es siempre la man
página en la que debe buscar. Aquí hay una foto de algunos de sus resultados después de que lo hice:
mansed bash read printf
... ambos bloques se devuelven enteros. A menudo lo uso como:
mansed ksh '[Cc]ommand.*'
... para lo cual es bastante útil. Además, conseguirlo lo SYNOPS[ES]
hace realmente útil:
Aquí está si quieres darle un giro; no te culparé si no lo haces.
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
");}
Brevemente, el flujo de trabajo es:
- cualquier línea que no esté en blanco y que no contenga un
\n
carácter ewline se eliminará de la salida.
\n
Los caracteres ewline nunca aparecen en el espacio del patrón de entrada. Solo se pueden obtener como resultado de una edición.
:print
y :indent
son bucles cerrados mutuamente dependientes y son la única forma de obtener una línea \n
electrónica.
:print
El ciclo de bucle comienza si los caracteres principales de una línea son una serie de espacios en blanco seguidos de un \n
carácter de línea de hilo.
:indent
El ciclo comienza en las líneas en blanco, o en las :print
líneas de ciclo que fallan #test
, pero :indent
elimina todas las \n
secuencias iniciales en blanco + ewline de su salida.
- una vez que
:print
comience, continuará tirando de las líneas de entrada, eliminando los espacios en blanco iniciales hasta la cantidad encontrada en la primera línea de su ciclo, traduce los escapes de retroceso de sobretasa y subtrazo en escapes de terminales de color e imprime los resultados hasta que #test
falle.
- antes de que
:indent
comience, primero verifica el h
espacio anterior para ver si hay una posible continuación de sangría (como una Subsección) , y luego continúa introduciendo la entrada siempre que #test
falle y cualquier línea que sigue a la primera continúa coincidiendo [-
. Cuando una línea después de la primera no coincide con ese patrón, se elimina, y posteriormente también lo son todas las líneas siguientes hasta la siguiente línea en blanco.
#match
y #test
unir los dos bucles cerrados.
#test
pasa cuando la serie principal de espacios en blanco es más corta que la serie seguida por la última línea \n
ew en una secuencia de línea.
#match
antepone los ewlines \n
iniciales necesarios para comenzar un :print
ciclo a cualquiera de :indent
las secuencias de salida que conducen con una coincidencia a cualquier arg de línea de comando. Esas secuencias que no se vuelven vacías, y la línea en blanco resultante se devuelve a :indent
.