Хотя это правда, что некоторые встроенные оболочки могут иметь скудное отображение в полном руководстве - особенно для тех bash
специфических встроенных функций, которые вы, скорее всего, будете использовать только в системе GNU (люди GNU, как правило, не верят man
и предпочитают свои собственные info
страницы) - подавляющее большинство утилит POSIX - встроенных в оболочку или других - очень хорошо представлены в Руководстве программиста POSIX.
Вот отрывок из нижней части моего man sh
(который, вероятно, 20 страниц или около того ...)
Все те , есть и другие , не упомянутые , такие как set
, read
, break
... ну, мне не нужно , чтобы назвать их всех. Но обратите внимание (1P)
на нижний правый угол - он обозначает серию руководств по POSIX категории 1 - это man
страницы, о которых я говорю.
Может быть, вам просто нужно установить пакет? Это выглядит многообещающе для системы Debian. Хотя help
это полезно, если вы можете найти его, вы обязательно должны получить эту POSIX Programmer's Guide
серию. Это может быть чрезвычайно полезно. И это составляющие страницы очень подробны.
Кроме того, встроенные функции оболочки почти всегда перечислены в определенном разделе руководства по конкретной оболочке. zsh
например, для этого есть целая отдельная man
страница - (я думаю, что она насчитывает около 8 или 9 отдельных zsh
страниц, в том числе zshall
огромных).
Вы можете просто grep
man
конечно:
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
... что довольно близко к тому, что я делал при поиске на man
странице оболочки . Но в большинстве случаев help
это довольно хорошо bash
.
Я на самом деле работал над sed
сценарием, чтобы справиться с такими вещами в последнее время. Вот как я схватил раздел на картинке выше. Это все еще дольше, чем мне нравится, но оно улучшается - и может быть довольно удобным. В своей текущей итерации он довольно надежно извлекает контекстно-зависимый раздел текста в соответствии с заголовком раздела или подраздела на основе [a] pattern [s], заданного им в командной строке. Он окрашивает свой вывод и печатает на стандартный вывод.
Это работает, оценивая уровни отступа. Непустые строки ввода обычно игнорируются, но когда он встречает пустую строку, он начинает обращать внимание. Он собирает строки оттуда до тех пор, пока не проверит, что текущая последовательность определенно отступает дальше, чем ее первая строка, прежде чем появится другая пустая строка, или же он отбрасывает поток и ждет следующего пробела. Если тест пройден успешно, он пытается сопоставить ведущую строку со своими аргументами командной строки.
Это означает , что матч шаблон будет соответствовать:
heading
match ...
...
...
text...
..а также..
match
text
..но нет..
heading
match
match
notmatch
..или..
text
match
match
text
more text
Если совпадение может быть выполнено, оно начинает печатать. Он уберет начальные пробелы совпавшей линии со всех строк, которые он печатает, поэтому независимо от уровня отступа, он обнаружит, что линия на нем печатает его так, как если бы он был сверху. Он будет продолжать печатать до тех пор, пока не встретит другую строку на уровне отступа, равном или меньшем, чем у соответствующей строки - поэтому целые разделы будут взяты только с совпадением заголовка, включая любые / все подразделы, абзацы, которые они могут содержать.
Таким образом, в основном, если вы попросите его сопоставить с шаблоном, он будет делать это только с каким-либо предметным заголовком и раскрасит и напечатает весь текст, найденный в разделе, возглавляемом его совпадением. Ничего не сохраняется, так как он делает это, кроме отступа первой строки - и поэтому он может быть очень быстрым и обрабатывать \n
ввод, разделенный на электронные строки, практически любого размера.
Мне потребовалось некоторое время, чтобы выяснить, как использовать следующие подзаголовки:
Section Heading
Subsection Heading
Но я разобрался со временем.
Мне все же пришлось переделать все это ради простоты. Хотя раньше у меня было несколько маленьких циклов, которые делали в основном одни и те же вещи немного по-разному, чтобы соответствовать их контексту, меняя способы рекурсии, мне удавалось дублировать большую часть кода. Теперь есть две петли - одна печать и одна проверка отступа. Оба зависят от одного и того же теста - цикл печати запускается при прохождении теста, а цикл отступа вступает во владение, если он не выполняется или начинается с пустой строки.
Весь процесс очень быстрый, потому что большую часть времени он просто /./d
выбирает любую непустую строку и переходит к следующей - даже результат zshall
мгновенного заполнения экрана. Это не изменилось.
Во всяком случае, пока это очень полезно. Например, read
вышеописанное можно сделать так:
mansed bash read
... и он получает весь блок. Он может принимать любые шаблоны или что угодно, или несколько аргументов, хотя первым всегда является man
страница, на которой он должен искать. Вот картина некоторых из его результатов после того, как я сделал:
mansed bash read printf
... оба блока возвращаются целыми. Я часто использую это как:
mansed ksh '[Cc]ommand.*'
... для чего это весьма полезно. Кроме того, получение SYNOPS[ES]
делает это действительно удобным:
Вот если ты хочешь сделать это - я не буду винить тебя, если ты этого не сделаешь.
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
");}
Вкратце, рабочий процесс:
- любая строка, которая не является пустой и не содержит
\n
символа ewline, удаляется из вывода.
\n
символы ewline никогда не появляются в пространстве входных паттернов. Их можно получить только в результате редактирования.
:print
и :indent
оба являются взаимозависимыми замкнутыми циклами и являются единственным способом получить электронную \n
линию.
:print
Цикл цикла начинается, если ведущие символы в строке представляют собой серию пробелов, за которыми \n
следует символ ewline.
:indent
Цикл начинается на пустых строках - или на :print
строках цикла, которые терпят неудачу #test
- но :indent
удаляет все \n
начальные пустые + электронные строки из своего вывода
- как только
:print
он начнется, он продолжит вытягивать входные строки, обрезать начальные пробелы до величины, найденной в первой строке своего цикла, преобразовывать экранирование избыточного удара и обратного удара обратного пробела в побеги цветных терминалов и печатать результаты до тех пор, пока #test
не произойдет сбой.
- перед началом
:indent
он сначала проверяет h
старое пространство на предмет возможного продолжения отступа (такого как подраздел) , а затем продолжает вводить данные до тех пор, пока происходит #test
сбой, и любая строка, следующая за первой, продолжает совпадать [-
. Если строка после первой не совпадает с этим шаблоном, она удаляется - и впоследствии все последующие строки до следующей пустой строки.
#match
и #test
соединить две замкнутые петли.
#test
проходит, когда \n
начальная серия заготовок короче, чем серия, за которой следует последняя электронная линия в последовательности строк.
#match
присоединяет ведущее \n
ewlines необходимого для начала :print
цикла любых из :indent
«s выходных последовательностей , которые приводят спичку в любой командной строке арг. Те последовательности, которые не отображаются пустыми - и полученная пустая строка передается обратно :indent
.