Intereting Posts
Как настроить простой Debian 7 как шлюз? Выполните условие IF из результата, который мы получаем с удаленного сервера Почему большинство менеджеров пакетов distros не разрешают один и тот же пакет в нескольких версиях и новейших версиях без обновления? Как освободить пространство в динамически растущем изображении qcow2 VM? Запустить команду при запуске для одного пользователя Есть ли таблица Syscall так же, как таблица прерываний? Каков максимальный разрешенный размер файла (и папки) с помощью eCryptfs? Когда применяется правило отказа NGINX? Augeas не читает все файлы yum.repos.d. Зачем? установить модуль python для конкретного экземпляра python Как написать сценарии LSB init.d, которые могут запускать несколько экземпляров одной и той же службы? Попытка установить Windows на систему с установленным Ubuntu 12.04 От 192.168.0.146 icmp_seq = 1 Destination Host Unreachable Как скрыть меню Gnome / Xfce / GTK приложения по умолчанию? Как заставить LibreOffice работать на Ubuntu 11.10?

Почему оболочки не имеют правильных страниц?

Все встроенные оболочки имеют одну и ту же страницу руководства:

BUILTIN(1) BSD General Commands Manual BUILTIN(1) NAME builtin, ! 

и т.п.

Затем есть небольшой текст, описывающий, какие оболочки встроены, а затем список, который выглядит примерно так:

  Command External csh(1) sh(1) ! No No Yes % No Yes No 

Но если мы делаем man grep мы получаем разделы, такие как

  • ошибки
  • история
  • Смотрите также
  • стандарты
  • Описание

и т.п.

Не имеют ли встроенные оболочки оболочки своя история, описание и аргументы типа -A или -r ? Почему это не указано на страницах руководства и как я научусь использовать их правильно и эффективно?

Потому что встроенные компоненты являются частью оболочки. Любые ошибки или история, которые у них есть, – это ошибки и история самой оболочки. Они не являются независимыми командами и не существуют вне оболочки, в которую они встроены.

