Это подборка разделов, скопированных с http://zsh.sourceforge.net/Guide/zshguide02.html и размещенных здесь, чтобы я мог легко прочитать их на своем телефоне.

2.5: Что поместить в ваши файлы запуска

2.5.3: Механизм истории: типы истории

Название «механизм истории» относится к тому факту, что zsh хранит «историю» введенных вами команд. Есть три способа получить их обратно; все они используют один и тот же набор командных строк, но механизмы доступа к ним довольно разные. По какой-то причине элементы в списке истории (полная строка ввода, введенная и выполненная одновременно) стали называться «событиями».

Прямое редактирование истории

Во-первых, вы можете использовать редактор; обычно нажатие стрелки вверх переводит вас на предыдущую строку, а стрелка вниз возвращает вас назад. Обычно это самый простой способ, поскольку вы можете точно видеть, что делаете. Гораздо больше я скажу о редакторе в главе 4; первое, что нужно знать, это то, что его основные команды работают либо как emacs, либо как vi, поэтому, если вы знаете одну из них, вы можете сразу же начать редактировать строки. Оболочка пытается угадать, использовать ли emacs или vi из переменных окружения $VISUAL или $EDITOR, именно в таком порядке; они традиционно содержат имя вашего предпочтительного редактора для программ, которым нужно, чтобы вы редактировали текст. В прежние времена $VISUAL был полноэкранным редактором, а $EDITOR — строковым редактором, как и благословенная память ed, но теперь различие очень размыто. Если любой из них содержит строку vi, построчный редактор запустится в режиме vi, иначе он запустится в режиме emacs. Если вы находитесь в неправильном режиме, `bindkey -e' в ~/.zshrc переведет вас в режим emacs, а `bindkey -v' в режим vi. Пользователям vi следует помнить, что вы начинаете в режиме вставки, поэтому нажимайте ESC, чтобы иметь возможность вводить команды vi.

История взрыва

Во-вторых, вы можете использовать механизм `bang-history' в стиле csh (если вы не установили опцию NO_BANG_HIST); 'bang' — это восклицательный знак '!', также известный как 'pling' или 'sriek' (или факториал, но это уже другая история). Таким образом, `!!' извлекает последнюю командную строку и выполняет ее; `!-2' извлекает предпоследний. Вы можете выбирать слова: `!!:1' выбирает первое слово после команды последней команды (если вы обратили внимание выше, вы заметите, что в этом случае вам нужен только один `!'); 0 после двоеточия выбирает само командное слово; `*’ выбирает все аргументы после команды; `$’ выбирает последнее слово. У вас могут быть даже диапазоны: `!!:1–3' выбирает эти три слова, и такие вещи, как `!!:3-$’, тоже работают.

После селектора слов у вас может быть второй набор двоеточий, а затем несколько специальных команд, называемых модификаторами — — их очень полезно запомнить, поскольку их можно применять к параметрам и шаблонам файлов, поэтому вот еще подробности. Модификатор `:t' (хвост) выбирает последнюю часть имени файла, все после последней косой черты; и наоборот, `:h' (голова) выбирает все до этого. Итак, с записью в историю,

% print /usr/bin/cat
  /usr/bin/cat
  % print !!:t
  print cat
  cat

Обратите внимание на две вещи: во-первых, механизм истории взрывов всегда печатает то, что он собирается выполнить. Во-вторых, вам не нужен селектор слов; оболочка может сказать, что `:t' является модификатором, и предполагает, что вы хотите применить его ко всей предыдущей команде. (Здесь будьте осторожны, так как на самом деле :t сократит выражение до всего после последней косой черты в любом слове, что немного неожиданно.)

С параметрами:

% foo=/usr/bin/cat
  % print ${foo:h}
  /usr/bin

(обычно вы можете опустить `{‘ и `}’, но с ними понятнее и безопаснее). И, наконец, с файлами — — это не сработает, если вы установите NO_BARE_GLOB_QUAL для sh-подобного поведения:

% print /usr/bin/cat(:t)
  cat

где вам нужны круглые скобки, чтобы сообщить оболочке, что `:t' не просто часть имени файла.

Полный список см. в руководстве по zshexpn или в разделе Модификаторы в печатной или информационной версиях руководства, но вот еще несколько наиболее полезных. `:r' удаляет суффикс файла, превращая file.c в файл; `:l' и `:u' переводят все слова в нижний регистр или все в верхний регистр; `:s/foo/bar/’ заменяет первое вхождение foo на bar в словах; `:gs/foo/bar’ заменяет все вхождения (г означает глобальный); `:&’ повторяет последнюю такую ​​замену, даже если вы сделали это в предыдущей строке; `:g&’ также работает. Так

% print this is this line
  this is this line
  % !!:s/this/that/
  print that is this line
  that is this line
  % print this is no longer this line
  this is no longer this line
  % !!:g&
  print that is no longer that line
  that is no longer that line

Наконец, есть сокращение: ^old^new^ точно эквивалентно !!:s/old/new/; вы даже можете поставить другой модификатор после него. `^' на самом деле является вторым символом $histchars, упомянутым выше. Вы можете пропустить последний `^', если за ним больше нечего следовать. Кстати, вы можете соединять модификаторы вместе, но каждый из них должен сопровождаться двоеточием: :t:r, применяемый к `dir/file.c’, дает `file’, а повторные применения :h делают пути все короче и короче.

Прежде чем мы покинем историю взрывов, обратите внимание на параметр HIST_VERIFY. Если это установлено, то после подстановки строка снова появляется с изменениями, а не сразу печатается и выполняется. Так как вам просто нужно набрать ‹RET›, чтобы выполнить его, это полезный трюк, чтобы уберечь вас от выполнения неправильного действия, что может легко произойти со сложными строками истории взрывов; У меня у самого такой набор.

И последний совет: расширение и завершение оболочки, о которых я подробно расскажу позже, позволяет вам сразу же расширять ссылки на историю взрывов, нажимая TAB сразу после того, как вы набрали полную ссылку, и вы обычно можете ввести управление вместе с косой чертой (на некоторых клавиатурах вы ограничены ^Xu), чтобы вернуть его в исходное состояние, если вам не нравится результат — — это часть функции «отменить» редактора.

Команды истории в стиле Ksh

Третья форма истории использует встроенную функцию fc. Это самое громоздкое: вы должны указать команде, какие полные строки выполнять, и вам может быть предоставлена ​​возможность сначала отредактировать их (но с помощью внешнего редактора, а не в оболочке). Вы, вероятно, не будете использовать его таким образом, но есть три вещи, которые на самом деле контролируются fc, которые вы могли бы использовать: во-первых, команда `r' повторяет последнюю команду (игнорируя r), что немного похоже на `!! '. Во-вторых, команда под названием «история» также действительно замаскирована. Он дает вам список последних команд. Рядом с ними есть цифры; вы можете использовать их с историей взрыва вместо использования отрицательных чисел для обратного отсчета, как я первоначально объяснил, преимущество в том, что они не меняются при вводе большего количества команд. Вы можете указать диапазоны чисел для истории, первое число для того, где начать перечисление, а второе, где остановиться: конкретный пример — «история 1», в которой перечислены все команды (даже если первая команда, которую он все еще помнит, старше, чем 1; он просто молча опускает все это). Третье использование fc — для чтения и записи вашей истории, чтобы вы могли сохранять ее между сеансами.

2.5.4: Настройка истории

На самом деле, оболочка может читать и записывать историю, не сообщая об этом. Однако вам нужно указать, где сохранить историю, и для этого вы должны установить параметр $HISTFILE на имя файла, который вы хотите использовать (обычно это `~/.history'). Затем вам нужно установить параметр $SAVEHIST на количество строк вашей истории, которые вы хотите сохранить. Когда эти два параметра установлены, оболочка будет считывать строки $HISTSIZE из $HISTFILE в начале интерактивного сеанса и сохранять последние строки $SAVEHIST, которые вы выполнили в конце сеанса. Чтобы он читал или писал посередине, вам нужно либо установить одну из опций, описанных ниже (INC_APPEND_HISTORY и SHARE_HISTORY), либо использовать команду fc: fc -R и fc -W читать и записывать историю соответственно, а fc -A добавляет его к файлу (хотя и обрезает его, если он длиннее $SAVEHIST); fc -WI и fc -AI похожи, но I означает только запись событий с момента последней записи истории.

Существует третий параметр $HISTSIZE, который определяет количество строк, которые оболочка будет хранить в рамках одного сеанса; за исключением особых причин, о которых я не буду говорить, вы должны установить $SAVEHIST не более чем $HISTSIZE, хотя это может быть и меньше. Значение по умолчанию для $HISTSIZE равно 30, что немного скупо на память и дисковое пространство современных компьютеров; Пользователи zsh часто используют число до 1000. Таким образом, простой набор параметров для установки в .zshrc:

HISTSIZE=1000
  SAVEHIST=1000
  HISTFILE=~/.history

и этого достаточно, чтобы все заработало. Обратите внимание, что вы должны установить $SAVEHIST и $HISTFILE для работы автоматического чтения и записи строк истории.

2.5.5: Опции истории

Есть также много вариантов, влияющих на историю; они значительно увеличились с версией 3.1.6, которая впервые предоставила INC_APPEND_HISTORY, SHARE_HISTORY, HIST_EXPIRE_DUPS_FIRST, HIST_IGNORE_ALL_DUPS, HIST_SAVE_NO_DUPS и HIST_NO_FUNCTIONS. Я уже описал BANG_HIST, CSH_JUNKIE_HISTORY и HIST_VERIFY и больше не буду о них рассказывать.

ПРИЛОЖЕНИЕEND_HISTORY, INC_APPEND_HISTORY, SHARE_HISTORY

Обычно, когда он записывает файл истории, zsh просто перезаписывает все, что там есть. APPEND_HISTORY позволяет добавлять новую историю к старой. Оболочка постарается не записывать строки, которые уже должны быть там; это может усложниться, если у вас одновременно запущено много zsh в разных окнах. Этот вариант подходит большинству людей. INC_APPEND_HISTORY означает, что вместо того, чтобы делать это при выходе из оболочки, каждая строка добавляется в историю таким образом, как она выполняется; это означает, например, что если вы запустите zsh в основной оболочке, его история будет похожа на историю основной оболочки, что весьма полезно. Это также означает, что порядок команд из разных оболочек, работающих одновременно, гораздо более логичен — — в основном просто порядок их выполнения — — поэтому для 3.1.6 и выше этот вариант рекомендуется.

SHARE_HISTORY делает еще один шаг вперед: по мере добавления каждой строки файл истории проверяется, чтобы увидеть, не было ли что-либо записано другой оболочкой, и если это так, то это также включается в историю текущей оболочки. Это означает, что zsh, работающий в разных окнах, но на одном хосте (или, в более общем случае, с одним и тем же домашним каталогом), имеет одну и ту же историю. Обратите внимание, что zsh пытается не сбить вас с толку появлением неожиданных записей в истории: если вы используете историю в стиле !, команды из другого сеанса не отображаются в списке истории до тех пор, пока вы явно не введете команду history для их отображения, так что вы можете быть уверены, какую команду вы на самом деле выполняете повторно. Оболочка Korn всегда ведет себя так, как если бы параметр SHARE_HISTORY был установлен, по-видимому, потому, что он не сохраняет внутреннюю историю.

РАСШИРЕННАЯ_ИСТОРИЯ

Это усложняет формат записи истории: кроме самой команды, в ней сохраняется время запуска команды и время ее выполнения. Команда history принимает три параметра, которые используют это: history -d печатает время начала команды; history -f печатает это вместе с датой; history -D (которую вы можете комбинировать с -f или -d) печатает прошедшее время команды. Формат даты можно изменить с помощью -E для европейского (день.месяц.год) и -i для международного (год-месяц-день). Основными причинами, по которым вы не хотите устанавливать это значение, может быть нехватка места на диске или то, что вы хотите, чтобы ваш файл истории читался другой оболочкой.

HIST_IGNORE_DUPS, HIST_IGNORE_ALL_DUPS, HIST_EXPIRE_DUPS_FIRST, HIST_SAVE_NO_DUPS, HIST_FIND_NO_DUPS

Эти параметры позволяют справиться с повторяющимися строками, которые часто появляются в истории. Самым простым является HIST_IGNORE_DUPS, который указывает оболочке не сохранять строку истории, если она такая же, как и предыдущая, тем самым сводя множество повторяющихся команд к одной; это очень хороший вариант, чтобы установить. Он ничего не делает, когда повторяющиеся строки не являются смежными, поэтому, например, всегда будут сохраняться чередующиеся пары команд. Здесь могут помочь следующие два параметра: HIST_IGNORE_ALL_DUPS просто удаляет копии строк, все еще находящихся в списке истории, сохраняя только что добавленную, в то время как HIST_EXPIRE_DUPS_FIRST более тонкий: он предпочтительно удаляет дубликаты, когда история заполняется, но ничего не делает до этого момента. HIST_SAVE_NO_DUPS означает, что какие бы опции ни были установлены для текущего сеанса, оболочка не должна сохранять повторяющиеся строки более одного раза; а HIST_FIND_NO_DUPS означает, что даже если повторяющиеся строки были сохранены, поиск в обратном направлении с помощью команд редактора не показывает их более одного раза.

HIST_ALLOW_CLOBBER, HIST_REDUCE_BLANKS

Это позволяет механизму истории вносить изменения в строки по мере их ввода. Первый влияет на перенаправление вывода, когда вы используете символ › для перенаправления вывода команды или набора команд в именованный файл или используете ›› для добавления вывода в этот файл. Если у вас установлен параметр NO_CLOBBER, то

touch newfile
  echo hello >newfile

терпит неудачу, потому что команда `touch' создала новый файл, и NO_CLOBBER не позволит вам перезаписать (затереть) его в следующей строке. С HIST_ALLOW_CLOBBER вторая строка появляется в истории как

echo hello >|newfile

где ›| переопределяет NO_CLOBBER. Таким образом, чтобы обойти NO_CLOBBER, вы можете просто вернуться к предыдущей строке и выполнить ее, не редактируя.

Второй вариант, HIST_REDUCE_BLANKS, подчистит строку при ее вводе в историю, удалив все лишние пробелы, ничего не значащие для оболочки. Это также может означать, что строка становится дубликатом предыдущей, даже если она не была бы в нечистом виде. Достаточно мудро не удалять пробелы, которые важны, т.е. цитируются.

HIST_IGNORE_SPACE, HIST_NO_STORE, HIST_NO_FUNCTIONS

Эти три варианта позволяют сказать, что определенные строки вообще не должны попасть в историю. HIST_IGNORE_SPACE означает, что строки, начинающиеся с пробела, не попадают в историю; идея состоит в том, что вы намеренно вводите пробел, который в остальном не имеет значения для оболочки, перед вводом любой строки, которую вы хотите сразу после этого забыть. В zsh 4.0.1 это реализовано так, что вы всегда можете вызвать для редактирования непосредственно предшествующую строку, даже если в ней есть пробел; но когда следующая строка выполняется и заносится в историю, строка, начинающаяся с пробела, забывается.

HIST_NO_STORE указывает оболочке не сохранять историю или команды fc. в то время как HIST_NO_FUNCTIONS говорит ему не хранить определения функций, поскольку они, хотя обычно и нечастые, могут быть утомительно длинными. Определение функции — это все, что начинается с `function funcname {...' или `funcname() {...'.

NO_HIST_BEEP

Наконец, в редакторе используется HIST_BEEP: если вы попытаетесь прокрутить вверх или вниз за пределы списка истории, оболочка издаст звуковой сигнал. Он включен по умолчанию, поэтому используйте NO_HIST_BEEP, чтобы отключить его.

2.5.7: Именованные каталоги

Как уже упоминалось, `~/' в начале имени файла расширяется до вашего домашнего каталога. В более общем смысле, `~user/' позволяет вам обращаться к домашнему каталогу любого другого пользователя. Кроме того, zsh позволяет вам определять свои собственные именованные каталоги, использующие этот синтаксис. Основная идея проста, так как любой параметр может быть именованным каталогом:

dir=/tmp/mydir
  print ~dir

печатает `/tmp/mydir’. Пока что это ничем не отличается от использования параметра как $dir. Разница возникает, если вы используете конструкцию `%~', описанную выше, в приглашении. Затем, когда вы перейдете в этот каталог, вместо сообщения `/tmp/mydir' вы увидите аббревиатуру `~dir'.

Оболочка не зарегистрирует имя каталога до тех пор, пока вы сами не заставите его сделать это с помощью `~dir' хотя бы один раз. Вы можете сделать следующее в своем .zshrc:

dir=/tmp/mydir
  bin=~/myprogs/bin
  : ~dir ~bin

где `:' — это команда, которая ничего не делает — — но ее аргументы проверяются на параметры и т. д. обычным способом, так что оболочка может поместить dir и bin в свой список именованных каталогов. Более простой способ сделать это — установить параметр AUTO_NAME_DIRS; тогда любой созданный параметр, который ссылается на каталог, будет автоматически преобразован в имя. Каталог должен иметь абсолютный путь, т. е. его развернутое значение, после превращения любых `~' в начале в полные пути, должно начинаться с `/'. Параметр $PWD, показывающий текущий каталог, защищен от превращения в ~PWD, так как это ничего вам не скажет.

2.5.8: Варианты «Быстрее» для опытных пользователей

Вот еще несколько случайных параметров, которые вы, возможно, захотите установить в своем .zshrc.

NO_BEEP

Обычно zsh издает звуковой сигнал, если ему что-то не нравится. Это может очень раздражать; setopt nobeep отключит его. Я неофициально называю это вариантом OPEN_PLAN_OFFICE_NO_VIGILANTE_ATTACKS.

AUTO_CD

Если этот параметр установлен, и вы вводите что-то без аргументов, не являющееся командой, zsh проверит, действительно ли это каталог. Если это так, оболочка перейдет в этот каталог. Таким образом, `./bin' сам по себе эквивалентен `cd ./bin', если каталог `./bin' действительно существует. Это особенно полезно в форме `..', которая переходит в родительский каталог.

CD_ABLE_VARS

Это еще один способ сэкономить ввод при смене директории, правда, только на один символ. Если каталог не существует, когда вы пытаетесь перейти в него, zsh попытается найти параметр с таким именем и использовать его вместо этого. Вы также можете иметь `/' и другие биты после параметра. Таким образом, `cd foo/dir', если нет каталога `foo', но есть параметр $foo, становится эквивалентным `cd $foo/dir'.

EXTENDED_GLOB

Шаблоны, чтобы соответствовать именам файлов и прочему, могут быть очень сложными в zsh, но чтобы получить от них максимальную отдачу, вам нужно использовать эту опцию, так как в противном случае некоторые функции не включаются, так что люди привыкли к более простым шаблонам ( может просто `*', `?' и `[…]') не смущаются странными событиями. Я расскажу гораздо больше о функциях шаблонов zsh, но это для того, чтобы напомнить вам, что вам нужна эта опция, если вы делаете что-то умное с `~', `#', `^' или подстановочными флагами — — а также для того, чтобы напомнить вы, что эти символы могут иметь странные эффекты, если у вас установлена ​​​​опция.

НЕСКОЛЬКО

Выше я упомянул, что для того, чтобы заставить zsh вести себя как ksh, вам нужно было установить NO_MULTIOS, но я не сказал, что делает опция MULTIOS. Он имеет два разных эффекта для вывода и ввода.

Во-первых, для вывода. Вот это альтернатива тройной программе. Я упоминал однажды, но не описывал подробно, что вы можете использовать ›filename, чтобы указать оболочке отправлять вывод в файл с заданным именем, а не на терминал. С установленным MULTIOS вы можете иметь более одного из этих перенаправлений в командной строке:

echo foo >file1 >file2

Здесь `foo' будет записано в оба именованных файла; zsh копирует вывод. Механизм пайпа, который я лучше опишу в главе 3, представляет собой своего рода перенаправление в другую программу, а не в файл: MULTIOS влияет и на это:

echo foo >file1 | sed 's/foo/bar/'

Здесь `foo' снова записывается в файл1, но также отправляется в канал программе sed ("потоковый редактор"), которая подставляет `foo' в `bar' и (поскольку в этой части нет перенаправления вывода) печатает его к терминалу.

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

some_command 2>&1 >/dev/null | sed 's/foo/bar/'

Предположительно, намерение состоит в том, чтобы отправить стандартную ошибку на стандартный вывод (`2›&1', очень часто используемый иероглиф оболочки), а не отправлять стандартный вывод куда-либо (`›/dev/null'). (Если вы не встречались с концепцией «стандартной ошибки», это просто еще один выходной канал, который идет туда же, куда и обычный вывод, если только вы его не перенаправляете; он используется, например, для отправки сообщений об ошибках на терминал, даже если ваш вывод идет куда-то еще.) В этом примере функция MULTIOS также заставляет исходный стандартный вывод идти в конвейер. Вы можете увидеть, как это происходит, если мы добавим версию `some_command':

{ echo foo error >&2; echo foo not error;  } 2>&1 >/dev/null |
  sed 's/foo/bar/'

где вы можете рассматривать материал внутри `{…}' как черный ящик, который отправляет сообщение `foo error' в стандартную ошибку и `foo not error' в стандартный вывод. Однако с MULTIOS результат

error bar
  not error bar

потому что оба были отправлены в трубу. Без МУЛЬТИОС вы получите ожидаемый результат,

error bar

как и любая другая оболочка в стиле Борна. Там

При вводе MULTIOS организует чтение последовательности файлов по порядку. На этот раз это немного похоже на использование программы cat, которая объединяет все файлы, перечисленные после нее. Другими словами,

cat file1 file2 | myprog

(где myprog — некоторая программа, считывающая все присланные ей на вход файлы) можно заменить на

myprog <file1 <file2

который делает то же самое. Еще раз, канал считается перенаправлением, и канал читается сначала, до любых файлов, перечисленных после `‹’:

echo then this >testfile
  echo this first | cat <testfile

ПРАВИЛЬНО, ПРАВИЛЬНО_ВСЕ

Если у вас установлено ПРАВИЛЬНО, оболочка будет проверять все вводимые вами команды, и если они не существуют, но есть команда с похожим именем, она спросит вас, имели ли вы в виду именно ее. Вы можете ввести «n» для «нет», не исправлять, просто продолжайте; 'y' для да, исправьте это, затем продолжайте; 'a' для прерывания, ничего не делайте; `e' для редактирования, вернитесь в редактор, чтобы снова отредактировать ту же строку. Пользователи новой системы завершения должны учитывать, что это не то же самое исправление, которое вы получаете там: это просто исправление команд.

CORRECT_ALL применяется ко всем словам в строке. Это немного менее полезно, потому что в настоящее время оболочка должна предполагать, что они должны быть именами файлов, и пытаться исправить их, если они не существуют как таковые, но, конечно, многие аргументы команды не являются именами файлов. Если определенные команды генерируют слишком много попыток исправить свои аргументы, вы можете отключить это, поставив `nocorrect' перед именем команды. Псевдоним — очень хороший способ сделать это, как описано далее.

2.5.10: Переменные среды

Часто руководство к программе говорит вам определить определенные переменные среды, обычно это набор заглавных букв с возможными цифрами и нечетным символом подчеркивания. Они могут передавать информацию в программу без необходимости использования дополнительных аргументов. В zsh переменные среды отображаются как обычные параметры оболочки, хотя они должны быть определены немного по-другому: строго говоря, среда — это особая область за пределами оболочки, и zsh нужно указать поместить туда копию, а также сохранить одну из своих своя. Обычный синтаксис

export VARNAME='value'

другими словами, как обычное присваивание, но с «экспортом» впереди. Обратите внимание, что перед именем переменной окружения нет символа `$'; все «экспорт» и подобные операторы работают одинаково. Проще всего поместить их в .zshenv — отсюда и название. Переменные среды будут передаваться любым программам, запускаемым из оболочки, поэтому может быть достаточно определить их в .zlogin или .zprofile: однако любая оболочка, запущенная для вас неинтерактивно, не будет запускать их, и есть другие возможные проблемы. если вы используете оконную систему, которая запускается оболочкой, отличной от zsh, или которая вообще не запускает файл запуска оболочки — — мне пришлось настроить мою, чтобы она работала так. Так что .zshenv - самое безопасное место; определение переменных окружения не занимает много времени. Другие люди, без сомнения, дадут вам совершенно противоположные взгляды, но это люди для вас.

Обратите внимание, что вы не можете экспортировать массивы. Если экспортировать параметр, а затем присвоить ему массив, в окружении ничего не появится; вы можете использовать внешнюю команду «printenv VARNAME» (опять же без «$», потому что команде нужно знать имя, а не значение) для проверки. С массивами есть и более тонкая проблема. Встроенная функция экспорта является частным случаем встроенной функции typeset, которая определяет переменную, не помечая ее для экспорта в среду. Вы можете подумать, что можете сделать

typeset array=(this doesn\'t work)

но вы не можете — — специальный синтаксис массива понимается только тогда, когда присваивание не следует за командой, а не в обычных аргументах, как в данном случае, поэтому вам нужно поместить присваивание массива на следующую строку. Это очень легко сделать ошибку. Дополнительные варианты использования typeset будут описаны в главе 3; они включают в себя создание локальных параметров в функциях и определение специальных атрибутов (одним из которых является атрибут export) для параметров.

2.5.11: Путь

Это помогает иметь возможность находить внешние программы, то есть все, что не является частью оболочки, любую команду, кроме встроенной, функции или псевдонима. Для этого используется массив $path. На самом деле системе нужна переменная окружения $PATH, которая содержит список каталогов, в которых нужно искать программы, разделенных двоеточием. Эти каталоги являются отдельными компонентами массива $path. Итак, если $path содержит

path=(/bin /usr/bin /usr/local/bin .)

тогда $PATH автоматически будет содержать эффект

PATH=/bin:/usr/bin:/usr/local/bin:.

без необходимости устанавливать это. Идея просто в том, что, хотя системе нужен $PATH, потому что она не понимает массивы, гораздо более гибко использовать массивы в оболочке и, следовательно, практически забыть о форме $PATH.

Изменения пути аналогичны описанным выше изменениям переменных среды, так что все применимо. Однако есть небольшие трудности с установкой $path в .zshenv, даже несмотря на то, что причины, приведенные выше для этого, по-прежнему применимы. Обычно путь будет установлен для вас либо системой, либо системным администратором в одном из глобальных файлов запуска, и если вы измените путь, вы просто захотите его добавить. Но если ваш .zshenv содержит

path=(~/bin ~/progs/bin $path)

— — это правильный способ добавить что-то в начало $path — — тогда каждый раз, когда вызывается .zshenv, ~/bin и ~/progs/bin застревают впереди, поэтому, если вы запустите еще один zsh, у вас будет два устанавливает там.

Конечно, вы можете добавить тесты, чтобы увидеть, есть ли уже что-то. Zsh удобно позволяет проверять наличие элементов в массиве. Предваряя индекс массива (r) (для обратного), он попытается найти соответствующий элемент и вернуть его, иначе пустую строку. Вот как это сделать (но пока не добавляйте это, см. следующий абзац):

for dir in ~/bin ~/progs/bin; do
    if [[ -z ${path[(r)$dir]} ]]; then
      path=($dir $path)
    fi 
  done

Это для… сделать… сделано – это еще одна специальная конструкция оболочки. Он берет каждую вещь после `in' и присваивает ее, в свою очередь, параметру, названному перед `in' -- -- $dir, но поскольку это форма присвоения, `$' опускается -- -- так что в первый раз это имеет эффект dir=~/bin, а в следующий раз dir=~/progs/bin. Затем он выполняет то, что находится в цикле. Тест -z проверяет, что следующее пусто: в этом случае это будет, если каталог $dir еще не находится в $path, поэтому он идет дальше и добавляет его впереди. Обратите внимание, что каталоги добавляются в порядке, обратном порядку их появления.

Однако на самом деле zsh снимает с вас все эти проблемы. Заклинание `typeset -U path', где -U означает уникальный, говорит оболочке, что она не должна ничего добавлять в $path, если он там уже есть. Если быть точным, он сохраняет только самое левое вхождение, поэтому, если вы добавили что-то в конце, оно исчезнет, ​​а если вы добавили что-то в начале, старое исчезнет. Таким образом, в .zshenv прекрасно работает следующее:

typeset -U path
  path=(~/bin ~/progs/bin $path)

и вы можете записать это «для» как урок программирования оболочки. Вы можете перечислить все переменные, для которых включена уникальность, набрав `typeset +U' с `+' вместо `-', потому что в последнем случае оболочка также покажет значения параметров, а это не так. что вам нужно здесь. Флаг -U также будет работать с массивами, разделенными двоеточиями, такими как $PATH.

2.5.12: Почта

Zsh проверит наличие новой почты для вас. Если все, что вам нужно, это время от времени получать напоминания о том, что что-то приходит в вашу обычную папку, вам просто нужно установить параметр $MAIL в любое место: обычно это один из /usr/spool/mail, /var/spool/ почту или /var/mail.

Массив $mailpath предоставляет больше возможностей. Как и $path, у него есть коллега в верхнем регистре, $MAILPATH, который представляет собой массив, разделенный двоеточием. На этот раз системе это не нужно, так что в основном это для того, чтобы вы могли экспортировать его в другую версию zsh; экспорт массивов не будет работать. Как теперь может быть до боли ясно, если вы установили .zshenv или .zshrc, вам не нужно их экспортировать, потому что они устанавливаются в каждом экземпляре оболочки. Элементы $mailpath работают так же, как $MAIL, поэтому вы можете указать разные места, куда приходит почта. Это наиболее полезно, если у вас есть программа, такая как filter или procmail, для перераспределения поступающей почты по разным папкам. Вы можете указать разные сообщения для каждой папки, поставив в конце `?message’. Например, мой выглядит так.

mailpref=/temp/pws/Mail
  mailpath=($mailpref/newmail
            $mailpref/zsh-new'?New zsh mail' 
            $mailpref/list-new'?New list mail'
            $mailpref/urth-new'?New Urth mail')

Обратите внимание, что zsh знает, что массив не закончен до `)', даже если элементы находятся на разных строках; это одна из очень веских причин для установки $mailpath, а не $MAILPATH, для которого нужен один длинный фрагмент.

Другим интересным параметром является $MAILCHECK, который указывает частоту в секундах, когда zsh должен проверять наличие новой почты. Значение по умолчанию — 60. На самом деле zsh проверяет только после того, как команда завершила выполнение и собирается напечатать приглашение. Поскольку проверка файлов не занимает много времени, обычно вы можете установить минимальное значение, которое равно MAILCHECK=1; ноль не работает, потому что отключает проверку. Одной из причин, по которой вы не захотите этого делать, может быть то, что $MAIL и $mailpath могут содержать каталоги вместо обычных файлов; они будут рекурсивно проверяться на наличие файлов с чем-то новым, поэтому это может быть медленным.

Наконец, есть еще одна связанная опция, MAIL_WARNING (хотя MAIL_WARN также принимается для того же самого из соображений совместимости с менее грамматическими оболочками). Оболочка запоминает, когда почтовый файл был проверен; в следующий раз, когда он проверяет, он сравнивает дату. Если новой почты нет, а дата файла все равно изменилась, выведет предупреждающее сообщение. Это произойдет, если вы прочитаете почту с помощью программы для чтения почты и поместите сообщения в другое место. Вероятно, вы знаете, что сделали это, поэтому предупреждение может быть не таким уж полезным.

2.5.13: Другие подобные пути вещи

Есть и другие пары, такие как $path и $PATH. Я воздержусь от разговора о $cdpath, пока не расскажу больше о том, как zsh обрабатывает каталоги. Когда я упомянул $fpath, я не сказал, что есть $FPATH, но он есть. Затем есть $manpath и $MANPATH; они вообще не используются оболочкой, но $MANPATH, если он экспортируется, используется внешней командой man, а $manpath предоставляет более простой способ его установки.

Начиная с версии 3.1.6 есть механизм для определения ваших собственных таких комбинаций; если бы это было доступно раньше, не было бы необходимости встраивать $manpath и $MANPATH. В .зшенв ты бы поставил,

export -TU TEXINPUTS texinputs

определить такую ​​пару. Ключом к этому является -T (для галстука); Я использовал `export', хотя основной командой объявления переменных является `typeset', потому что вы почти всегда хотите получить версию, разделенную двоеточием (здесь $TEXINPUTS), видимую для среды, и я установил -U, как описано выше. для $path, потому что в любом случае это удобная функция. Теперь вы можете присвоить массиву $texinputs и позволить программе (TeX или его производным) увидеть $TEXINPUTS. Еще одна полезная для этого переменная — $LD_LIBRARY_PATH, которая в большинстве современных версий UNIX (и Linux) сообщает системе, где найти библиотеки, предоставляющие дополнительные функции при запуске программы.

2.5.14: Особенности версии

Поскольку zsh меняется быстрее, чем почти любой другой известный человечеству интерпретатор команд, вам часто будет необходимо узнать, какую версию вы используете. Это может стать немного многословным; действительно, параметр, который вам нужно проверить, теперь $ZSH_VERSION, до версии 3.0 назывался просто $VERSION. Если вы не используете устаревшее программное обеспечение такого типа, вы, вероятно, можете обойтись такими тестами:

if [[ $ZSH_VERSION == 3.1.<5->* ||
        $ZSH_VERSION == 3.<2->* ||
        $ZSH_VERSION == <4->* ]]; then
    # set feature which appeared first in 3.1.5
  fi

Это похоже на то, чтобы быть уверенным в будущем: там сказано, что если это выпуск 3.1, он должен быть как минимум 3.1.5, но любой выпуск 3.2 (их не было) или любой выпуск 4 или более поздние также будут в порядке. . «‹5-›» и т. д. — это расширенные тесты на сопоставление с образцом: сопоставление с образцом использует те же символы, что и подстановка, но для проверки других вещей, вот то, что слева от «==». Это соответствует любому числу, которое равно как минимум 5, например 6, 10 или 252, но не 1 или 4. Существуют также версии для разработки; в настоящее время номера версий выглядят как X.Y.Z-tag-N (tag — какое-то короткое слово, остальные — числа), но если вы не следите за развитием, вам не нужно их искать, так как они официально не выпущены. Это `==' в тесте также может быть просто `=', но в руководстве сказано, что первое предпочтительнее, поэтому я использовал их здесь, хотя обычно люди не беспокоятся.

Версия 4 zsh предоставляет функцию, которая, по крайней мере, сделает это за вас: она просматривает только числа X, Y и Z. (и N, если он существует), игнорируя все буквы и знаки препинания. Вы даете ему минимальную версию оболочки, которая вам нужна, и она возвращает true, если текущая оболочка достаточно новая. Например, `is-at-least 3.1.6-pws-9' вернет true, если текущая версия zsh — 3.1.6-dev-20 (или 3.1.9, или 4.0.1, и т. д.), что является правильным поведением. Как и в случае с любой другой функцией оболочки, вы должны организовать автозагрузку is-at крайней мере, если хотите ее использовать.

2.5.15: Все остальное

В файлах запуска есть много других возможностей; в частности, я не коснулся определения вещей для построчного редактора и настройки завершения. Для них нужно многое объяснить, поэтому я вернусь к ним в соответствующих главах. Вам просто нужно помнить, что все это должно быть в .zshrc, так как он нужен для всех интерактивных оболочек и ни для каких других.