Эквивалент, по крайней мере для bash , – это команда help . Например:

 $ help while while: while COMMANDS; do COMMANDS; done Execute commands as long as a test succeeds. Expand and execute COMMANDS as long as the final command in the `while' COMMANDS has an exit status of zero. Exit Status: Returns the status of the last command executed. 

У всех разработчиков bash есть страницы help . Даже help себе:

 $ help help help: help [-dms] [pattern ...] Display information about builtin commands. Displays brief summaries of builtin commands. If PATTERN is specified, gives detailed help on all commands matching PATTERN, otherwise the list of help topics is printed. Options: -d output short description for each topic -m display usage in pseudo-manpage format -s output only a short usage synopsis for each topic matching PATTERN Arguments: PATTERN Pattern specifiying a help topic Exit Status: Returns success unless PATTERN is not found or an invalid option is given. 

Вдохновленный сценарием @ mikeserv's, вот небольшая функция, которая будет печатать соответствующий раздел справочной страницы с использованием Perl. Добавьте эту строку в файл инициализации вашей оболочки ( ~/.bashrc для bash):

 manperl(){ man "$1" | perl -00ne "print if /^\s*$2\b/"; } 

Затем вы запустите его, указав ему справочную страницу и название раздела:

 $ manperl bash while while list-1; do list-2; done until list-1; do list-2; done The while command continuously executes the list list-2 as long as the last command in the list list-1 returns an exit status of zero. The until command is identical to the while command, except that the test is negated; list-2 is exe‐ cuted as long as the last command in list-1 returns a non-zero exit status. The exit status of the while and until commands is the exit status of the last command executed in list-2, or zero if none was executed. $ manperl grep SYNOPSIS SYNOPSIS grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...] $ manperl rsync "-r" -r, --recursive This tells rsync to copy directories recursively. See also --dirs (-d). 

Хотя верно, что некоторые встроенные оболочки оболочки могут иметь небольшое представление в полном руководстве, особенно для тех встроенных в bash специфических встроенных функций, которые вы можете использовать только в системе GNU (люди GNU, как правило, не верят в man и предпочитают свои собственные info страницы) – подавляющее большинство утилит POSIX – встроенные оболочки или другие – очень хорошо представлены в Руководстве программиста POSIX.

Вот выдержка из нижней части моего man sh (что, вероятно, 20 страниц или около того …)

введите описание изображения здесь

Все они есть, а другие не упомянуты, такие как set , read , break … ну, мне не нужно их всех называть. Но обратите внимание на (1P) в правом нижнем углу – это обозначает ручную серию POSIX категории 1 – это те страницы man я говорю.

Может быть, вам просто нужно установить пакет? Это выглядит многообещающим для системы Debian. Хотя help полезна, если вы ее можете найти, вы должны обязательно получить эту серию POSIX Programmer's Guide . Это может быть очень полезно. И составные страницы очень детализированы.

В стороне, встроенные оболочки почти всегда перечислены в конкретном разделе руководства конкретной оболочки. Например, zsh имеет целую отдельную страницу для этого – (я думаю, что она насчитывает 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 

… который довольно близок к тому, что я делал при поиске на странице оболочки. Но help в большинстве случаев хороша в bash .

Я на самом деле работал над sed скриптом, чтобы обрабатывать подобные вещи в последнее время. Вот как я захватил раздел на картинке выше. Это еще дольше, чем мне нравится, но оно улучшается – и может быть очень удобно. В своей текущей итерации он довольно надежно извлекает контекстно-зависимый раздел текста в соответствии с заголовком раздела или подраздела на основе шаблона [a], указанного в командной строке. Он раскрашивает свой вывод и печатает на stdout.

Он работает, оценивая уровни отступов. Непустые строки ввода обычно игнорируются, но когда он встречает пустую строку, он начинает обращать внимание. Он собирает строки оттуда, пока не проверит, что текущая последовательность определенно отступает дальше, чем первая строка перед другой пустой строкой, или же она отбрасывает поток и ждет следующего пустого. Если тест прошел успешно, он пытается сопоставить ведущую строку с аргументами командной строки.

Это означает, что шаблон соответствия будет соответствовать:

 heading match ... ... ... text... 

..а также..

 match text 

..но нет..

 heading match match notmatch 

..или..

  text match match text more text 

Если матч может быть получен, он начнет печать. Он будет вырезать ведущие пробелы совпадающей строки со всех строк, которые он печатает, – поэтому независимо от уровня отступов он обнаружил, что строка на нем печатает его, как если бы он был наверху. Он будет продолжать печатать до тех пор, пока он не встретит другую строку на уровне равного или меньшего, чем уровень отступа, чем соответствующая строка – так что целые секции захватываются только совпадением заголовков, включая любые / все подразделы, абзацы, которые они могут содержать.

Поэтому в основном, если вы попросите, чтобы он соответствовал шаблону, он будет делать это только против какого-либо предметного заголовка и будет окрашивать и печатать весь текст, который он находит в разделе, возглавляемом его совпадением. Ничего не сохраняется, поскольку это делает это, кроме отступа первой строки, – и поэтому он может быть очень быстрым и обрабатывать \n ewline разделенный вход практически любого размера.

Мне потребовалось некоторое время, чтобы выяснить, как рекурсировать в подзаголовки, например:

 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 символьные символы никогда не встречаются в пространстве ввода. Они могут быть получены только в результате редактирования.
  • :print и :indent являются взаимно зависимыми замкнутыми контурами и являются единственным способом получения \n ewline.
    • :print цикл цикла :print начинается, если ведущие символы в строке представляют собой серию пробелов, за которыми следует символ \n ewline.
    • :indent цикл :indent начинается с пустых строк – или на :print линиях цикла :print которые не #test но :indent удаляет из своего вывода все ведущие строки + \n ewline.
    • один раз :print начинается, он будет продолжать тянуть входные строки, стирать ведущие пробелы до суммы, найденной в первой строке в своем цикле, переводить чрезмерные и неуемные обратные экраны в экранирующие экраны цветовых терминалов и печатать результаты до #test пор, пока #test не сработает.
    • before :indent начинает сначала проверяет h старое пространство для любого возможного продолжения отступа (например, Подразделение) , а затем продолжает втягивать входные данные, пока #test терпит неудачу, и любая строка, следующая за первым, продолжает соответствовать [- . Когда строка после первого не совпадает с этим шаблоном, она удаляется – и, следовательно, все последующие строки до следующей пустой строки.
  • #match и #test соединяют два замкнутых #test .
    • #test проходит, когда ведущая серия пробелов короче, чем серия, за которой следует последняя \n строка в последовательности строк.
    • #match ведущие \n строки, необходимые для начала цикла :print любой из последовательностей вывода :indent которые приводят к совпадению с любым аргументом командной строки. Те последовательности, которые не являются пустыми, – и получающаяся пустая строка возвращается обратно :indent .

Каждая оболочка имеет свой собственный набор встроенных функций. Хотя существуют общие черты, каждый из них имеет свои особенности, которые необходимо документировать.

В таких системах, как Linux и FreeBSD (и OSX, которые наследуются от FreeBSD), где каждая оболочка предоставляется в виде отдельного пакета, нет man-страницы для встроенных функций; вместо этого каждый встроенный документ задокументирован в man-странице оболочки. Так что прочитайте страницу bash man для документации по установке kill bash, прочитайте страницу dash man для документации по установке kill dash и т. Д. Также есть справочная страница для автономной утилиты kill .

См. Могу ли я получить отдельные справочные страницы для встроенных команд bash? для man функции, которая показывает внутреннюю документацию bash вместо man-страницы, если аргумент является именем встроенного.

Существуют версии unix, которые предоставляют справочные страницы для встроенных оболочек – на самом деле, большинство коммерческих вариантов. Это возможно, потому что система поставляется либо с одной оболочкой, либо с набором известных оболочек. На странице руководства обсуждаются различия между оболочками. Например, fg(1) страница fg(1) на Solaris 10 имеет разделы для sh , ksh и csh . Страница fg(1) на AIX 7.1 ссылается на «оболочку Korn» и «оболочку POSIX», но обсуждает их вместе (они поддерживают точно такие же функции для fg ). Страница man fg(1) на Tru64 5.0 обсуждает ksh builtin и ссылается на пользователей csh(1) страницу man csh(1) . По- видимому, SCO поставляется с одной оболочкой. Вы можете установить другие оболочки как дополнительные пакеты в этих операционных системах; если вы используете пользовательскую оболочку, вы должны помнить, что страницы руководства для встроенных функций не будут иметь значения при использовании оболочки, отличной от настроек по умолчанию.