Использование csh и tcsh

Пол Дюбуа

1995

перевод В.Айсин

Предисловие

Оболочка (shell) — это интерпретатор команд. Вы вводите команды в оболочку, и она передаёт их компьютеру для выполнения. В системах UNIX обычно есть несколько вариантов оболочек. В этом руководстве рассматриваются две оболочки: C-оболочка (csh) и расширенная C-оболочка (tcsh).

C-shell (csh) — популярный интерпретатор команд, созданный на основе Berkeley UNIX, — особенно хорошо подходит для интерактивного использования. Он предлагает множество функций, в том числе возможность запоминать и изменять предыдущие команды, создавать ярлыки для команд, сокращённые обозначения для путей к домашним каталогам и управлять заданиями.

tcsh, расширенная версия csh, почти полностью совместима с csh, поэтому всё, что вы знаете о C-shell, можно сразу применить к tcsh. Но tcsh выходит за рамки csh, добавляя такие возможности, как редактор командной строки общего назначения, исправление орфографии и программируемое завершение имён команд, файлов и пользователей.

В вашей системе могут быть доступны оболочки, отличные от csh и tcsh. Двумя наиболее значимыми примерами являются Bourne shell (sh) и Korn shell (ksh). Оболочка Bourne является старейшей из популярных в настоящее время оболочек и является наиболее широко доступной. Оболочка Korn была разработана в AT&T и наиболее распространена в UNIX-системах на базе System V. Обе оболочки полностью задокументированы в другом месте, поэтому мы не будем рассматривать их здесь.

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

В этом руководстве особое внимание уделяется двум моментам:

Целевая аудитория

Это руководство может быть использовано любым человеком, независимо от уровня владения csh или tcsh. Оно будет полезно в следующих случаях:

Область применения данного руководства

Настоящее руководство разделено на три части. Часть I, Изучение основ, предназначена для того, чтобы познакомить вас с основами, предоставив базовое введение в оболочку и широкий обзор, показывающий, как использовать более продвинутые функции оболочки для выполнения множества различных задач.

Часть II, Повышение эффективности, предлагает более актуальный подход к возможностям оболочки. Главы части II посвящены конкретным аспектам оболочки. Эти главы будут полезны, если вам нужна дополнительная информация о функциях оболочки, которые описаны в части I.

Часть III содержит приложения, в которых представлена информация о получении и установке tcsh, краткий справочник по функциям оболочки, описанным в этом руководстве, а также ссылки на другие документы, касающиеся csh и tcsh.

Часть I, Изучение основ

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

В главе 2, Основы работы с командной строкой, приводится краткое изложение основных принципов. Если вы уже знаете что-то о командах, вы можете просмотреть эту главу в качестве обзора или пропустить её.

Глава 3, Эффективное использование оболочки, представляет собой обзор многих функций, которые предоставляет оболочка, чтобы помочь вам работать более эффективно. Это простые и практичные способы извлечь больше пользы из командной строки. Часто даже опытные пользователи не знают обо всех этих функциях. В этой главе вы получите представление о методах, которые подробно рассматриваются в остальной части книги.

Часть II, Повышение эффективности

В главе 4, Файлы запуска командной строки, описываются файлы ~/.cshrc и ~/.login, которые оболочка использует для инициализации вашей рабочей среды. В этой главе также даются рекомендации по изменению файлов запуска в соответствии с вашими предпочтениями.

В главе 5, Настройка вашего терминала, обсуждается, как узнать, какие специальные символы используются в вашем терминале (например, для обратного SPACEа) и как их изменить, если вам не нравятся настройки по умолчанию.

В главе 6, Использование истории команд, рассказывается о том, как меньше печатать, используя историю команд.

В главе 7, Редактор командной строки tcsh, описываются возможности редактора, которые позволяют редактировать команды в интерактивном режиме.

В главе 8, Использование алиасов для создания шорткатов команд, рассказывается о том, как сократить количество вводимых символов, используя механизм алиасов оболочки для создания шорткатов команд.

В главе 9, Шорткаты для имён файлов, описываются способы, с помощью которых оболочка может предоставлять аргументы имён файлов, чтобы вам не приходилось вводить их вручную.

В главе 10, Имена файлов и автоматическое завершениеб описывается, как использовать оболочку для автоматического завершения имён файлов после ввода только начального префикса. В ней также рассказывается о том, как tcsh может дополнять другие типы слов, помимо имён файлов, и как настроить запрограммированное дополнение.

Глава 11, Кавычки и специальные символы, описывает правила использования кавычек в оболочке. Следуя этим правилам, вы можете вводить в командную строку любые символы, даже специальные, не опасаясь, что они будут неправильно интерпретированы.

Глава 12, Использование команд для создания аргументов, рассказывает о подстановке команд — функции, которая позволяет создавать фрагменты командной строки на основе вывода других команд.

Глава 13, Навигация по файловой системе, описывает, как эффективно перемещаться по файловой системе.

Глава 14, Отслеживание местоположения, описывает, как получать информацию о текущем местоположении в файловой системе.

Глава 15, Управление заданиями, показывает, как приостанавливать, возобновлять и завершать задания; переключаться между заданиями; перемещать задания между активным и фоновым режимами.

Часть III, Приложения

Приложение A, Получение и установка tcsh, описывает, как сделать tcsh доступным в вашей системе, если у вас нет текущей версии.

Приложение B, Краткий справочник по csh и tcsh, содержит краткое описание функций и возможностей csh и tcsh, описанных в этом руководстве.

Приложение C, Другие источники информации, содержит ссылки на другие документы. Наиболее важной из этих ссылок является страница руководства tcsh. Она доступна в нескольких форматах, в одном из которых можно перемещаться по гипертекстовым ссылкам с помощью браузера World Wide Web.

Как читать это руководство

Сначала вам следует прочитать главу 1. При необходимости измените оболочку входа в систему на csh или tcsh, следуя приведённым там инструкциям.

Если вы новичок, не знакомы с командной строкой или просто хотите повторить основы выполнения простых команд, вам следует перейти к главе 2. Если у вас также возникают проблемы с тем, как выполнить такие действия, как возврат каретки в терминале, вам может быть полезно прочитать главу 5.

Если вы уже что-то знаете о командной оболочке, вы можете пропустить вводную часть и перейти к главе 3. Эта глава предназначена для того, чтобы помочь вам лучше использовать командную оболочку, представив множество сочетаний клавиш, которые сэкономят ваше время и силы. Применяя информацию, которую вы найдёте здесь, вы быстро станете более опытным пользователем командной строки.

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

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

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

Некоторые специальные символы на клавиатуре отображаются в тексте в верхнем регистре моноширным шрифтом (например, TAB для клавиши «tab»). Другие специальные символы — это RETURN (иногда обозначается как ENTER), ESC (иногда обозначается как ESCAPE), DEL (иногда обозначается как DELETE или RUBOUT) и BACKSPACE (это то же самое, что CTRL-H). Управляющие символы, которые вводятся нажатием клавиши CTRL (или CTL, или CONTROL) и нажатием другой клавиши, обозначаются как CTRL-X, где X — это какая-либо буква. (Для неалфавитных символов может потребоваться клавиша SHIFT. Например, если @ находится на той же клавише, что и 2, вам может потребоваться удерживать нажатой клавишу SHIFT, чтобы ввести CTRL-@.)

В этой книге используются следующие типографские условные обозначения:

Курсив

Используется для команд UNIX, имен файлов и переменных.

Моноширный

Используется в примерах для отображения содержимого файлов или вывода команд. Моноширный также используется для обозначения вводимых вами команд.

Моноширный жирный

Используется в примерах для демонстрации взаимодействия между вами и оболочкой. Текст, который вы вводите, выделяется жирным шрифтом. Например:

% chsh                  # Запустить команду изменения оболочки
Old shell: /bin/csh     # chsh отображает текущую оболочку
New shell: /bin/tcsh    # Ввести оболочку вместо текущей
Моноширный курсив

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

Реверсивное отображение

Используется для отображения положения курсора в командной строке. Например, курсор находится на звёздочке в следующей команде:

% sed -e 's/^ *//' datafile
Рамка

Используется в примерах для отображения места, где нужно ввести специальный символ. В следующем примере вы вводите CTRL-V и TAB между кавычками:

% grep "CTRL-VTAB" myfile

Комментарии и исправления

Если у вас есть комментарии к этой книге, предложения по улучшению или исправления, пожалуйста, свяжитесь со мной по электронной почте: dubois@primate.wisc.edu.

Благодарности

Я благодарю Партху С. Банерджи, Скотта Болта, Пола Плейсуэя, Дэйва Швайсгута, Тима П. Старрина, Киммо Суоминена, Пола А. Викси и Кристоса Зуласа за рецензирование рукописи. Комментарии рецензентов значительно улучшили содержание этого справочника. Тим Старрин предложил раздел о переменных оболочки только для чтения и предоставил текст, на котором он был основан.

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

Мэри Кей Шерер скептически окинула взглядом мою иногда сомнительную прозу, выискивая и исправляя многие паравербальные конструкции.

Адриан Най был главным редактором, но не только. Адриан придумал идею для книги, а затем направлял и поддерживал меня, чтобы воплотить её в жизнь. Я также благодарен другим сотрудникам O’Reilly, в том числе Лену Мьюлнер, Норму Уолшу, Шерил Авруч, Кисмет МакДонаф, Сету Мейслину, Кирстен Науман, Джульетте Мьюлнер и Крису Рейли.

Наконец, я ценю готовность моей жены Карен помочь в написании еще одной книги и за то, что она время от времени напоминает о необходимости дать клавиатуре немного остыть. Она также помогала процессу написания, обсуждая со мной структуру, подход и содержание книги. Эти сеансы обдумывания вслух были бесценны для придания Using csh & tcsh его нынешнего вида.

Часть I
Изучение основ

Глава 1
Введение

В этой главе:

При входе в систему UNIX вас обычно встречает какое-то сообщение на экране и приглашение, например % или $. Приглашение указывает на то, что вы разговариваете с оболочкой (shell) — интерпретатором команд, который предоставляет вам интерфейс для работы с сервисами UNIX. Почему она называется «оболочкой»? Представьте, что оболочка — это оболочка UNIX, которая защищает вас от необходимости разбираться в деталях операционной системы. Оболочка помогает вам выполнять работу, считывая вводимые вами команды и передавая их операционной системе для выполнения.

В этом руководстве рассказывается о csh — популярной оболочке, которая хорошо подходит для выполнения команд, и tcsh — более мощной оболочке, родственной csh. Когда вы используете оболочку, её возможности и ваша способность эффективно их использовать напрямую влияют на эффективность вашей работы. Это руководство поможет вам извлечь больше пользы из csh или tcsh, показав, на что способны эти оболочки и как использовать их возможности интересными и креативными способами. Ваша оболочка станет для вас более ценной, потому что вы будете знать, как использовать её, чтобы выполнять работу быстрее.

Использование примеров

Это руководство лучше всего читать, сидя за клавиатурой. Попробуйте примеры самостоятельно (или составьте на их основе свои собственные команды). Так вам будет проще понять описанные методы. Если я не указываю, относится ли пример к csh или tcsh, вы можете предположить, что пример работает в обеих оболочках. Особенности, характерные для csh, отмечены особо.

Скорее всего, вам придётся внести некоторые изменения в примеры команд из-за различий между версиями UNIX. Например, во многих примерах для разбивки вывода команд на страницы используется команда more, но в некоторых системах вместо неё используется команда pg. Аналогично, в ряде примеров в качестве аргумента команды mail для указания темы сообщения используется -s, но в некоторых системах команда mailx, а не mail, понимает -s. Команды для печати также немного отличаются. В примерах я использую lpr, но вам нужно будет заменить его на местный эквивалент. В таблице 1-1 перечислены некоторые команды-заменители, которые вы можете попробовать.

Таблица 1-1: Команды-заменители
Если у вас нет... Попробуйте вместо этого...
more page, pg, less, most
mail -s mailx -s, elm -s
stty all stty -a
lpr lp
emacs gmacs, gnumacs
colrm cut -c

Выбор оболочки для входа в систему

Оболочка для входа в систему — это оболочка, которую система запускает для вас при входе в систему. Вам следует определить, какая оболочка является вашей оболочкой для входа в систему, и изменить ее, если она не та, которую вы хотите использовать. Переменная среды SHELL обычно содержит путь к вашей оболочке для входа в систему. Вы можете отобразить ее значение с помощью команды echo:

% echo $SHELL

В ответ на команду echo должно быть указано имя пути, например /bin/sh, /bin/csh или /bin/ksh. Последняя часть пути указывает, какую оболочку вы используете. Если оболочка, которую вы хотите использовать, уже является вашей оболочкой для входа в систему, то всё готово.

Если вы решите использовать другую оболочку для входа в систему, вам нужно знать, где она находится. Используйте команду which, чтобы определить имя пути оболочки:

% which tcsh
/bin/tcsh

В этом примере команда which указывает, что tcsh установлен в /bin/tcsh. (В вашей системе путь может быть другим.) Зная путь к оболочке, выполните команду «change shell» в вашей системе (вероятно, chsh или passwd -s). Предположим, что ваша текущая оболочка — csh, но вы хотите использовать tcsh и знаете, что ее путь — /bin/tcsh. Сделайте tcsh своей оболочкой для входа в систему следующим образом:

% chsh                  # Запустить команду изменения оболочки
Old shell: /bin/csh     # chsh отображает текущую оболочку
New shell: /bin/tcsh    # Ввести оболочку вместо текущей

В некоторых версиях chsh отображается список оболочек, из которых вы можете выбрать. Другие нужно вызывать следующим образом:

% chsh dubois /bin/tcsh

Первый аргумент — это ваше имя пользователя (имя, которое вы используете для входа в систему), а второй — путь к оболочке, которую вы хотите использовать.

В системах на базе 4.4BSD для изменения оболочки используется команда chpass:

% chpass -s /bin/tcsh

Если команда для изменения оболочки не работает, обратитесь к системному администратору. В противном случае войдите в систему снова, и вы будете работать в новой оболочке.

Временное переключение на другую оболочку

Если вы не уверены, что хотите сделать определённую оболочку своей оболочкой для входа в систему, вы можете попробовать её временно. Введите имя оболочки, чтобы запустить её, введите команды, которые вы хотите выполнить, а затем завершите работу оболочки, введя exit. Например, чтобы запустить пример сеанса tcsh, выполните следующие действия:

% tcsh                           # Запустить tcsh
% ...type other commands here... # Выполнить несколько команд
% exit                           # Завершить tcsh и вернуться в исходную оболочку

Если оболочка не найдена, вы получите сообщение об ошибке:

% tcsh
tcsh: Command not found.

В этом случае оболочка может быть недоступна на вашем компьютере или установлена в нестандартном месте. Обратитесь к системному администратору.

Рекомендация: используйте tcsh, а не csh

csh широко распространена, особенно в системах UNIX на базе Berkeley, где она, как правило, является стандартной пользовательской оболочкой. csh обычно доступна и в других версиях UNIX, например, на базе System V. tcsh не поставляется «официально» таким количеством производителей, как csh, но tcsh работает во многих версиях UNIX и доступна бесплатно в Интернете. Если в вашей системе не установлен tcsh, см. Приложение A Получение и установка tcsh для получения инструкций по его установке.

Я рекомендую вам сделать tcsh своей оболочкой для входа в систему для ежедневной работы. tcsh более мощный и удобный, чем csh, и может помочь вам выполнять работу более эффективно. Некоторые преимущества tcsh по сравнению с csh:

Прежде чем читать дальше

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

% more ~/.cshrc ~/.login     # Отобразить файлы запуска оболочки
                             # (попробуйте page или pg если нет more)
% stty all                   # Отобразить настройки терминала
                             # (попробуйте stty -a, если stty all не работает)
% printenv                   # Отобразить значения переменных среды
% set                        # Отобразить значения переменных оболочки
% alias                      # Отобразить определения алиасов
% history                    # Просмотреть историю

Имеют ли для вас смысл выходные данные этих команд или они похожи на тарабарщину? Если второе, то это нормально — попробуйте вспомнить, как странно выглядят некоторые результаты команд сейчас. По мере чтения этого руководства время от времени запускайте команды снова. Их выходные данные должны становиться всё более понятными, и вы начнёте понимать, что изучаете, когда в этой незнакомой местности начнут появляться узнаваемые ориентиры.

Глава 2
Основы работы с оболочкой

В этой главе:

В этой главе представлено простое и краткое введение в оболочку. Вам следует прочитать его, если вы новичок в работе с оболочкой и/или UNIX, или если вы хотите получить общее представление перед прочтением остальной части этого руководства.

Если используемая здесь команда вам незнакома, попробуйте команду man, чтобы прочитать соответствующую страницу онлайн-руководства. Например, если вы не знаете, что такое wc, когда она появляется в примере, вы можете узнать, что это программа для подсчёта слов, с помощью следующей команды:

% man wc

Чтобы прочитать о команде man, используйте эту команду:

% man man

Ещё один полезный справочник — это руководство O'Reilly & Associates UNIX in a Nutshell.

Ввод команд

Чтобы ввести команду, напечатайте её и нажмите клавишу RETURN. Некоторые команды настолько просты, что их можно выполнить, напечатав только их название. Вот несколько примеров:

% date             # Отобразить текущие дату и время
% who              # Показать кто в системе
% ls               # Просмотреть содержимое текущего каталога
% mail             # Прочитать почту
% clear            # Очистить экран
% logout           # (или exit) Завершить сеанс

Если оболочка не сможет найти команду, вы получите сообщение об ошибке (ошибки обычно возникают, когда команда не существует или вы неправильно написали её название):

% glarbl                    # Несуществующая команда
glarbl: Command not found.
% dtae                      # Ошибка в написании команды date
dtae: Command not found.

Если вы заметили ошибку при вводе до того, как нажали RETURN, вы можете удалить ее с помощью клавиши BACKSPACE или DEL (если одна клавиша не работает, попробуйте другую). Чтобы удалить всю строку, нажмите CTRL-U или CTRL-X. Чтобы удалить только последнее слово, нажмите CTRL-W. (Если это не сработает и вы используете tcsh, попробуйте ESC DEL или ESC BACKSPACE.) Если вы вводите команду, а затем решаете, что хотите прервать ее выполнение, попробуйте нажать CTRL-C.

Команды иногда требуют дополнительной информации, например параметров обработки или имён файлов для чтения. Эти дополнительные сведения называются аргументами команды. Аргументы указываются после имени команды и разделяются SPACEами. Ниже приведены примеры:

% ls -a               # Выводит список всех файлов в каталоге, в т.ч. невидимых
% sort -r file        # Сортирует файлы в обратном порядке
% mv file1 file2      # Переименовывает file1 в file2 (file1 становится file2)
% cp file1 file2      # Создает копию файла file2 (file1 остается как есть)
% rm file1 file2      # Удаляет file1 и file2
% mail christine      # Отправляет письмо Кристине
% cal 1752            # Показывает календарь на 1752 год
% grep boa snakelist  # Поиск экземпляров слова boa в файле snakelist

Вы можете выполнить несколько команд в одной строке, разделив их точкой с запятой:

% date ; who ; ls

И наоборот, вы можете ввести одну команду в несколько строк, завершив все строки, кроме последней, обратной косой чертой. Обратная косая черта служит символом продолжения:

% more file1 file2 file3 \
file4 file5 file6 \
file7 file8

Ввод и вывод команд

По умолчанию большинство команд, которые выводят данные, записывают их в ваш терминал. Если вы используете символ >, оболочка позволяет вместо этого отправлять вывод в файл:

% who > users               # Записать список пользователей в файл users
% cat file1 file2 > file3   # Объединить (конкатенировать) file1 и file2 в file3

Это называется перенаправлением вывода. Если выходной файл не существует, он создаётся. Если файл уже существует, его содержимое перезаписывается:

% sort data > junk         # Отсортировать data в junk
% cal 1995 > junk          # Перезаписать junk данными календаря за 1995 год

Другая форма перенаправления вывода использует символы >> для добавления вывода в файл. Вы можете записать использование диска на заданную дату следующим образом:

% date > junk            # Записать дату в junk
% du >> junk          # Добавить отчет об использовании дискового пространства в junk

Когда вы записываете выходные данные команды в файл, вы можете использовать их позже по-разному, без необходимости повторять команду снова и снова:

% who > users                # Записать список пользователей в файл users
% more users                    # Просмотреть список пользователей
% wc -l users                   # Подсчитать количество строк (т.е. пользователей)
% sort users > sorted-users  # Отсортировать список пользователей в другой файл

Многие команды по умолчанию считываются с терминала. То есть они считывают всё, что вы вводите, пока вы не введёте строку, состоящую только из CTRL-D, что означает конец файла. Например, чтобы отправить электронное письмо, вы можете запустить программу отправки писем, ввести своё сообщение, а затем завершить его с помощью CTRL-D:

% mail javaman
How about joining us for lunch tomorrow?
(If you're not hungry, you can just drink coffee!)
CTRL-D

Для таких команд оболочка поддерживает перенаправление ввода. Если ваше почтовое сообщение находится в файле с именем my-msge, вы можете перенаправить ввод с помощью символа <, чтобы почта считывала данные из файла, а не из терминала:

% mail javaman < my-msge

Перенаправление ввода и вывода можно использовать вместе:

% tr a-z A-Z < in > out       # Перевести строчные буквы в прописные

Перенаправление ввода используется не так часто, как перенаправление вывода. Перенаправление ввода часто не требуется, потому что большинство команд знают, как читать файлы, названные в командной строке. Например, эти команды имеют одинаковый эффект, поэтому < во второй команде — это просто дополнительный ввод:

% sort data > junk
% sort < data > junk

Файлы и каталоги

При создании файла лучше использовать в названии «безопасные» символы, такие как буквы, цифры и подчёркивания. Точки и тире тоже допустимы, но лучше не использовать их в качестве первого символа в имени файла. В именах файлов UNIX важен регистр букв, поэтому junk, Junk и JUNK — это разные файлы.

Каталог — это особый тип файла, который используется для хранения других файлов (включая другие каталоги). Каталог, в котором вы оказываетесь при первом входе в систему, называется вашим домашним каталогом. Каталоги помогают вам упорядочивать работу, поскольку вы можете группировать наборы связанных файлов в отдельные каталоги. Таким образом, вам не нужно хранить всё в домашнем каталоге — это верный способ создать неразбериху.

Шаблоны имён файлов

Если вы хотите указать несколько файлов в командной строке, то ввод всех имён по отдельности быстро надоест. Часто можно сэкономить на нажатиях клавиш, используя шаблоны имён файлов. Оболочка интерпретирует шаблоны и находит соответствующие имена файлов. Шаблоны имён файлов кратко описаны ниже. Дополнительную информацию см. в главе 9, Сокращения для имён файлов.

Оболочка предоставляет следующие операторы сопоставления шаблонов:

*

Соответствует любой строке символов. * сам по себе соответствует любому имени файла; a* соответствует именам файлов, начинающимся с a; *z соответствует именам файлов, заканчивающимся на z: a*z соответствует именам файлов, начинающимся с a и заканчивающимся на z; *a* соответствует именам файлов, содержащих a в любом месте имени файла.

?

Соответствует любому отдельному символу. ??? соответствует именам файлов, состоящим из трёх символов; part? соответствует именам файлов, начинающимся с part, за которым следует любой символ; ?????* соответствует именам файлов, состоящим как минимум из пяти символов.

[...]

Соответствует любому отдельному символу, указанному в скобках. [mM]* соответствует именам файлов, начинающимся с m или M (Вернее, начинающимся на любое количество символов m или M. Прим. пер.); *.[cho] соответствует именам файлов, заканчивающимся на .c, .h или .o. Для обозначения диапазона символов можно использовать дефис. Например, part[0-9] соответствует десяти именам файлов от partO до part9.

Шаблоны имён файлов обладают широкими возможностями и помогают сократить количество вводимых символов, но к ним нужно немного привыкнуть. Используйте команду echo, чтобы попрактиковаться в использовании шаблонов. Команда echo безопасна, потому что она ничего не делает, кроме как отображает аргументы, переданные ей оболочкой. Это позволяет просмотреть результаты применения шаблона, ничего не делая с файлами с именами:

% echo [0-9]*               # Какие имена файлов начинаются с цифры?
00REAEME
% echo *.ps                 # Какие файлы являются файлами PostScript?
fontlist.ps spiral.ps tiger. ps
% echo *.[ly]               # Какие файлы являются исходными файлами lex или yacc?
parser .y scanner.1
«Невидимые» файлы

Команда ls выводит список файлов в каталоге, но обычно не отображает точечные файлы (те файлы, имена которых начинаются с точки, скрытые). Если вы запустите ls после создания такого файла, вы не увидите его имя — может показаться, что файл никогда не создавался! Чтобы увидеть все файлы в каталоге, используйте параметр -a («показать все»). Попробуйте выполнить следующие две команды в своём домашнем каталоге и обратите внимание на разницу:

% ls                    # Список файлов, кроме скрытых
% ls -a                 # Список всех файлов

Если вы запустите ls -a в разных каталогах, вы заметите, что имена файлов . и .. всегда отображаются. Имя файла . означает «текущий каталог» и обеспечивает удобный способ ссылки на текущее местоположение:

% chmod 700 .                    # Сделать текущий каталог закрытым
% cp /usr/lib/aliases .          # Скопировать файл в текущий каталог
% find . -name core -print       # Поиск дампов ядра в текущем каталоге

Имя файла .. всегда означает «родительский каталог». .. полезно, когда вы хотите сослаться на расположение на один или несколько уровней выше в файловой системе:

% ls ..                       # Показать каталог, расположенный выше текущего
% mv thisfile ..              # Переместить файл из текущего каталога в родительский
% mv ../thisfile .            # Переместить файл из родительского каталога в текущий
% cd ..                       # Перейти на один уровень выше
% cd ../..                    # Перейти на два уровня выше
Создание каталогов

Используйте команду mkdir, чтобы создать новый каталог. Например, чтобы создать подкаталог с именем NewDir в текущем каталоге, выполните следующее:

% mkdir NewDir

Если вы хотите сделать каталог закрытым, измените режим доступа к нему:

% chmod 700 NewDir            # Режим 700 = доступ только для владельца
Изменение текущего каталога

Команда cd (смена каталога) изменяет текущий каталог, то есть ваше местоположение в файловой системе. Без дополнительных аргументов команда cd переходит в ваш домашний каталог, позволяя легко вернуться на «домашнюю базу» из любой точки файловой системы:

% cd

Если вы укажете каталог, команда cd перейдёт в него. Ниже приведены некоторые стандартные команды для перемещения по файловой системе:

% cd dir1                  # Перейти на один уровень вниз в dir1
% cd dirl/dir2             # Перейти на два уровня вниз через dir1 в dir2
% cd ..                    # Перейти на один уровень вверх в родительский каталог
% cd ../..                 # Перейти на два уровня вверх в родительский каталог родительского каталога
% cd ../dir3               # Перейти на один уровень вверх, затем обратно в dir3
% cd /                     # Перейти в корневой каталог (верхнюю часть файловой системы)
% cd -                     # Перейти в последнее место (только для tcsh)
Удаление каталогов

Когда вы закончите работу с каталогом и захотите его удалить, используйте команду rmdir:

% rmdir NewDir

rmdir не сработает, если каталог не пуст (содержит другие файлы или каталоги):

% rmdir NewDir
rm: NewDir: Directory not empty

Если rmdir не сработает, а каталог кажется пустым, в нём могут быть скрытые файлы. Используйте ls -a для их поиска:

% ls -a NewDir

Игнорируйте записи . и .., но если присутствуют другие файлы, удалите их, а затем снова попробуйте выполнить rmdir. В качестве альтернативы вы можете удалить каталог, даже если он не пуст, с помощью этой команды:

% rm -r NewDir

Параметр -r указывает команде rm на рекурсивное удаление NewDir и всех файлов и каталогов в нём. Да, этот параметр опасен! Хорошенько подумайте, прежде чем использовать rm -r.

Объединение команд

Вы можете объединять команды с помощью символа | (вертикальная черта или труба (pipe)), чтобы вывод первой команды стал вводом для второй:

% ls | wc -l               # Подсчитать количество файлов в текущем каталоге
% who | grep colin         # Узнать, вошёл ли в систему пользователь colin

Одно из наиболее распространённых применений труб — добавление чего-либо в конец команды, чтобы вывод не прокручивался за пределы экрана:

% cal 1492 | more          # Просмотреть календарь на 1492 год с помощью пейджера

Команды, соединённые с помощью труб, образуют более длинную команду, называемую конвейером. Конвейеры могут состоять более чем из двух программ. Следующая команда выводит размеры (в блоках диска) и имена ваших файлов, удаляет начальную строку «total size», сортирует остальные размеры в обратном порядке, а затем выводит первые пять строк результата. В результате выводится информация о пяти самых больших файлах:

% ls -s | tail +2 | sort -rn | head -5

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

Конвейеры и перенаправление вывода можно использовать вместе:

% ls -s | tail +2 | sort -rn | head -5 > big5

Вы можете объединить выходные данные последовательных команд, заключив последовательность в скобки. Эти две строки команд отличаются друг от друга:

% date ; who | more
% (date ; who) | more

В первой последовательности выходные данные команды date записываются в терминал, а выходные данные команды who — в more. Во второй последовательности выходные данные обеих команд записываются в more.

Тот же принцип применяется при перенаправлении вывода:

% date ; du > junk
% (date ; du) > junk

Первая последовательность записывает вывод команды date в терминал, а вывод команды du — в файл junk. Вторая последовательность записывает вывод обеих команд в файл junk.

Выполнение команд в фоновом режиме

Обычно оболочка ожидает завершения выполнения команды, прежде чем предложить вам ввести следующую. Если вы считаете, что выполнение команды займёт много времени, и хотите продолжить работу во время её выполнения, вы можете запустить команду в фоновом режиме. Когда вы добавляете символ & к команде, оболочка запускает команду в фоновом режиме и сразу же запрашивает следующую:

% sort huge-in > huge-out &

Вы можете применить & к последовательности команд, чтобы запустить всю последовательность в фоновом режиме. Следующая команда служит грубым напоминанием о том, что нужно вернуться домой через 10 минут:

% (sleep 600 ; echo TIME TO LEAVE) &

sleep приостанавливает работу на указанное количество секунд и завершает работу, поэтому команда ожидает 10 минут, а затем выводит на ваш терминал сообщение TIME TO LEAVE. Поскольку она работает в фоновом режиме, вы можете продолжать работать в это время.

Вы можете одновременно запускать несколько команд в фоновом режиме:

% sort huge-in.l > huge-out.1 &
% sort huge-in.2 > huge-out.2 &
% sort huge-in.3 > huge-out.3 &

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

Когда важны SPACEы?

Имена команд и аргументы разделяются SPACEами, но количество SPACEов вокруг имени и его аргументов не имеет значения. Эти команды эквивалентны:

% sort -r    file
% sort    -r file
%    sort -r file

В командах, показанных до сих пор, я обычно ставил SPACEы вокруг следующих специальных символов:

; < > | ( ) &

Почему я вставил SPACEы? Просто, чтобы облегчить чтение команд. Эти символы не требуют SPACEов вокруг них, поэтому следующие команды эквивалентны:

% ( date ; ls -s | tail +2 | sort -rn ) > sizes &
% (date;ls -s|tail + 2|sort -rn)> sizes&

Если аргумент содержит SPACEы, заключите его в кавычки, чтобы оболочка не интерпретировала его как несколько аргументов. Например, при использовании mail для отправки кому-либо файла полезно указать тему с помощью параметра -s, чтобы получатель мог легко определить, о чем идет речь в сообщении. Если тема состоит из нескольких слов, закавычьте ее:

% mail -s 'Here are the figures you requested' karen < budget

Без кавычек mail будет думать, что тема сообщения "Here", а получатели - "are", "the", "figures", "you", "requested и "karen".

Вам также следует использовать кавычки, если аргумент команды содержит другие специальные символы, например, скобки и & в следующей команде:

% mail -s 'Playoff Schedule (for May. 6 & 7)' ian < playoffs

Файлы запуска оболочки

Когда вы входите в систему, оболочка считывает два файла запуска с именами .cshrc и .login из вашего домашнего каталога. Если .tcshrc существует, tcsh считывает .tcshrc вместо .cshrc . Эти файлы содержат команды, которые настраивают вашу рабочую среду — такие вещи, как алиасы, настройки вашего терминала, приглашение командной строки и набор каталогов, в которых ваша оболочка выполняет поиск команд. Вы можете отредактировать файлы запуска, чтобы изменить свою среду; любые изменения вступают в силу при следующем входе в систему.

Ознакомьтесь с содержимым ваших файлов автозагрузки, выполнив следующую команду в своём домашнем каталоге:

% more .cshrc .login

Возможно, вы не поймёте всё, что видите, но по мере накопления опыта работы с оболочкой файлы будут иметь для вас больше смысла.

Более подробную информацию о файлах автозагрузки, а также рекомендации по их изменению можно найти в главе 4 Файлы автозагрузки оболочки. Кроме того, поищите в тексте .cshrc и .login; в этом руководстве представлено множество примеров команд в файлах запуска, которые вы можете использовать для настройки рабочей среды.

Глава 3
Эффективное использование оболочки

В этой главе:

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

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

Некоторые из методов, обсуждаемых в этой главе, поначалу могут показаться вам странными. Лучший способ преодолеть это чувство — попробовать эти методы самостоятельно. Немного попрактиковавшись, вы привыкнете к функциям, которые поначалу казались странными, и будете жалеть, что не научились пользоваться ими раньше.

Использование имён файлов

Большинство команд работают с файлами, поэтому во время работы вы часто вводите имена файлов. Один из способов быстро обращаться к файлам — использовать шаблоны имён файлов (представленные в главе 2, Основы работы с оболочкой, как способ указания групп файлов). В оболочке есть много других способов вводить имена файлов, затрачивая меньше времени и усилий:

Позвольте оболочке вводить имена файлов за вас

Когда вы вводите первую часть имени файла, оболочка часто может определить остальную часть имени, чтобы вам не приходилось вводить его самостоятельно. Эта функция называется завершением имени файла. Чтобы использовать ее, введите первую часть имени файла, нажмите специальную клавишу, и оболочка введёт оставшуюся часть.

Чтобы активировать автозаполнение имени файла в tcsh, введите префикс имени файла и нажмите клавишу TAB. Если вы хотите отредактировать файл с именем disestablishmentarianism, введите первую часть имени и позвольте оболочке завершить ввод, как показано ниже ( указывает на расположение курсора):


% vi dis                        # Введите первую часть имени файла и нажмите TAB
% vi disestablishmentarianism   # tcsh введет оставшуюся часть имени за вас

В csh автозаполнение имени файла используется немного по-другому. Вместо TAB вы нажимаете ESC, и, кроме того, в вашем ~/.cshrc должна быть следующая команда:

set filec

Если префикс неоднозначен (совпадает с несколькими именами файлов), оболочка издаёт звуковой сигнал, но всё равно выводит столько информации, сколько может, то есть столько, сколько является общим для всех имён, совпадающих с префиксом. Нажмите CTRL-D, чтобы оболочка вывела для вас список совпадающих имён файлов. Эта функция полезна, когда вы пытаетесь понять, сколько ещё нужно ввести, чтобы префикс стал однозначным.

Если курсор находится после SPACEа, текущий префикс имени файла пуст. Пустой префикс соответствует всем именам в текущем каталоге, поэтому нажатие CTRL-D после SPACEа — это быстрый способ получить список ls, пока вы вводите команду.

Чтобы исключить из сопоставления имена файлов, оканчивающиеся на определённые суффиксы, задайте в файле ~/.cshrc переменную fignore со списком суффиксов[1]:

set fignore = ( .o .bak )    # Не используйте файлы .o или .bak для сопоставления

fignore игнорируется, если существует только одно возможное завершение.

В дополнение к описанным выше возможностям завершения, оболочка имеет и другие возможности. Чтобы узнать о них, см. главу 10, Имя файла и программируемое завершение.

  1. При присвоении переменной значения, состоящего из нескольких строк, необходимы скобки.
Использование «шаблонов» для несуществующих имён файлов

Шаблоны имен файлов с использованием *, ? или [...] полезны для указания групп связанных имен файлов, но только если вы хотите ссылаться на файлы, которые уже существуют. Если вы пытаетесь указать новые имена файлов, вы можете использовать другой метод.

Предположим, вы хотите создать несколько каталогов с именами от Experiment1 до Experiment4 для хранения экспериментальных данных. Шаблон, подобный Experiment[1-4], не работает, потому что имен не существует:

% mkdir Experiment[1-4]
mkdir: No match.

Вместо этого используйте { } для указания имён каталогов:

% mkdir Experiment{1,2,3,4}

Оболочка просматривает строки, разделённые запятыми, между фигурными скобками и генерирует по одному аргументу для каждой из них. Полученная команда эквивалентна этой:

% mkdir Experiment1 Experiment2 Experiment3 Experiment4
Использование сокращений для имён домашних каталогов

Если вы хотите обратиться к своему домашнему каталогу или к каталогу другого пользователя, не вводя длинное имя пути, используйте обозначение ~. Символ ~ в начале имени пути относится к вашему домашнему каталогу. Эта функция позволяет легко использовать этот каталог независимо от вашего текущего местоположения. Например, если в вашем домашнем каталоге есть подкаталог Mail, вы можете легко скопировать в него файл:

% cp myfile ~/Mail      # Скопировать myfile в каталог Mail

Аналогичным образом вы можете скопировать файлы из каталога Mail в текущий каталог, например так:

% cp ~/Mail/myfile . # Скопировать myfile из каталога Mail

Другая форма обозначения ~, ~name, означает домашний каталог пользователя name. Это обозначение поможет вам сэкономить много времени при указании местоположений в чужой учётной записи. Например, если домашний каталог alison/usr/staff/alison, то следующие команды эквивалентны, но вторую проще набрать:

% ls /usr/staff/alison
% ls ~alison

Не все учётные записи позволяют другим пользователям получать к ним доступ; сообщения, подобные приведённым ниже, означают, что david ценит свою конфиденциальность и ограничил доступ к своей учётной записи, чтобы никто не шпионил за ним:

% cd ~david
/usr/staff/david: Permission denied.
% ls ~david
/usr/staff/david unreadable

Вы можете сделать свою учётную запись закрытой, если хотите:

% chmod 700 ~

Поскольку ~ является специальным символом только в начале имён файлов, вы можете использовать его как обычный символ в других местах имён. Некоторым людям нравится использовать его в конце имени файла, чтобы обозначить, что файл является резервной копией (аналогично тому, как используется суффикс .bak):

% cp report report~     # Создать резервную копию файла с именем report~
Позвольте оболочке исправлять ошибки в написании

tcsh может исправлять ошибки в написании. Эта функция может быть весьма полезной, особенно если вы плохо печатаете. Чтобы включить исправление орфографии, установите правильную переменную оболочки в файле ~/.cshrc с помощью одной из приведённых ниже команд:

set correct = cmd
set correct = all

Первая форма включает исправление орфографии только для имён команд. Вторая форма включает исправление орфографии для всей командной строки.

Если tcsh считает, что вы допустили ошибку в написании слова, он предлагает исправленную командную строку:

% mroe myfile
CORRECT>more myfile (y|n|e|a)?  

Введите y, чтобы принять исправление, n, чтобы отказаться от исправления (т.е. выполнить команду в точности так, как она была введена), e, чтобы отредактировать команду, или a, чтобы прервать выполнение команды. (Чтобы отредактировать команду, вам нужно знать, как пользоваться редактором командной строки tcsh. Смотрите раздел "Повторное использование и редактирование команд" в этой главе и главу 7, Редактор командной строки tcsh, для получения дополнительной информации.)

Обязательно ознакомьтесь с исправлением орфографии, которое предлагает tcsh, — не просто вводите y автоматически. Это предупреждение особенно актуально, если вы создаете новый файл. Механизм исправления предполагает, что новое имя файла должно быть неправильным, если файл не существует, поэтому вместо этого предлагается использовать один из существующих файлов. Такое поведение иногда приводит к тому, что оболочка предлагает исправления, как показано ниже:

% mv file1 file2
CORRECT>mv file1 file1 (y|n|e|a)?  

Предложенная команда бессмысленна, поэтому вам следует ввести n, чтобы выполнить команду так, как вы её ввели.

Работа с именами файлов, которые трудно ввести

К файлу может быть сложно получить доступ, если его имя содержит символы, которые интерпретируются оболочкой особым образом. Предположим, у вас есть файл с именем Preliminary Results, и вы пытаетесь посмотреть, что в нём содержится. Вы не можете просто ввести имя файла, как показано ниже:

% more Preliminary Results
Preliminary: No such file or directory
Results: No such file or directory

Команда не выполняется, потому что имя файла содержит SPACE. SPACEы обычно разделяют аргументы команды, поэтому оболочка передаёт в команду more два аргумента, а не один.

Обычно вы можете ссылаться на такие проблемные файлы, заключив их название в кавычки или поставив перед каждым специальным символом обратную косую черту, чтобы отключить любое специальное значение:

% more 'Preliminary Results'
% more Preliminary\ Results

В tcsh часто проще всего использовать автозаполнение имён файлов, чтобы не вводить длинные имена. Когда tcsh завершает имя файла, он ставит обратную косую черту перед специальными символами, чтобы заключить их в кавычки:


% more Pre                     # Введите префикс имени файла и нажмите TAB
% more Preliminary\ Results    # tcsh завершит имя и экранирует SPACE за вас

Общие рекомендации по работе со специальными символами в именах файлов см. в главе 11, Кавычки и специальные символы.

Повторное использование и редактирование команд

Мы только что рассмотрели несколько способов быстрого ввода имён файлов. В следующих разделах показано, как использовать некоторые другие функции оболочки для сокращения количества вводимых символов: повторное использование и редактирование команд, использование алиасов для создания шорткатов команд и подстановка команд.

Список истории команд оболочки

В оболочке есть механизм для ведения списка истории. То есть она запоминает выполняемые вами команды и позволяет повторно запускать их несколькими нажатиями клавиш. Предположим, вы анализируете два набора данных и просматриваете результаты каждого анализа перед печатью данных:

% sed -e 's/~\(...\) *\([0-9][0-9]*\)/\2 \1/' data1 > temp
% anova Height Weight < temp | more
% anova Height Weight < temp | lpr
% sed -e 's/^\(...\) *\([0-9][0-9]*\)/\2 \1/' data2 > temp
% anova Height Weight < temp | more
% anova Height Weight < temp | lpr

В этих командах много избыточных элементов. Вы можете получить те же результаты, введя меньше символов, если будете повторно использовать команды, которые вы уже запускали:

% sed -e 's/^\(...\) *\([0-9][0-9]*\)/\2 \1/' data1 > temp
% anova Height Weight < !$ | more   # Запустите anova, используя temp как входной файл
% ^more^lpr                            # Измените more на lpr
% !sed:s/data1/data2                   # Выполните sed, заменив data1 на data2
% !?more                               # Выполните последнюю команду, содержащую more
% !?lpr                                # Выполните последнюю команду, содержащую ipr

Прежде чем пытаться повторно использовать команды, убедитесь, что ваша оболочка их запоминает. Попробуйте выполнить команду history, чтобы отобразить список истории:

% history
209  rm junk
210  pushd
211  ls
212  vi chO1
213  more appc
.
.
.

history должна отображать последние выполненные команды с порядковым номером рядом с каждой из них. Задайте переменную оболочки истории, введя следующее в файл ~/.cshrc. Измените число, если вы хотите, чтобы оболочка запоминала больше (или меньше) последних 20 команд:

set history = 20

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

Оба способа доступа к списку истории кратко описаны в следующих нескольких разделах. Дополнительную информацию см. в главе 6 Использование истории команд и в главе 7.

Редактор может использовать сочетания клавиш emacs или vi. В этой главе я для простоты буду предполагать, что вы используете сочетания клавиш emacs, которые по умолчанию используются на большинстве сайтов. Если вас интересует использование сочетаний vi, см. главу 7.

Повторение команд с помощью !-спецификаторов

Символ ! вводит ссылку на историю, указывая оболочке повторить что-либо из списка истории. Спецификаторы для повторения команд приведены в таблице 3-1.

Таблица 3-1: Спецификаторы истории для повторения команд
Спецификатор Описание
!! Повторить предыдущую команду.
!n Повторить команду n, где n — это номер, указанный рядом с командой в выводе из history.
!-n Повторить предпоследнюю команду, например, !-2 повторяет предпоследнюю команду.
!str Повторить последнюю команду, начинающуюся с str, например, !ls повторяет вашу последнюю команду ls, str не обязательно должно быть полным именем команды; это может быть префикс.
!?str Повторить последнюю команду, содержащую str в любом месте командной строки.

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

% date                        # Введите команду
Fri Sep  9 13:38:43 CDT 1994
% !!                          # Повторите ее
date                          # Оболочка печатает команду
Fri Sep  9 13:38:49 CDT 1994
Повторение команд с помощью редактора команд

В tcsh вы можете использовать редактор команд для поиска и выполнения команд. Нажимайте CTRL-P (предыдущая команда) и CTRL-N (следующая команда), чтобы перемещаться вверх и вниз по списку истории по одной команде за раз[2]. Каждая команда отображается по мере поиска, курсор находится в конце. Нажмите RETURN, чтобы выполнить отображаемую команду. Введите символ прерывания (обычно CTRL-C), чтобы отменить команду.

Самый простой способ использования редактора команд — нажать CTRL-P, чтобы повторить предыдущую команду. CTRL-P эквивалентен !!, но требует меньше нажатий клавиш.

Чтобы найти в списке истории команды, начинающиеся с str, введите str, а затем ESC p. Например, вы можете ввести vi ESC p, чтобы получить самую последнюю команду vi. Если это не та команда, которую вы искали, продолжайте вводить ESC p, пока не получите нужную команду. (Если вы зашли слишком далеко, ESC n выполняет поиск в обратном направлении.)

Одно из преимуществ редактора команд перед !-спецификаторами заключается в том, что вы можете увидеть команду, которую будете выполнять, прежде чем нажмёте RETURN, — не нужно гадать.

  1. Стрелки вверх и вниз выполняют те же функции, что и CTRL-P и CTRL-N. Возможно, вам будет проще запомнить стрелки.
Повторение части команды

Часто бывает полезно повторить только часть команды, а не всю целиком. Для этого можно использовать !-спецификаторы. !-спецификаторы, показанные в таблице 3- 2, особенно полезны.

Таблица 3-2: Обозначения истории для повторения слов
Обозначение Описание
!* Повторить все аргументы из предыдущей команды
!^ Повторить первый аргумент из предыдущей команды
!$ Повторить последний аргумент из предыдущей команды

Используйте !* для копирования всех аргументов одной команды в другую:

% grep Unix file1 file2 file3     # Найдите строку в нескольких файлах
% grep -i !*                      # Теперь выполните поиск без учёта регистра
grep -i Unix file1 file2 file3

!$ полезно, когда вы хотите выполнить набор операций с одним и тем же файлом:

% more document.ms          # Просмотр файла
% vi !$                     # Редактирование файла
vi document.ms
% groff -ms !$ | lpr        # Форматирование и печать файла
groff -ms document.ms | lpr

Используйте !^ если вам нужен только первый аргумент из предыдущей команды:

% tbl final-report.ms | nroff -ms | more
% mail -s "Final report" june kokfung < !^
mail -s "Final report" june kokfung < final-report.ms

Оболочка предоставляет другие обозначения, которые позволяют повторить любое слово из любой команды в списке истории. Эти обозначения описаны в главе 6.

Вы также можете повторять слова с помощью редактора команд tcsh. В таблице 3-3 приведены некоторые полезные команды для повторения.

Таблица 3-3: Команды редактора команд для повторения слов
Команда Описание
ESC _ Повторить последний аргумент из предыдущей команды
ESC CTRL-_ Повторить предыдущее слово из текущей команды
ESC / Повторить самое последнее слово из списка истории, которое совпадает со словом слева от курсора

ESC / в некотором смысле похоже на автозаполнение имени файла. Оно «дополняет» префикс слева от курсора, но ищет совпадение в списке истории. Если найденное совпадение вам не подходит, снова введите ESC /, чтобы продолжить поиск в списке.

Команды редактирования

Вы можете исправить орфографические ошибки или изменить аргументы, введя немного текста, используя механизм ^^ оболочки:

% mre file1                 # Запустите команду more, чтобы просмотреть файл
mre: Command not found.     # Упс!
% ^m^mo                     # Замените m на mo
more file1
% ^1^2                      # Теперь просмотрите file2
more file2

Строки, которые появляются после первого и второго ^, указывают, что вы хотите изменить и на что заменить. Первая строка не должна содержать SPACEов.

^^ можно использовать для внесения изменений только в предыдущую команду. Чтобы выполнить подстановку в произвольной команде из списка истории, используйте :s// вместо нее:

% !-2:s/abc/def        # Замените abc на def во второй по счёту команде
% !nr:s/more/lpr       # Замените more на lpr в последней команде nroff

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

% nroff -ms myfile | more         # Запустите команду
% nroff -ms myfile | more         # Нажмите CTRL-P, чтобы вспомнить команду
% nroff -ms myfile |              # Backspace, чтобы удалить more
% nroff -ms myfile | lpr          # Введите lpr

Вы также можете стереть и заново ввести команду, в конце которой есть ошибка:

% nroff -ms myfile | moer      # Выполнить команду
moer: Command not found.       # Упс!
% nroff -ms myfile | moer      # Нажмите CTRL-P, чтобы вспомнить команду
% nroff -ms myfile | mo        # Нажмите Backspace, чтобы стереть er
% nroff -ms myfile | more      # Введите re

Редактор команд позволяет вносить более общие изменения (например, добавлять или удалять слова или символы в любом месте строки). Дополнительные сведения см. в главе 7.

Повторение команд с помощью цикла

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

% foreach f (intro.ms reference.ms tutorial.ms)
? gtbl $f | groff -ms | lpr
? end

После ввода строки foreach оболочка меняет приглашение, собирая тело цикла. После ввода строки end она выполняет цикл. Каждый раз, когда оболочка проходит цикл, она присваивает переменной (в данном случае f) следующее слово в списке в скобках.

Вы можете ввести более одной команды между строками foreach и end. Кроме того, слова в скобках не обязательно должны быть именами файлов. В приведенном ниже примере слова используются в качестве суффиксов для создания имен файлов в запросах к архивам списков рассылки tcsh:

% foreach suf (9311 9312 9401 9402 9403 9404)
? echo "Sending request for log$suf"
? echo "get tcsh log$suf" | mail listserv@mx.gw.com
? end

Если вы решите, что не хотите выполнять цикл, введите символ прерывания.

Создание сочетаний клавиш

Вероятно, у вас есть определённые привычки, связанные с командами, которые вы выполняете. Если да, то вы можете сэкономить время, используя алиасы — короткие имена для часто используемых команд или последовательностей команд. Например, я часто использую команды more и history. Добавив следующие строки в мой файл ~/.cshrc, я могу запускать команды, просто набирая m и h:

alias m more
alias h history

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

% pr файл | lpr -Plwe
% pr -m list1 list2 | lpr -Plwe
% sort names | pr -5 | lpr -Plwe

Алиас — назовём его print — позволяет делать то же самое, но с меньшим количеством нажатий клавиш. Добавьте этот алиас в файл ~/.cshrc:

alias print 'pr \!* | lpr -Plwe'

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

% print file
% print -m list1 list2
% sort names | print -5

Обратите внимание, что определение print заключено в кавычки. Это потому, что оно содержит специальные символы, такие как | и !. Символ \!* в определении расширяется до любых указанных аргументов. (Аргументы алиаса обычно добавляются в конец команды, до которой расширяется алиас. Использование \!* позволяет размещать аргументы в любом месте.)

В главе 8, Использование алиасов для создания шорткатов, показано еще множество примеров алиасов.

Использование подстановки команд

Предположим, вы работаете над программой и решили изменить имя переменной с wdCnt на wordCount везде, где она используется. Вы можете использовать следующую команду, чтобы определить, в каких исходных файлах C (.c) и заголовочных файлах (.h) используется эта переменная[3]:

% grep -l wdCnt *.[ch]

Но вместо того, чтобы просто выводить полученные имена файлов в терминале, вы можете указать оболочке выполнить команду grep и передать имена напрямую в редактор. Для этого просто заключите команду в обратные кавычки[4]:

% vi `grep -l wdCnt *.[ch]`

Оболочка видит обратные кавычки и выполняет подстановку команды: она заменяет команду grep на её вывод (после замены новых строк на SPACEы, чтобы вывод стал одной строкой). Таким образом, вы можете редактировать нужные файлы, не зная заранее, какие именно. Если команда grep выводит имена файлов defs.h, fileio.c, main.c, utils.c и vars.c, команда vi эквивалентна следующей:

% vi defs.h fileio.c main.c utils.c vars.c

Подстановка команд полезна в сочетании с другими возможностями оболочки, такими как история команд. Например, вы можете выполнить только команду grep, чтобы понять, в каких файлах содержится имя переменной, а затем использовать !! для его повторения в команде vi:

% grep -l wdCnt *.[ch]
% vi `!!`
vi `grep -l wdCnt *.[ch]`

Подстановка команд — это метод, который на первый взгляд может показаться эзотерическим и малопригодным. Однако это настолько полезный метод построения командных строк, что он должен стать неотъемлемой частью ваших навыков работы с оболочкой. Дополнительные примеры и дальнейшее обсуждение см. в главе 12, Использование команд для создания аргументов.

  1. grep отображает строки в файлах, которые соответствуют шаблону. grep -l отображает только имена файлов, содержащих совпадающие строки.
  2. Обратная кавычка — это символ `, а не символ '.

Навигация по файловой системе

Если вы не планируете выполнять всю работу в одном каталоге, вы будете создавать каталоги для организации файлов и перемещаться между ними в зависимости от того, над чем вы работаете в данный момент. В следующих разделах описано, как оболочка упрощает выполнение повторяющихся операций по изменению местоположения и присвоению имен каталогам, в которые вы хотите переместиться. Глава 13, Навигация по файловой системе, содержит дополнительную информацию о перемещении по файловой системе.

Если вам нужно выполнить команды в двух разных каталогах, полезно знать, как легко переключаться между ними. В tcsh можно вернуться в последний каталог, в котором вы были, следующим образом:

% cd -

Последовательные команды cd - переключают между текущим и предыдущим каталогами.

Другой способ (который работает как в csh, так и в tcsh) использует команду pushd вместо cd. Команда pushd с аргументом в виде имени каталога сохраняет текущий каталог в стеке памяти, а затем переключается на новый каталог. Команда pushd без аргумента меняет текущее местоположение на запомненное.

Предположим, я хочу переключаться между ~/Database/Parts и ~/Database/Suppliers. Я могу сделать это сложным способом, например так:

% cd ~/Database/Parts
% cd ../Suppliers
% cd ../Parts
% cd ../Suppliers
% cd ../Parts
и т. д.

pushd упрощает эту задачу, как показано ниже. Первая команда меняет текущий каталог на ~/Database/Parts. Вторая команда сохраняет текущий каталог в стеке и меняет его на каталог ~/Database/Suppliers:

% cd ~/Database/Parts
% pushd ../Suppliers
~/Database/Suppliers ~/Database/Parts

Теперь можно легко перемещаться между двумя каталогами:

% pushd                          # Вернёмся к ~/Database/Parts
~/Database/Parts ~/Database/Suppliers
% pushd                          # Вернёмся к ~/Database/Suppliers
~/Database/Suppliers ~/Database/Parts
% pushd                          # Вернёмся к ~/Database/Parts
~/Database/Parts ~/Database/Suppliers
и т. д.

Команда pushd показывает, какие каталоги запоминает оболочка, отображая текущий каталог слева. Это позволяет вам ориентироваться в пространстве при перемещении. Если вы забыли, что находится в стеке каталогов, используйте команду dirs. Она отображает стек без изменения вашего местоположения.

popd удаляет текущий каталог из стека и возвращает вас в местоположение, указанное в предыдущей записи.

Позвольте оболочке находить каталоги за вас

Чтобы перейти в каталог, обычно нужно указать путь. Предположим, что структура каталогов вашей учётной записи показана на рисунке 3-1.

Рисунок 3-1. Простое дерево каталогов

Если вы хотите последовательно перейти в каталоги tokenscan, shell, Mail и Books, вы можете использовать следующие команды:

% cd ~/Projects/Programs/tokenscan
% cd ~/Projects/Books/shell
% cd ~/Mail
% cd ~/Projects/Books

Вы можете сделать то же самое, но проще, указав оболочке подсказки по поиску каталогов. Если вы зададите переменной cdpath в оболочке список каталогов, оболочка будет использовать их в качестве начальных точек при поиске каталогов при использовании команды cd. Эта функция позволяет вводить более короткие имена при перемещении по каталогам. Например, вы можете задать cdpath следующим образом в файле ~/.cshrc:

set cdpath = (~ ~/Projects ~/Projects/Books ~/Projects/Programs)

Затем вы можете сократить предыдущий набор команд cd следующим образом:

% cd tokenscan
% cd shell
% cd Mail
% cd Books

cdpath также работает с командой pushd.

Использование строки приглашения

Строка приглашения по умолчанию обычно выглядит как % или >, что довольно скучно. В этом разделе показаны некоторые способы сделать строку приглашения более информативной.

Вы можете задать строку приглашения, присвоив значение переменной prompt. Следующая команда устанавливает в качестве приглашения строку Yeah?:

set prompt = "Yeah? "

Кавычки не позволяют оболочке интерпретировать ? как символ шаблона имени файла и позволяют включить в приглашение SPACE в конце.

Лучше всего экспериментировать с командами set prompt из командной строки. Когда вы найдёте нужную вам подсказку, поместите её в файл ~/.cshrc, заменив все существующие настройки подсказок. (Вам также следует удалить все команды set prompt, которые вы найдёте в файле ~/.login.)

Один простой способ сделать подсказку более полезной — включить в неё номер текущей команды, вставив \! в строку подсказки:


% set prompt = "\! -> "     # Установить в качестве подсказки номер команды, за которым следует ->
44 -> echo hello
hello
45 -> date
Fri Apr 28 23:32:21 CDT 1995
46 ->

Подсказка, включающая номер команды, упрощает использование команды !n для повторения команд, которые все еще видны на экране, поскольку вы также можете видеть номера команд.

Использование последовательностей форматирования подсказок tcsh

Интерпретация \! в строке приглашения — это единственное, что может делать csh. tcsh может делать это и многое другое, используя специальные последовательности форматирования в строке. Некоторые из возможностей показаны ниже. (В справочной странице tcsh перечислены все доступные последовательности.)

Добавьте часы в строку приглашения

Последовательность %t отображает время. %p отображает время, включая секунды. (%T и %P похожи, но используют 24-часовой формат.) Чтобы отобразить день, месяц или год, используйте %D, %W или %y. Например:

set prompt = "[%W/%D/%y %P] % "
Сделайте так, чтобы ваша подсказка выделялась

Вы можете использовать %B, %U или %S, чтобы включить выделение жирным шрифтом, курсивом или выделением текста (инверсное видео) в вашей подсказке. Используйте %b, %u или %s, чтобы отключить эти атрибуты выделения. Например:

set prompt = "%BYou rang?%b "       # Используйте подсказку, выделенную жирным шрифтом

Подсказка с выделением облегчает поиск предыдущих строк команд на загруженном экране, особенно если вы используете окно терминала с возможностью прокрутки назад.

Укажите своё текущее местоположение в командной строке

Пока вы активно работаете в каталоге, обычно не так сложно запомнить, где вы находитесь. Однако если вы ненадолго покидаете терминал или работаете в среде с несколькими окнами, которая позволяет одновременно входить в несколько учётных записей, легко потерять представление о своём текущем местоположении.

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

csh позволяет указывать текущее местоположение в командной строке, но это сложнее. Соответствующие команды приведены в главе 14, Следите за тем, где вы находитесь. В этой главе также описано, как можно отображать информацию о местоположении в заголовках окон или значках, если вы используете оконную систему.

Использование управления заданиями

Задание — это любая запущенная вами команда, которая не завершена. Оболочка предоставляет средство управления заданиями, которое позволяет временно останавливать (приостанавливать) команды и возобновлять их позже, а также перемещать команды между текущим и фоновым режимами.

Почему управление заданиями полезно

Управление заданиями предоставляет вам форму мультиплексирования заданий, которая позволяет управлять выполнением команд и переключаться между заданиями:

Базовое управление заданиями

Попробуйте приведенные ниже примеры, чтобы понять, как работает управление заданиями. В таблице 3-4 перечислены команды, которые мы будем использовать. Я предполагаю, что CTRL-Z и CTRL-C — это ваши символы приостановки и прерывания. (Если вы используете другие настройки терминала, внесите соответствующие изменения. Дополнительные сведения о настройках терминала см. в главе 5, Настройка терминала.)

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

Таблица 3-4. Основные команды управления заданиями
Команда Действие команды
CTRL-Z Остановить задание на переднем плане
CTRL-C Прервать (завершить) задание на переднем плане
fg Вывести остановленное или фоновое задание на передний план
bg Переместить остановленное задание в фоновый режим
kill % Убить (завершить) остановленное или фоновое задание
stop % Остановить фоновое задание
jobs Отобразить текущий список заданий
Остановка задания

Чтобы остановить команду, выполняемую на переднем плане, введите CTRL-Z:

% sleep 1000             # Запустить задание на переднем плане
CTRL-Z                  # Приостановить задание
Stopped                  # Оболочка сообщает, что задание остановлено

Перенос задания в фоновый режим

bg переносит остановленное задание в фоновый режим и запускает его снова в процессе:

% bg                        # Перенести задание в фоновый режим
[1] Running  sleep 1000 &   # Оболочка сообщает номер задания и его новый статус

Оболочка выводит командную строку задания, переносимого в фоновый режим (& указывает на выполнение в фоновом режиме), вместе с номером задания и новым статусом.

Вывод задания на передний план

fg выводит текущее задание на передний план (fg работает для остановленных или фоновых заданий). Когда вы выводите задание на передний план, оболочка выводит командную строку задания:

% fg                  # Вывести задание на передний план
sleep 1000            # Оболочка выводит командную строку

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

Завершение задания

Команде sleep 1000 потребуется некоторое время для завершения, поэтому завершите ее, нажав CTRL-C.

Другой способ завершить задание — остановить его с помощью CTRL-Z, а затем использовать команду kill. Чтобы увидеть, как работает этот процесс, выполните следующие команды:

% sleep 1000               # Запустить задание на переднем плане
CTRL-Z                    # Приостановить задание
Остановлено                # Оболочка сообщает, что задание остановлено
% kill %                   # Завершить задание
[1] Terminated sleep 1000  # Оболочка сообщает, что задание завершено

Сочетание CTRL-Z плюс kill полезно, когда вы сталкиваетесь с программой, которая перехватывает CTRL-C, чтобы предотвратить прерывания. В отличие от fg и bg, для kill требуется аргумент, указывающий задание. Аргумент % означает «текущее задание». (Если у вас несколько заданий, может быть трудно определить, какое из них является текущим; это не проблема, если задание только одно.)

kill работает и с фоновыми заданиями:

% sleep 1000 &                # Запустить фоновый процесс
[1] 2948                      # Оболочка сообщает номер и ID процесса
% kill %                      # Завершить процесс
[1] Terminated   sleep 1000   # Оболочка сообщает, что процесс завершён

Если оболочка не выводит сообщение о том, что процесс был завершён, попробуйте следующее:

% kill -9 %

kill -9 отправляет процессу неотлавливаемый сигнал завершения.

Остановка фонового процесса

Есть два способа остановить фоновый процесс. Во-первых, можно использовать команду stop. Как и kill, stop требует аргумента:

% sleep 1000 &                      # Запустить фоновый процесс
[1] 2987                            # Оболочка сообщает номер и ID процесса
% stop %                            # Остановить фоновый процесс
[1] Suspended (signal) sleep 1000   # Оболочка сообщает, что процесс остановлен

В качестве альтернативы вы можете использовать fg, чтобы вывести фоновый процесс на передний план, а затем приостановить его с помощью CTRL-Z. Обычно для этого нужно меньше печатать.

Работа с несколькими процессами

Предположим, что несколько процессов остановлены или работают в фоновом режиме. Используйте команду jobs, чтобы отобразить информацию о них. Например, в процессе получения и сборки программного обеспечения я могу составить список процессов, который будет выглядеть так:

% jobs
[1]    Stopped     ftp 144.92.43.19
[2]  - Stopped     vi README
[3]  + Stopped     vi reference.ms
[4]    Running     groff -ms reference.ms | lpr
[5]    Running     make >& make.out

На выходе отображается командная строка, связанная с каждым заданием, а также номер и статус задания. Задания 1, 2 и 3 остановлены и ожидают перезапуска. Задания 4 и 5 выполняются в фоновом режиме.

Команды управления заданиями из предыдущих примеров работали с текущим заданием. Поскольку в этих примерах одновременно выполнялось только одно задание, указание задания не было проблемой. Если у вас несколько заданий остановлены или выполняются в фоновом режиме, команды, которые вы используете для управления ими, те же (fg, bg, kill и stop), но часто вам нужно более четко указать, к какому заданию вы хотите обратиться.

Приведённые ниже примеры иллюстрируют различные способы указания заданий. Они относятся к выводам команды jobs, показанным выше.

Указание текущего задания

Спецификаторы заданий начинаются с символа %. % сам по себе относится к текущему заданию. Как правило, текущее задание — это последнее остановленное задание. Если вы не уверены, какое задание является текущим, воспользуйтесь командой jobs, чтобы это выяснить. Текущее задание будет иметь + рядом со столбцом состояния. В нашем примере это задание 3, поэтому следующие команды повлияют на второе задание vi:

% fg %
% bg %
% stop %
% kill %
Обращение к заданиям по номеру

Вы можете обращаться к заданиям по номеру. Например, %4 относится к заданию 4, команде groff, а %1 относится к заданию 1, команде ftp. Если мы решим завершить первую задачу и возобновить выполнение второй на переднем плане, мы можем использовать следующие команды:

% kill %4
% fg %1
Обращение к задачам по имени

Вы можете использовать строку для указания задачи. %str указывает на задачу с командной строкой, начинающейся со str; %?str указывает на задачу с командной строкой, содержащей str:

% fg %ftp              # Вывести команду ftp на передний план
% kill %gr             # Завершить работу groff
% fg %?REA             # Продолжить просмотр файла README
% stop %?out           # Завершить работу команды make

Если при использовании спецификатора задания %?str оболочка выдаёт сообщение No match, попробуйте поставить обратную косую черту перед символом ?:

% fg %\?REA
% stop %\?out
Сочетания клавиш для управления заданиями

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

Что делать, если вы видите сообщение «There are stopped jobs» (Есть остановленные задания)

При использовании управления заданиями легко забыть об остановленном задании (или даже не знать, что оно у вас есть, если вы случайно нажали CTRL-Z). Когда это происходит и вы пытаетесь выйти из системы, оболочка предупреждает вас о том, что есть задачи, которые вы, возможно, захотите выполнить:

% logout
There are stopped jobs.

Если вы видите это сообщение, у вас есть несколько вариантов:

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

Часть II
Повышение эффективности работы

Глава 4
Файлы запуска оболочки

В этой главе:

При входе в систему ваша оболочка работает не в вакууме. На ее поведение влияет ваша рабочая среда, которая включает:

Все вышеперечисленное инициализируется в файлах запуска оболочки.

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

Файлы запуска и завершения работы

При входе в систему ваша оболочка настраивает среду, читая два файла с именами .cshrc и .login из вашего домашнего каталога. Если файлы существуют, оболочка выполняет их команды перед отображением первой строки приглашения.

tcsh читает файлы запуска немного иначе, чем csh. Если в вашем домашнем каталоге есть файл с именем .tcshrc, tcsh читает его вместо .cshrc. Чтобы не повторять уточняющую фразу в этом руководстве, следует понимать, что ссылки на .cshrc означают «.tcshrc, если он существует и вы используете tcsh, .cshrc в противном случае». Любые исключения из этого соглашения будут понятны из контекста.

В этой главе я предполагаю, что вы находитесь в своём домашнем каталоге, и называю файлы запуска .cshrc и .login. В других местах я не делаю таких предположений и называю файлы ~/.cshrc и ~/.login, чтобы явно указать, что они находятся в вашем домашнем каталоге.

Ваша оболочка может также считывать общесистемные файлы запуска до того, как будут прочитаны файлы запуска в вашем домашнем каталоге. Не все версии оболочки считывают файлы системного уровня, и имена этих файлов различаются в зависимости от системы (например, они могут называться /etc/csh.cshrc и /etc/csh.login). Системные администраторы иногда используют эти файлы для стандартизации рабочей среды для разных учётных записей. Вы можете либо оставить эти настройки, либо использовать такие команды, как unset, unsetenv, unalias и uncomplete, чтобы удалить их.

Если в вашем домашнем каталоге есть файл .logout, оболочка считывает команды из него при выходе из системы. Ваша оболочка также может считывать общесистемный файл, например /etc/csh.logout, прежде чем считывать файл в вашем домашнем каталоге. Как и /etc/csh.cshrc и /etc/csh.login, /etc/csh.logout может использоваться системными администраторами.

Знакомство с .cshrc и .login

Если вы не знакомы с файлами .cshrc и .login, вам следует запустить команду ls в своём домашнем каталоге, чтобы узнать, существуют ли они. Укажите параметр -a («показать все»), так как команда ls обычно не показывает точечные файлы (файлы с именами, начинающимися с точки):

% ls -a
.           .cshrc       .mailrc     Letters     Papers      calendar    src
..          .exrc        .msgsrc     Mail        Projects    junk        tmpfile
.Xdefaults  .login       .plan       Misc        bin         mbox

Если у вас нет файлов .cshrc и .login, вы можете создать их с помощью любого текстового редактора, но, скорее всего, стандартные версии .cshrc и .login были установлены в вашем домашнем каталоге при создании учётной записи. Стандартные версии могут выглядеть примерно так:

% more .cshrc
if ($?prompt) then
    set prompt = "% "
    set history = 20
    set cdpath = ( ~ ~/Projects ~/Papers )
endif
alias h history
alias ll ls -l
alias print 'pr \!* | lpr'
set path = ( /bin /usr/bin /usr/ucb ~/bin . )
% more .login
tset -I -Q
stty erase ^h intr ^c
setenv TERM vt1OO
biff y

Ничего страшного, если вы не поймёте содержимое .cshrc и .login при первом взгляде на них, но в конечном итоге вам следует стремиться к этому. Если вы видите в своих файлах автозагрузки команды, с которыми вы не знакомы, поищите их в указателе этого руководства, прочтите их описания или спросите о них знающего пользователя вашей системы. Кроме того, полезно посмотреть, как другие люди используют свои файлы автозагрузки. Попросите более опытных пользователей предоставить вам копии их файлов и попросите их объяснить те части, которые вы не понимаете. Возможно, вы даже решите скопировать некоторые из найденных вами файлов в свои собственные.

Изменение .cshrc и .login

Вы можете сразу изменить свою рабочую среду, введя команды в командной строке, но внесённые таким образом изменения исчезнут, как только вы выйдете из системы. Чтобы убедиться, что команда запускается при каждом входе в систему, добавьте её в один из файлов автозагрузки вашей оболочки с помощью текстового редактора, например vi или emacs. Изменения вступят в силу при следующем входе в систему.

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

Использование переменных

Переменные управляют поведением командной строки, включая отображение подсказок, где искать команды и следует ли вести список истории. Оболочка понимает два вида переменных: переменные оболочки и переменные среды. Как правило, переменные оболочки используются внутри оболочки и влияют на ее собственную работу, тогда как переменные среды доступны программам, запускаемым из оболочки. В приложении B, Кратком справочнике csh и tcsh, перечислены несколько полезных переменных каждого типа.

Переменные можно задавать непосредственно в командной строке, но обычно вы задаёте их в файлах запуска, чтобы либо переопределить значения по умолчанию, предоставляемые оболочкой, либо определить переменные, которые оболочка оставляет неопределёнными.

Переменные оболочки

Используйте команду set для определения переменных оболочки. Некоторым переменным не требуется явное значение; они действуют просто благодаря своему существованию:

set notify           # Включить немедленное уведомление о завершении работы
set ignoreeof        # Отключить выход из системы с помощью CTRL-D

Для других переменных требуется значение:

set history = 20             # Заставьте оболочку запоминать последние 20 команд
set prompt = "% "            # Задайте приглашение командной строки
set fignore = (.o .bak)      # Укажите суффиксы, которые следует игнорировать при завершении имени файла
set term = vtlOO             # Укажите тип терминала

Значения, содержащие SPACEы или другие специальные символы, следует заключать в кавычки, как в приведенной выше команде set prompt. Значения, состоящие из нескольких строк, следует заключать в скобки, как в команде set fignore.

Вам не нужно ставить SPACEы вокруг знака =, отделяющего имя переменной от значения. Если вы это сделаете, SPACEы должны быть с обеих сторон:

set history= 20              # Неверно
set history =20              # Неверно
set history=20               # Верно
set history = 20             # Верно

Я предпочитаю использовать SPACEы, потому что так команды set более понятны.

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

Используйте setenv для определения переменных среды:

setenv TERM vtlOO                  # Укажите тип терминала
setenv PAGER /usr/ucb/more         # Укажите предпочитаемый пейджер вывода
setenv EDITOR /usr/bin/emacs       # Укажите предпочитаемый редактор

Обратите внимание, что, в отличие от set, в setenv нет знака = между именем переменной и её значением.

Переменные среды отличаются от переменных оболочки тем, что, хотя их значения известны оболочке, эти значения также доступны программам, которые вы запускаете из оболочки. (Например, если ваш почтовый клиент позволяет вам открыть редактор для редактирования сообщения, он может определить, какой редактор использовать, обратившись к переменной среды EDITOR.) Имена переменных среды обычно пишутся заглавными буквами. Использование заглавных букв необязательно, но это полезное соглашение, которое помогает отличать переменные среды от переменных оболочки.

Изучение и использование значений переменных

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

% set                        # Отобразить все переменные оболочки
% setenv                     # Отобразить все переменные среды

В некоторых системах есть команды env или printenv, которые действуют как setenv.

Ссылка на имя переменной записывается как $name или ${name}. Вы можете просмотреть отдельные значения переменных с помощью echo:

% echo $TERM $path             # Отображение типа терминала и пути поиска команд
% echo ${TERM} ${path}         # Это эквивалентно приведенной выше команде

Если вы попытаетесь использовать несуществующую (т. е. не определенную) переменную, оболочка выдаст сообщение:

% echo $junk
junk: Undefined variable.

Если переменная относится к имени файла, вы можете применить один из модификаторов, указанных в таблице 4-1, чтобы извлечь различные части значения. Модификаторы применяются с помощью синтаксиса $name:m или ${name:m}:

% set xyz = /etc/csh.cshrc
% echo root $xyz:r extension $xyz:e head $xyz:h tail $xyz:t
root /etc/csh extension cshrc head /etc tail csh.cshrc
% echo root ${xyz:r} extension ${xyz:e) head ${xyz:h} tail ${xyz:t}
root /etc/csh extension cshrc head /etc tail csh.cshrc
Таблица 4-1: Модификаторы переменных
Модификатор Описание
r Корень значения (всё, кроме расширения после точки)
e Расширение значения (суффикс после точки)
h Начало значения (всё, кроме последнего компонента пути)
t Конец значения (последний компонент пути)
Отключение переменных

Если вы хотите отключить переменную оболочки или среды, используйте unset или unsetenv:

unset mail                      # Отключить уведомление о новой почте
unsetenv DISPLAY                # Отключить спецификацию дисплея X
Сделать переменные оболочки tcsh доступными только для чтения

В tcsh переменную оболочки можно сделать доступной только для чтения с помощью команды set -r. Переменная, доступная только для чтения, не может быть изменена с помощью команды set или удалена с помощью команды unset:

% set -r xyz
% set xyz
set: $xyz is read-only.
% unset xyz
unset: $xyz is read-only.

Системный администратор может использовать переменные, доступные только для чтения, чтобы поместить неизменяемую переменную в рабочую среду всех пользователей tcsh. На загруженном сайте, где линии терминалов и другие ресурсы ограничены, в общесистемный файл запуска можно добавить следующую строку, чтобы выводить из системы неактивных пользователей через час бездействия:

set -r autologout = 60        # Выводить из системы неактивных пользователей через 60 минут
Парные переменные

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

set term = vtlOO                       # Это также устанавливает переменную среды TERM
setenv TERM vtlOO                      # Это также устанавливает переменную оболочки term

path и PATH — ещё одна такая пара, хотя их значения указываются в разных форматах:

set path = (~/bin /usr/bin /bin /usr/ucb)
setenv PATH /usr/staff/dubois/bin:/usr/bin:/bin:/usr/ucb

При установке path или PATH оболочка автоматически преобразует значение в формат, необходимый для другой переменной.

Организация файлов автозагрузки

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

Вы можете обнаружить, что небольшая перестановка ваших загрузочных файлов вполне уместна, даже если вы никогда их не изменяли. Стандартные загрузочные файлы, которые поставщики поставляют для использования при создании новых учетных записей, часто содержат команды не в том файле. Например, переменные истории и приглашения иногда задаются в .login, а не в .cshrc.

Оболочки для входа и без входа в систему

Оболочка, которую вы получаете при входе в систему, — это (естественно) оболочка входа в систему, и она считывает файлы .cshrc и .login. Существуют также оболочки, не связанные с входом в систему, например те, которые выполняют команды, реализованные в виде скриптов csh, или те, которые выполняют команды оболочки !command из таких программ, как mail, more или vi. Оболочки, не связанные с входом в систему, считывают только .cshrc.

Следовательно, если команда должна выполняться при каждом запуске оболочки, она обычно должна быть указана в .cshrc. Команды, которые нужно запускать только при входе в систему, должны быть в .login. Примеры таких команд:

Интерактивные и неинтерактивные оболочки

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

Интерактивные и неинтерактивные оболочки имеют несколько разные возможности и поведение. Например, только интерактивные оболочки выводят приглашение или позволяют использовать управление заданиями и историю команд. Команды, применимые только к интерактивным оболочкам, можно пропустить, чтобы сократить время запуска:

if ($?prompt) then
    set prompt = "% "
    set notify
    set history = 20
    set ignoreeof
    .
    .
    .
endif

Оператор if проверяет, имеет ли переменная prompt значение, чтобы различать интерактивные и неинтерактивные оболочки[5]. Этот тест работает, потому что интерактивные оболочки присваивают prompt значение по умолчанию перед чтением любых файлов запуска, а неинтерактивные оболочки — нет. Команды, которые имеют отношение только к интерактивным оболочкам, могут быть размещены между if и endif, а неинтерактивные оболочки будут их игнорировать.

Не устанавливайте подсказку до тех пор, пока не проверите её значение по умолчанию. Если вы добавите команду set prompt в файл .cshrc перед оператором if, который проверяет, установлена ли подсказка, проверка всегда будет успешной, независимо от того, является ли оболочка интерактивной!

  1. SPACE после if обязателен. Некоторые версии csh выдают ошибку, если его нет.
Использование команды source

Если вы добавляете много информации в файлы автозагрузки, они могут стать довольно длинными. Один из способов уменьшить беспорядок — сгруппировать похожие команды в отдельные файлы, а затем ссылаться на них с помощью команды source. Например, вы можете поместить свои алиасы и привязки клавиш в файлы .aliases и .bindings в вашем домашнем каталоге. Затем вы можете ссылаться на эти файлы в .cshrc следующим образом:

source ~/.aliases                   # Процесс определения алиасов
source ~/.bindings                  # Процесс привязки клавиш

Ещё одним преимуществом такого подхода является то, что если вы измените один из отдельных файлов, вы сможете использовать его без повторной обработки всего файла .cshrc.

Защита команд, доступных только в tcsh, от csh

Даже если tcsh является вашей оболочкой входа в систему, csh может время от времени читать ваш файл .cshrc. Некоторые программы реализованы как csh-скрипты, поэтому .cshrc может быть прочитан, когда csh вызывается для выполнения скрипта. Следовательно, вам нужно быть осторожным при размещении команд, специфичных для tcsh, в вашем файле .cshrc. Если csh попытается выполнить команды tcsh, такие как bindkey или complete, произойдет ошибка.

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

if ($?tcsh) then
    bindkey -e
    complete cd 'p/l/d/'
    .
    .
    .
endif

Другой подход заключается в использовании .tcshrc для tcsh и .cshrc для csh. Простой способ создать .tcshrc - скопировать .cshrc и добавить любые команды, специфичные для tcsh. Однако позже, возможно, потребуется внести изменения в оба файла. В качестве альтернативы вы можете создать версию .tcshrc, которая, по сути, выполняет все команды в .cshrc, а затем также выполняет определенные команды, специфичные для tcsh. Схема, показанная ниже, позволяет выполнить эту задачу:

source ~/.cshrc             # Получите все стандартные команды csh из cshrc
bindkey -e                  # Теперь выполните команды, специфичные для tcsh
complete cd 'p/l/d/'
.
.
.

Файл .logout

Если в вашем домашнем каталоге есть файл .logout, оболочка считывает его при выходе из системы. Этот файл можно использовать для хранения команд, которые вы хотите выполнить по завершении работы, например clear, для очистки экрана.

.logout не обрабатывается, если вы используете команду login для повторного входа без предварительного выхода из системы.

Глава 5
Настройка терминала

В этой главе:

Вы взаимодействуете с оболочкой с помощью клавиатуры, поэтому важно знать, какие клавиши выполняют специальные функции для управления терминалом[6]:

В этой главе объясняется, как использовать команду stty, чтобы узнать, каковы ваши ключевые настройки, и как их изменить, если они вам не нравятся. Ваш терминал — это инструмент, которым управляете вы, а не он вами.

  1. Под терминалом я подразумеваю комбинацию клавиатуры и дисплея. Дисплеем может быть экран реального терминала, окно xterm, работающее под X, или экран, управляемый программой эмуляции терминала, работающей на микрокомпьютере.

Определение настроек вашего терминала

stty отображает текущие настройки вашего терминала. Его параметры варьируются от системы к системе, но по крайней мере одна из следующих командных строк должна выдавать выходные данные, идентифицирующие несколько важных функций управления терминалом и символы, которые вы вводите для их выполнения:

% stty -a
% stty all
% stty everything

В выводе ищите что-то вроде этого:

erase kill werase rprnt flush lnext susp intr quit step  eof
^?    ^U   ^W     ^R    ^O    ^V    ^Z   ^C   ^\   ^S/^Q ^D

Или этого:

intr = ^c; quit = ^\; erase = ^?; kill = ^u; eof = ^d; start = ^q;
step = ^s; susp = ^z; rprnt = ^r; flush = ^o; werase = ^w; lnext = ^v;

Слова erase, kill и т. д. указывают на функции управления терминалом. Последовательности ^c указывают на символы, выполняющие эти функции. Например, ^u и ^U обозначают CTRL-U, а ^? обозначает символ DEL.

Что означают настройки

На вашем терминале есть много специальных клавиш; наиболее важные из них выполняют функции erase, kill, werase, rprnt, lnext, stop, start, intr, susp и eof.

стирания, удаления, повторного стирания, печати, перехода на следующую строку, остановки, запуска, прерывания, приостановки и конца файла.
Настройки редактирования строк

Символы erase, kill, werase, rprnt и lnext позволяют выполнять простое редактирование текущей командной строки. (Некоторые системы не поддерживают символы werase и rprnt.) Если вы используете tcsh, у вас также есть доступ к встроенному редактору общего назначения, описанному в главе 7, Редактор командной строки tcsh.

erase

Чтобы удалить последний символ, введите символ erase (стирания). Обычно для стирания используются клавиши CTRL-H (также известная как BACKSPACE) или DEL. Терминалы различаются по предоставляемым возможностям. Часто есть клавиша BACKSPACE, которая вызывает нажатие CTRL-H, и/или клавиша DEL (или DELETE, или RUBOUT), которая вызывает нажатие клавиши DEL. На некоторых клавиатурах есть только клавиша BACKSPACE или клавиша DEL, но вы можете запрограммировать клавишу для вывода нужного вам символа.

kill

Символ kill (убить строку) полностью удаляет строку, которую вы вводите, чтобы вы могли начать заново. Обычно для символа kill используются сочетания клавиш CTRL-U или CTRL-X.

werase

Символ werase (стереть слово) стирает последнее слово в командной строке одним нажатием клавиши. Если вам нужно стереть несколько символов, использование символа werase часто быстрее, чем многократное нажатие клавиши erase (т.е. стирание по одному символу). Обычно для символа werase используется сочетание клавиш CTRL-W. (Если вы используете tcsh, сочетание клавиш CTRL-W может не удалять слова. Вместо этого попробуйте ESC DEL или ESC CTRL-H.)

rprnt

Символ rprnt (повторная печать) повторно отображает командную строку, которую вы вводите, — это полезно, если вывод попадает в середину командной строки (например, из-за фонового процесса или из-за помех на линии при подключении к модему). Перепечатав командную строку, вы можете увидеть, что вы ввели. Символ rprnt обычно представляет собой сочетание клавиш CTRL-R.

Если вы работаете на компьютере с системой UNIX System V, не верьте документации, в которой говорится, что эта управляющая функция называется reprint. Команда stty на самом деле распознает rprnt.

lnext

Символ lnext (literal-next) позволяет вводить в командную строку символы, которые в противном случае интерпретировались бы немедленно. Например, в tcsh символ TAB запускает автозаполнение имени файла. Чтобы ввести в команду символ TAB, сначала введите символ lnext. Символ lnext обычно вызывается нажатием CTRL-V.

Настройки управления процессами

Символы stop, start, intr, susp и eof позволяют управлять запущенными процессами.

stop, start

Символ stop останавливает вывод на ваш терминал до тех пор, пока вы не введёте символ start. Эти символы помогают вам управлять выводом на ваш терминал[7]. Символы stop и start обычно представляют собой CTRL-S и CTRL-Q. На некоторых терминалах есть клавиша «scroll lock» (блокировка прокрутки), которая попеременно генерирует CTRL-S и CTRL-Q.

intr

Если вы вводите команду, которая выполняется слишком долго или выдаёт слишком много вывода, вы обычно можете прервать её. Обычно для символа intr используется сочетание клавиш CTRL-C.

Если команда, которую вы хотите прервать, отключает CTRL-C, чтобы сделать себя невосприимчивой к прерываниям, попробуйте приостановить команду с помощью CTRL-Z. Затем завершите её следующим образом:

% kill %                # Попробуйте сначала
% kill -9 %             # Попробуйте, если простое завершение не работает

Символ kill отличается от команды kill; первый стирает текущую командную строку, а вторая завершает работающую программу.

susp

Если вы хотите переместить команду в фоновый режим (например, если она выполняется долго), сначала приостановите её, введя символ susp (приостановки) (обычно CTRL-Z). Затем возобновите выполнение команды в фоновом режиме следующим образом:

% bg
eof

Символ eof сигнализирует о завершении файла процессу, который в данный момент считывает данные с терминала. Если этим процессом является оболочка, она завершает работу. Символ eof обычно представляет собой комбинацию клавиш CTRL-D. Чтобы предотвратить завершение работы оболочки с помощью CTRL-D, установите переменную ignoreeof в вашем файле ~/.cshrc:

set ignoreeof

После этого для завершения работы оболочки вам нужно будет явно ввести exit или logout.

  1. Лучшей альтернативой является перенаправление вывода команды в more.

Изменение настроек терминала

Если вам не нравятся настройки вашего терминала, используйте stty, чтобы изменить их:

% stty function char

function — это имя управляющей функции, а char — соответствующий символ. Например, следующая команда устанавливает символ прерывания на CTRL-C:

% stty intr ^c

Вы можете использовать ^c или ^C; stty понимает их как CTRL-C.

Чтобы убедиться, что ваш терминал настроен правильно при каждом входе в систему, добавьте соответствующие команды stty в файл ~/.login, после любых команд tset или reset, которые могут уже быть в этом файле. Не забудьте снова войти в систему, чтобы изменения вступили в силу. (Информацию о файле ~/.login см. в главе 4, Файлы запуска оболочки.)

В следующих двух разделах описано, как решать некоторые распространённые проблемы, связанные с символами erase и kill (стирания и удаления) строк. Если вам кажется, что ваш терминал ведёт себя странно даже после настройки с помощью stty, посмотрите файл ~/.login другого пользователя или обратитесь к справочной странице stty. Возможно, вы найдёте что-то специфическое для вашей системы, что нужно настроить.

Проблемы с вводом символов # и @

Во многих системах # и @ по умолчанию являются символами erase и kill (стирания и удаления). Эти символы пришли из времён жёстких терминалов и больше не используются. Если в вашем файле ~/.login не заданы символы стирания и удаления, вам может быть сложно вводить # и @. Задайте символ kill (удаления) в файле .login, как показано ниже; обычно выбирают CTRL-U:

stty kill ^u

Задайте символ erase (стирания), как описано в следующем разделе.

Как заставить терминал использовать клавишу Backspace

При вводе команд все допускают ошибки, поэтому важно знать, как удалять ошибки при вводе. Обычно для этого нужно нажать клавишу BACKSPACE или DEL. Если у вас не получается удалить символ с помощью клавиши BACKSPACE, вероятно, вы и система не договорились о том, каким должен быть символ удаления. Если при попытке удалить символы вы видите ^H, значит, ваш терминал отправляет CTRL-H (другое название клавиши BACKSPACE). Добавьте следующее в файл ~/.login, чтобы система интерпретировала CTRL-H как символ стирания:

stty erase ^h           # Установите символ стирания на CTRL-H

Если при попытке стереть вы видите ^?, значит, ваш терминал отправляет DEL. Добавьте следующее в ~/.login, чтобы система интерпретировала DEL как символ стирания:

stty erase '^?'           # Установите символ стирания на DEL

Обратите внимание, что ^? следует заключать в кавычки как '^?' или использовать ^\? для отключения специального значения, которое символ ? имеет для оболочки в качестве оператора сопоставления шаблонов.

Ваш терминал перестал работать?

Если ваш терминал заблокирован, возможно, вы случайно нажали CTRL-S, что останавливает вывод на терминал. Чтобы снова запустить его, нажмите CTRL-Q. Даже если CTRL-S не является проблемой, CTRL-Q не причинит вреда.

Ваш терминал также может выйти из строя, даже если обычно он работает правильно. Такая ситуация может возникнуть по нескольким причинам:

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

Глава 6
Использование истории команд

В этой главе:

Пользователи оболочки часто вводят полностью каждую команду, которую они хотят выполнить. Это неэффективно и не нужно, поскольку оболочка позволяет вам вести список истории и вызывать команды из списка для их повторения. Таким образом, вы можете вводить команды быстрее, затрачивая меньше времени на ввод текста. В качестве примера, следующие две последовательности команд эквивалентны (они взяты из сеанса, в ходе которого пункты повестки дня редактировались и проверялись на форматирование, а затем отправлялись по почте и распечатывались). Разница между последовательностями заключается в том, что первая не использует механизм истории, в то время как вторая использует.

Последовательность 1:

% tbl agenda-apr | nroff -ms
% tbl agenda-apr | nroff -ms | more
% vi agenda-apr
% tbl agenda-apr | nroff -ms > agenda-apr.txt
% mail -s 'Here is the April agenda' tom < agenda-apr.txt
% mail -s 'Here is the April agenda' marian < agenda-apr.txt
% lpr agenda-apr.txt

Последовательность 2:

% tbl agenda-apr | nroff -ms
% !! | more
% vi !^
% tbl !$ | nroff -ms > !$.txt
% mail -s 'Here is the April agenda' tom < !$
% ^ton^marian
% lpr !$

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

В tcsh редактор команд также имеет доступ к вашему списку хронологии. Редактор предоставляет другой метод получения и повторного запуска команд. Чтобы узнать, как использовать этот метод, — что весьма рекомендуется сделать — ознакомьтесь с главой 7, Редактор командной строки tcsh.

Список истории

Чтобы использовать механизм history, вы должны установить переменную оболочки history. Если history включена, оболочка запоминает ваши последние команды в списке истории, чтобы вы могли использовать их позже. Добавьте в файл ~/.cshrc следующую строку, чтобы сохранять записи о последних 20 командах:

set history = 20

При желании вы можете использовать значение, отличное от 20. Если в вашем файле ~/.login есть команда set history, удалите её и вместо этого поместите команду в файл ~/.cshrc.

Просмотр истории

Каждая введённая вами команда — это событие, которое сохраняется в списке истории. Чтобы посмотреть, что находится в списке, используйте команду history. В csh каждая строка вывода, отображаемая командой history, содержит номер события и команду, которой соответствует это событие:

% history
683  cd ~/src/rtf
684  more Imakefile
685  make World >& make.world
686  more make.world
687  make clean
688  cd ..
689  tar cf rtf.tar rtf
690  gzip rtf.tar
691  ftp 144.92.43.19
692  uuencode rtf.tar.gz rtf.tar.gz > rtf.tar.gz.uu
693  mail -s 'New RTF distribution' rtf-list < rtf.tar.gz.uu
694  rm rtf.tar.gz*
и т. д.

В tcsh строки истории также содержат отметку времени.

Вывод команды history становится довольно длинным, если вы задаёте большое значение переменной history. Вы можете передать вывод в команду more или указать числовой аргумент, определяющий количество отображаемых строк:

% history | more               # Показать историю с помощью пейджера
% history 5                    # Показать последние пять команд

tcsh и большинство версий csh понимают обе команды, показанные выше. В некоторых версиях csh одна из команд не работает, и в этом случае вам нужно использовать ту, которая работает.

Использование команд из истории

Используйте символ ! для перехода к событию в списке истории. Оболочка видит !, определяет по следующим за ним символам, какое событие вы хотите использовать, выполняет подстановку из истории в командной строке, а затем выполняет команду. Чтобы вы были в курсе, оболочка выводит на экран полученную команду перед её выполнением. Вот простой пример использования !!, оператора «повторить предыдущую команду»:

% date                              # Введите команду
Tue Mar 7 13:01:25 CST 1995         # Вывод команды
% !!                                # Повторите команду
date                                # Оболочка выводит полученную команду
Tue Mar 7 13:01:32 CST 1995         # Вывод команды

Полный синтаксис для ссылки на историю выглядит следующим образом:

!event:words:modifiers

Это полный набор, но большая его часть необязательна. На практике ссылки на историю, как правило, простые, такие как !! для повторения предыдущей команды или !$ для повторения ее последнего аргумента. Вот что означают части ссылки на историю:

event

Событие (команда), на которое вы хотите сослаться.

words

Какие слова выбрать из команды, слова необязательны; если они отсутствуют, выбирается вся команда.

modifiers

Как изменить выбранное событие или слова, модификаторы необязательны; если они отсутствуют, событие или слова воспроизводятся без изменений.

В следующих разделах более подробно описаны части ссылок на историю.

Спецификаторы событий

Ссылка на историю начинается со спецификатора, указывающего, какое событие вас интересует. Вы можете ссылаться на события несколькими способами (см. таблицу 6-1).

Таблица 6-1: Спецификаторы событий в истории
Спецификатор Описание
!! Предыдущая команда
!n Команда n
!-n n-я по счёту команда
!str Последняя команда, начинающаяся со str
!?str? Последняя команда, содержащая str
!# Текущая командная строка, набранная до сих пор

Примеры каждого из спецификаторов событий в истории приведены ниже.

Вызов предыдущей команды

Самый простой оператор истории — ! ! , который повторяет вашу последнюю команду. Предположим, вы время от времени проверяете очередь печати, чтобы узнать, выполнено ли задание на печать. Введите команду проверки очереди один раз, а затем используйте ! ! для её повторения:

% lpq -Plwb
% !!
lpq -Plwb
% !!
lpq -Plwb
и т. д.
Обращение к командам по номеру

Если вы знаете номер события команды, вы можете обратиться к нему по этому номеру. Например, !12 повторяет команду 12. Если вы не знаете номер события, выполните команду history, чтобы просмотреть список истории. Чтобы снизить нагрузку на память и уменьшить необходимость в выполнении команды history, вы можете настроить отображение номеров событий в командной строке. Например, вы можете настроить командную строку в ~/.cshrc, как показано ниже:

set prompt = "\! % "

При каждом отображении приглашения оболочка заменяет \! на текущий номер события. Эта функция позволяет одним взглядом увидеть номера событий для всех недавних команд, которые все еще отображаются на экране, чтобы вам было проще их вспомнить.

События можно указать по их расположению относительно текущей команды. !-2 относится ко второй от конца команде, !-3 относится к третьей от конца и так далее. (!-1 допустимо, но !! эквивалентно этому и проще в наборе.)

Если я редактирую файл и отправляю его cindy, а потом понимаю, что мне нужно внести ещё одно изменение, я могу повторно отредактировать файл, сообщить ей, что готовится ещё одна копия, и отправить файл снова, вот так:

% vi schedule                      # Отредактировать файл
% mail cindy < schedule            # Отправить его по почте
% !-2                              # Отредактировать файл еще раз
vi schedule
% mail -s 'I goofed' cindy         # Сказать cindy, что готовится еще одна копия
That copy of the schedule was
bad. Toss it; I'll send another.
CTRL-D
% !-3                              # Отправить файл еще раз
mail cindy < schedule

Поскольку обозначение !-n является относительным, оно позволяет вам легко выполнять набор событий повторно. В следующем примере используется !-2 для чередования команд редактирования и форматирования:

% vi doc.ms                     # Отредактировать документ
% nroff -ms doc.ms | more       # Проверить, правильно ли он отформатирован
% !-2                           # Повторить команду редактирования
vi doc.ms
% !-2                           # Повторить команду форматирования
nroff -ms doc.ms | more
% !-2                           # Повторить команду редактирования
vi doc.ms
% !-2                           # Повторить команду форматирования
nroff -ms doc.ms | more
и т. д.
Обращение к событиям по имени команды или подстроке

Вы можете обращаться к событиям по строкам, а не по номерам, и оболочка будет искать в обратном направлении по списку истории указанную вами команду. !str повторяет последнюю команду, которая начинается с str. !?str? повторяет последнюю команду, которая содержит str. Если второй ? является последним символом командной строки, его можно не указывать.

Предположим, что последняя часть вашей истории выглядит так:

347  who
348  wc -l data
349  cal 1776
350  emacs calendar

В этом случае !w повторяет команду wc, а !wh повторяет команду who. !ca повторяет команду cal, но !?ca повторяет команду emacs, так как это самая последняя команда, содержащая ca.

Форма !?str часто является самым простым способом выбрать команду, которая отличается от других только текстом в конце строки (например, именем файла). Обычно вы знаете, какое имя файла хотите использовать, но не обязательно знаете номер события команды, которая использовала это имя файла.

Обращение к текущему событию

!# относится к текущему событию — это означает «всё, что вы ввели в командной строке до сих пор». !# используется в основном в сочетании с указателями слов, которые выбирают более ранние части текущей командной строки, поэтому обсуждение !# отложено до раздела «Повторение слов из текущей команды», который появится позже в этой главе.

Ошибочные ссылки на историю

Если вы вводите ссылку на историю, которую оболочка не понимает, она выдаёт сообщение:

% !xyz
xyz: Event not found.

Такой ответ обычно означает, что ссылка некорректна или что команда, которую вы хотите вспомнить, слишком старая и была удалена из списка истории более новыми командами.

Добавление текста к вызванным событиям

При вызове команды вы можете добавить к ней новый текст, сформировав новую команду:

% sort mydata | uni            Посмотреть уникальные строки в отсортированном выводе
uni: Contend not found         Упс, неправильно набрал uniq
% !!q                          Добавьте q к команде uni
sort mydata | uniq
% !! -d                        Теперь добавьте -d, чтобы просмотреть повторяющиеся строки
sort mydata I uniq -d

Или, например, вы запускаете команду diff для сравнения двух файлов, но вывод прокручивается за пределы экрана, потому что различия более обширные, чем вы ожидали. Повторите команду и добавьте канал, чтобы направить вывод через пейджер, как показано ниже:

% diff prog.c~ prog.c              # Сравнить предыдущую и текущую версии prog.c
% !! | more                        # Попробовать ещё раз, используя more
diff prog.c~ prog.c | more

Если вы запускаете команду, а затем решаете, что хотите запустить её ещё раз и сохранить вывод, вы можете добавить перенаправление вывода вместо канала:

% nroff -ms document.ms              # Запустить форматирование
% !! > document.txt               # Повторить, сохраняя вывод
nroff -ms document.ms > document.txt

В приведённых выше примерах текст добавляется в конец команд. Вы также можете добавить текст в начало команды, как показано ниже:

% uptime                  # Проверка состояния локального компьютера
% r!!                     # Проверка состояния компьютеров в локальной сети
ruptime
Разрешение неоднозначных дополнений

Иногда добавление текста в ссылку на историю создаёт новую ссылку, которая не выполняет нужные вам действия. Например, если вы хотите просмотреть data, а затем data2, следующая ссылка не сработает:

% more data                # Посмотреть data
% !m2                      # Попробовать посмотреть data2, используя !m и добавив 2
m2: Event not found.

В таких случаях изолируйте ссылку от следующего текста с помощью фигурных скобок, как показано ниже:

% more data
% !{m}2
more data2

Обозначения слов

Команды состоят из слов. Слово — это имя команды, аргумент, оператор или специальный символ, например ; или &. Если я введу следующую команду:

% grep "Baton Rouge" addresses|sort>output&

оболочка разбивает команду на слова и нумерует их следующим образом:

0     1              2          3  4     5  6       7
grep  "Baton Rouge"  addresses  |  sort  >  output  &

Слова нумеруются, начиная с 0, поэтому имя команды обычно является словом 0, а первый аргумент обычно является словом 1.

Механизм истории позволяет ссылаться на любое слово из любой команды в списке истории с помощью обозначений слов. Однако чаще всего вам, вероятно, захочется повторить слова из предыдущей команды, используя обозначения, показанные в таблице 6-2.

Таблица 6-2: Обозначения слов в истории для предыдущей команды
Обозначение Описание
!* Повторить все аргументы из предыдущей команды
!^ Повторить первый аргумент из предыдущей команды
!$ Повторить последний аргумент из предыдущей команды

!* полезно, если вы хотите выполнить команду для файлов, которые вы использовали в предыдущей команде:


% more file1 file2 file3          # Просмотреть несколько файлов
% pr !* | lpr                     # Распечатать те же файлы
pr file1 file2 file3 | lpr

Или если вы хотите повторно выполнить команду с дополнительным флагом между именем команды и аргументами:

% grep error file1 file2           # Найти слово
% grep -i !*                       # Выполнить тот же поиск без учёта регистра
grep -i error file1 file2

Использование !$ для повторения последнего аргумента полезно при выполнении серии операций с одним и тем же файлом. Чтобы просмотреть, отредактировать, распечатать и отправить файл по электронной почте, можно сделать что-то вроде этого:

% more checklist
% vi !$
vi checklist
% lpr !$
lpr checklist
% mall -s '!$ enclosed' dave < !$
mail -s 'checklist enclosed' dave < checklist

!^ удобно использовать для повторения первого аргумента предыдущей команды:

% pr myfile | lpr
% vi !^
vi myfile

Общий синтаксис для повторения слов из команды выглядит так:

!event:words

В этом синтаксисе event обозначает, какое событие нужно вспомнить, а :words определяет нужные вам слова из этого события. В таблице 6-3 перечислены различные формы, которые могут принимать слова. Ниже приведены несколько примеров использования этих форм:

!vi:*             # Все аргументы последней команды vi
!-2:$             # Последний аргумент предпоследней команды
!?edu?:^          # Первый аргумент последней команды, содержащий edu
!!:2-4            # Аргументы со 2-го по 4-й предыдущей команды
Таблица 6-3: Обозначение слов в справочной истории
Обозначение Описание
0 Слово 0 (название команды)
n Слово n (аргумент n)
^ Слово 1
$ Последнее слово
m-n Слова с m по n
-n Слова с 0 по n
m- Слова с m по последнее слово (но не включая его)
- Слова с 0 по последнее слово (но не включая его)
m* Слова с m по последнее слово
* Слова с 1 по последнее или ничего, если аргументов нет
% После спецификатора события !?str? следует слово, соответствующее str
Сокращенное обозначение слова

Иногда можно сокращать обозначения слов, используя следующие правила:

Рассмотрев эти правила, вы можете увидеть происхождение !*, !^ и !$: на самом деле это сокращенные формы !!:*, !!:* и !!:$. Например, !!:* становится !:* по первому правилу и !* по второму.

Согласно странице руководства csh, вы можете убрать двоеточие перед обозначениями слов, начинающимися с -, но лучше этого не делать. Например, !:-3 таким образом становится !-3, но !:-3 (слова до 3-го из предыдущей команды) — это ссылка на историю с совершенно другим значением, чем !-3 (третья по счёту команда). Аналогично, !:- становится !- без двоеточия. Однако многие версии оболочки не поддерживают !-.

Использование обозначений слов

Спецификаторы событий истории иногда выглядят немного странно, и могут выглядеть еще более странно, когда вы начинаете добавлять к ним словарные обозначения. Таким образом, вполне понятно, если вы изначально скептически относитесь к тому, действительно ли словоуказатели очень полезны или их легко выучить. На самом деле, это и то, и другое, и когда вы сами начнете вводить словоуказатели, вы обнаружите, что довольно быстро к ним привыкаете.

!*, !^ и !$ — это самые простые в использовании и запоминании обозначения, а в следующих разделах описаны некоторые практические применения некоторых других обозначений. Чтобы привыкнуть к использованию обозначений в своей работе, обращайте внимание на ситуации, в которых вы планируете использовать аргументы, недавно использованные в других командах. Хорошее практическое правило: если вам нужно повторить ряд аргументов или длинные аргументы, например полные пути, вы можете с успехом использовать обозначения слов.

Повторение набора слов

Обозначение диапазона m-n позволяет указать любой набор смежных слов:

% grep history chOO ch06 appb
% vi !:2-4
vi chOO ch06 appb

Вы можете опустить m, n или оба параметра в обозначении диапазона. Если опустить m, диапазон начинается со слова 0. Если опустить n, диапазон заканчивается словом перед последним. Таким образом, !:- — это быстрый способ повторить всё, кроме последнего слова команды. Этот метод полезен, если вы хотите указать другое последнее слово, как показано ниже:

% nroff -ms intro.ms | more       Форматирование и просмотр документа
% !:- lpr                         Теперь отправьте его на принтер
nroff -ms intro.ms | lpr
% grep -i trials method.ms        Поиск в файле по строке
% !:- results.ms                  Поиск в другом файле по той же строке
grep -i trials results.ms

m-$ — допустимый диапазон (от слова m до последнего слова), но m* означает то же самое и его проще набирать.

Повторение слов из текущей команды

!# относится ко всему, что находится слева от него в текущей командной строке. Поэтому вы часто можете создать новый аргумент на основе уже введённого вами аргумента, используя !# и обозначение слова. Например, вы можете легко создать резервную копию файла, используя !#^ для повторения первого аргумента текущей команды:

% cp observations !#^.bak

Наиболее распространённые обозначения слов с использованием !# перечислены в таблице 6-4.

Таблица 6-4: Обозначения слов для текущей команды
Обозначение Описание
!#* Все аргументы
!#^ Первый аргумент
!#$ Последний аргумент
!#:n Аргумент n

!# наиболее полезно для аргументов, похожих друг на друга. Следующие пары команд эквивалентны, но во второй команде каждой пары используется !# для экономии времени при наборе:

% gtbl ref-manual | groff -ms > ref-manual.ps
% gtbl ref-manual | groff -ms > !#^.ps

% diff Instructions Instructions.old
% diff Instructions !#^.old

Модификаторы событий

После обозначения слова (или указания события, если обозначения нет) вы можете добавить модификатор события:

!event:words:modifiers
!event:modifiers

Модификаторы изменяют способ обработки события. Если вы добавите :p к ссылке на событие, событие будет выведено на экран (отображено), но не выполнено. Другие модификаторы каким-то образом изменяют текст вызываемого события или слова. Например, добавление :s/a/b заменяет a на b в командной строке. Эта функция полезна для исправления ошибок или изменения аргумента. Возможные модификаторы перечислены в таблице 6-5.

Таблица 6-5: Модификаторы ссылок на историю
Модификатор Описание
p Напечатать результирующую команду, не выполняя ее
s/old/new/ Выполнить подстановку, заменив old на new
& Повторить предыдущую подстановку s
r Корень имени файла (все, кроме расширения после точки)
e Расширение имени файла (суффикс после точки)
h Начало пути (все, кроме последнего компонента)
t Конец пути (последний компонент)
q Слова в кавычках (предотвращает расширение шаблона имени файла)
x Как q, но разбивает на слова через SPACE
u Сделать первую строчную букву прописной (только tcsh)
l Сделать первую заглавную букву строчной (только tcsh)
g Применить модификатор после g глобально к каждому слову
a Применять модификатор (модификаторы) после a как можно больше раз к слову. Если используется с g, a применяется ко всем словам (только tcsh)

Модификаторы сильно различаются с точки зрения их общей полезности. Я считаю, что :s и :p являются наиболее ценными. В следующих разделах обсуждаются :p, модификатор подстановки :s (наряду с модификаторами повторения :g, :a и :&) и модификаторы имени файла :r, :e, :h и :t.

Вызов команд без их выполнения

:p вызывает отображение события, но не выполняет его. Эта функция полезна, если вы не уверены, что ссылка указывает на нужную вам команду. Когда вы нашли нужную команду, используйте !! для её повторения:

% !r:p                           Вспомнить последнюю команду rlogin, не выполняя её
rm *.ps                          Упс, это не то!
% !rl:p                          Попробовать ещё раз, указав больше параметров команды
rlogin ruby.ora.com -l dubois    Да, это то, что нужно
% !!                             Выполнить команду
rlogin ruby.ora.com -l dubois

Разумное использование :p поможет вам избежать проблем. Если бы вы ввели первую !r в предыдущем примере без :p, вы бы снова выполнили команду rm. Это может быть не очень хорошей идеей. (Если вы перешли в другой каталог после того, как изначально выполнили команду rm, вы можете удалить файлы, которые хотите сохранить.)

Модификаторы подстановки

Механизм истории оболочки поддерживает простую форму редактирования команд, в которой используется модификатор :s/old/new/, где old — это строка, которую нужно изменить, а new — это то, чем её нужно заменить. Например, я могу отформатировать файл на экране, а затем на принтере следующим образом:

% tbl Install-instructions | nroff -ms | more
% !:s/more/lpr/
tbl Install-instructions | nroff -ms | lpr

Эффект модификатора :s аналогичен команде подстановки s в sed или ex, хотя есть некоторые различия. Например, old — это буквальная строка, а не шаблон, и в большинстве версий оболочки в строке old не должно быть SPACEов.

Сокращённая форма ^old^new^ заменяет old на new в предыдущей команде, как показано ниже:

% more Install-instructions
% ^more^vi^
vi Install-instructions

Форма ^old^new проще в наборе, но позволяет изменить только самую последнюю команду. Форма :s/old/new длиннее, но более универсальна. Её можно использовать с любой командой из списка истории. В обеих формах, если последний разделитель (/ или ^) является последним символом в командной строке, его можно опустить.

^old^new можно использовать по-разному:

Убедитесь, что old предоставляет достаточно контекста, чтобы однозначно указать, что вы хотите изменить. В противном случае вы можете изменить не то, что нужно:

% sort data-a              Сортировка data-a
% ^a^b                     Теперь сортировка data-b
sort dbta-a                Упс, я перепутал a (нужно было использовать ^-a^-b)
sort: can't open dbta-a: No such file or directory

:s/old/new может делать все то же, что и ^old^new, но с чуть большим количеством нажатий клавиш. А поскольку вы используете :s с указанием события, вы можете использовать его для изменения любой команды в списке истории, а не только самой последней:

% vi myfile.ms                    Отредактируйте файл
% nroff -ms myfile.ms | more      Отформатируйте его и просмотрите результат
% !vi:s/e/e2                      Измените myfile.ms на myfile2.ms в команде vi
vi myfile2.ms
% !-2:s/more/lpr                  Измените more на lpr во второй с конца команде
nroff -ms myfile.ms | lpr

Помните о следующих свойствах модификатора :s, чтобы в полной мере использовать его возможности:

  1. Некоторые версии csh могут не поддерживать это.
  2. Некоторые версии csh могут не поддерживать это.
Повторение замены

Модификатор :s изменяет только первый экземпляр старого в выбранной команде или словах:

% echo a a a a
a a a a
% !:s/a/b
echo b a a a
b a a a
% echo !:2-3:s/a/b
echo b a
b a

Чтобы выполнить замену во всех словах, содержащих слово old, используйте вместо этого :gs. Следующая последовательность кодирует и отправляет по электронной почте два файла. Аргумент имени файла необходимо изменить глобально, поскольку он встречается более одного раза в каждой команде:

% uuencode file1 file1 > file1.uu             Закодируйте первый файл
% !:gs/1/2                                    Закодируйте второй файл
uuencode file2 file2 > file2.uu
% mail -s 'Here is file1' boss < file1.uu     Отправьте первый файл
% !:gs/1/2
mail -s 'Here is file1' boss < file2.uu       Отправьте второй файл

Хотя :gs выполняет подстановку в каждом слове команды, она заменяет old только один раз в каждом слове, даже если оно встречается в слове несколько раз:

% echo abc abcabc
% !:gs/abc/def
echo def defabc

В tcsh вы можете заставить подстановку выполняться как можно чаще, добавив a к модификатору :gs:

% echo abc abcabc
% !:ags/abc/def
echo def defdef

Однако будьте осторожны: модификатор, например :as/x/xx, вызывает цикл подстановки, как показано ниже:

% echo x
x
% !:as/x/xx
Substitution buffer overflow.
Повторение предыдущей подстановки

:& повторяет предыдущую подстановку :s/old/new или ^old^new.

% grep -i expenditure file1        Поиск строки в file1
% !:s/e1/e2                        Поиск той же строки в file2
grep -i expenditure file2
% pr file1 | lpr                   Распечатать file1
% !:&                              Повторить замену для печати file2
pr file2 | lpr

:g& повторяет предыдущую замену глобально.

Проверка замены

:p полезно с ^old^new, :s, :gs, :as и :ags для подавления выполнения команды. Эта форма позволяет проверить эффект от подстановок. Она также позволяет внести несколько изменений в команду перед её выполнением. При использовании :p с модификатором подстановки не забудьте добавить конечный разделитель ^ или /, как показано ниже:

% uuencode memo.aug24 memo.aug24 > junk1     Закодируйте первый файл
% !:gs/24/25/:p                              Измените входной файл и команду печати
uuencode memo.aug25 memo.aug25 > junk1
% ^1^2^:p                                    Измените выходной файл и команду печати
uuencode metno.aug25 memo.aug25 > junk2
% !!                                         Теперь команда в порядке; выполните её
uuencode metno.aug25 memo.aug25 > junk2
Модификаторы имён файлов

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

Таблица 6-6: Модификаторы имён файлов
Имя файла :h(начало) :t(конец) :r(корень) :e(расширение)
/usr/include/stdio.h /usr/include stdio.h /usr/include/stdio h
/usr/spool/lpd /usr/spool lpd /usr/spool/lpd empty
intro.ms empty intro.ms intro ms
README empty README README empty

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

% vi myprog.c
% make !$:r
make myprog

% diff introduction.ms.old !#^:r
diff introduction.ms.old introduction.ms

% more /usr/local/include/etm.h
% more !$:h/nio.h
more /usr/local/include/nio.h

Вы также можете применять модификаторы имён файлов к ссылкам на переменные. Например, чтобы извлечь последний компонент текущего рабочего каталога, используйте $cwd:t или ${cwd:t}.

Сохранение истории во время сеансов входа в систему

Если вы зададите переменную оболочки savehist, оболочка сохранит строки истории в ~/.history при выходе из системы и перечитает их при следующем входе в систему. Эта функция обеспечивает непрерывность истории при входе в систему, чтобы вы могли повторно использовать команды из предыдущего сеанса.

Если вы зададите savehist без указания значения, будет сохранен весь список истории:

set history = 20
set savehist

Если вы присваиваете значение savehist, оно должно быть не больше значения переменной history оболочки:

set history = 20
set savehist =10

Если вы используете несколько логинов с одним и тем же именем пользователя (например, в среде с несколькими окнами), история, считываемая при каждом новом логине, берется из сеанса, из которого вы вышли в последний раз.

Глава 7
Редактор командной строки tcsh

В этой главе:

tcsh предоставляет редактор командной строки общего назначения. С его помощью вы можете извлекать и повторять команды из списка истории (как есть или в изменённом виде), а также изменять текущую команду. Например, если вы заметили опечатку в начале строки, вы можете переместить курсор в начало и исправить ошибку, вместо того чтобы стереть команду и ввести её заново.

Редактор команд чрезвычайно полезен, но поначалу может показаться сложным. Когда вы впервые попробуете его, не пытайтесь выучить всё сразу. Вместо того чтобы пытаться запомнить десятки команд редактирования за один сеанс, начните с нескольких. Как только вы освоитесь, выучите ещё несколько. Не торопитесь, но продолжайте — с практикой использование редактора станет для вас всё более естественным, и вы будете рады, что потратили время на его изучение.

Эта глава состоит из следующих разделов:

Редактирование команды

Вы можете использовать редактор для внесения сколь угодно сложных изменений в команду, но процесс редактирования концептуально довольно прост. Введите новую команду (или извлеките команду из списка истории); если она нуждается в изменении (например, для создания аналогичной команды или исправления ошибок), отредактируйте команду, добавив новый текст или изменив существующий; затем нажмите RETURN, чтобы выполнить её.

Чтобы извлечь команды из списка истории, перемещайтесь вверх и вниз с помощью CTRL-P (предыдущая команда) и CTRL-N (следующая команда)[10]. Одна из основных команд, которую вам следует немедленно запомнить, — это CTRL-P RETURN для повторения предыдущей команды. Существуют также команды редактирования, которые выполняют поиск в списке истории; эти команды описаны ниже.

Если вы не хотите выполнять команду в буфере редактирования, отмените её, введя символ прерывания (обычно CTRL-C). Другой способ «отменить» команду — ввести в буфер редактирования другую команду, например, с помощью CTRL-P.

Курсор не обязательно должен находиться в конце строки для выполнения или отмены команды.

У вас не будет списка истории, из которого можно было бы вызывать команды, если вы не задали переменную оболочки history. Инструкции см. в главе 6, Использование истории команд.

  1. Стрелки вверх и вниз выполняют те же действия, что и CTRL-P и CTRL-N.

Привязки клавиш для команд

Вы управляете интерфейсом редактора команд, выбирая набор привязок клавиш — ассоциаций между клавишами и командами редактирования. Существует два набора привязок, созданных по образцу команд редактирования, используемых в GNU emacs и vi[11]. Если набор привязок, который вам нужен, отличается от набора, используемого tcsh по умолчанию на вашем компьютере[12], убедитесь, что вы всегда получаете нужные привязки, добавив соответствующую команду bindkey в ~/.cshrc или ~/.tcshrc:

bindkey -e           # Выберите привязки emacs
bindkey -v           # Выберите привязки vi

Вы также можете использовать команды bindkey для добавления, удаления или изменения отдельных привязок. См. раздел «Изучение и изменение привязок клавиш» далее в этой главе.

bindkey — это команда, специфичная для tcsh. Если вы используете ~/.cshrc, а не ~/.tcshrc, защитите все команды bindkey от csh, следуя инструкциям в разделе «Организация файлов автозагрузки» в главе 4, Файлы автозагрузки оболочки.

  1. tcsh учитывает постоянно возникающий конфликт между emacs и vi и решает его, предоставляя пользователям обоих редакторов одинаковые возможности.
  2. Привязки emacs обычно (но не обязательно) используются по умолчанию. Попробуйте выполнить эту команду:

    % echo $version

    Если в результате вы видите слово vi, tcsb по умолчанию использует привязки vi на вашем хосте.

Получение информации о привязках клавиш

При использовании любого набора привязок вам иногда придётся просматривать функции определённых клавиш по мере изучения командного редактора. Следующая команда будет полезна:

% bindkey

bindkey без аргументов отображает текущие привязки клавиш, показывая ассоциации между нажатиями клавиш и именами команд редактирования. Нажатия клавиш отображаются с помощью ^X для CTRL-X, ^[ для ESC, ^? для DEL и \nnn для символа ASCII с восьмеричным кодом nnn. Обозначение \nnn непонятно; обычно это нажатия клавиш, которые вы вводите, удерживая нажатой клавишу META. Обычно проще понять, что делает META-c, если поискать команду, связанную с ESC c (отображается как ^[c), потому что META-c и ESC c выполняют одну и ту же команду.

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

% bindkey -l
Сравнение режима emacs и режима vi

Если вы знакомы с emacs или vi, то соответствующий набор привязок команд редактора, как правило, похож на то, к чему вы уже привыкли, поэтому вы можете просто использовать привязки, наиболее похожие на тот редактор, который вы предпочитаете. В противном случае вы можете попробовать оба набора и выбрать тот, который вам больше нравится. Следующее сравнение описывает некоторые общие различия между привязками emacs и vi:

Режим редактирования emacs

В этом разделе описано, как редактировать команды с помощью привязок emacs. Не забудьте выбрать эти привязки, прежде чем использовать любую из описанных ниже команд:

% bindkey -e

В режиме Emacs команды редактирования всегда активны. Любой символ, который не является командой редактирования, вставляется в буфер редактирования. В противном случае команда выполняется.

Команды перемещения курсора Emacs

Прежде чем вносить изменения (например, добавлять или удалять текст), вы перемещаете курсор. Команды перемещения курсора emacs приведены в таблице 7-1.

Таблица 7-1: Команды для перемещения курсора (режим emacs)
Команда Описание
CTRL-B Переместить курсор назад (влево) на один символ
CTRL-F Переместить курсор вперёд (вправо) на один символ
ESC b Переместить курсор назад на одно слово
ESC f Переместить курсор вперёд на одно слово
CTRL-A Переместить курсор в начало строки
CTRL-E Переместить курсор в конец строки

Попробуйте выполнить эти команды, введя следующую строку и оставив курсор в конце:

% echo this is a conmand 

Затем введите приведенные ниже команды редактирования; вы увидите, как перемещается курсор, как показано на рисунке:

% echo this is a conmand          # Нажмите CTRL-B
% echo this is a conmand          # Нажмите ESC b
% echo this is a conmand          # Нажмите CTRL-A
% echo this is a conmand          # Нажмите CTRL-F
% echo this is a conmand          # Нажмите ESC f
% echo this is a conmand          # Нажмите CTRL-E
Команды для редактирования в emacs

Чтобы добавить новые символы в текущую команду, просто введите их. Чтобы удалить символы, слова или даже всю строку, используйте команды, показанные в таблице 7-2. Изменения происходят в позиции курсора.

Таблица 7-2: Команды удаления текста (режим Emacs)
Команда Описание
DEL или CTRL-H Удалить символ слева от курсора
CTRL-D Удалить символ под курсором
ESC d Удалить слово
ESC DEL или ESC CTRL-H Удалить слово в обратном направлении
CTRL-K Удалить от курсора до конца строки
CTRL-U Удалить всю строку

Попробуйте команды редактирования, введя следующую строку и оставив курсор в конце:

% echo My typing skilks are not amazing. 

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

% echo My typing skilks are not amazing.     # Нажмите ESC b
% echo My typing skilks are amazing.         # Нажмите ESC CTRL-H
% echo My typing skilks axe amazing.         # Нажмите CTRL-B несколько раз
% echo My typing skils axe amazing.          # Нажмите CTRL-H
% echo My typing skills axe amazing.         # Нажмите l

Команды удаления, отличные от тех, которые удаляют отдельные символы, помещают удаленный текст в буфер вырезания. Чтобы переместить текст обратно в командную строку, используйте CTRL-Y. Таким образом, вы можете легко изменить порядок частей командной строки, поскольку текст не нужно возвращать в исходное положение. Вы можете вставить текст в командную строку несколько раз. (Удалённые символы не помещаются в буфер вырезания, так как вы можете повторно ввести символ, чтобы восстановить его.)

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

Если вы хотите повторить команду несколько раз, часто проще указать количество повторений, чем вводить команду несколько раз. Чтобы повторить команду n раз, введите перед ней ESC n, где n - некоторое число. Например, ESC 10 CTRL-B перемещает курсор на десять символов назад, а ESC 3 ESC d удаляет три слова. Если команда не может быть повторена столько раз, сколько вы укажете, tcsh повторяет ее столько раз, сколько возможно.

Другой способ повторить команду, если она состоит из одного нажатия клавиши, — просто удерживать клавишу нажатой.

Команды emacs для поиска в истории

Режим emacs позволяет искать в списке истории команду, которую вы хотите отредактировать. Это часто быстрее, чем возвращаться по одной строке за раз с помощью CTRL-P или стрелки вверх. Вы можете указать командную строку либо по префиксу строки, либо по строке, которая встречается в строке.

Чтобы использовать поиск по префиксу, введите первую часть командной строки, затем нажмите ESC p. Префикс может содержать символы шаблона имени файла. tcsh просматривает вашу историю в обратном направлении в поисках команды, начинающейся с префикса, и извлекает её в буфер редактирования. Если это не та команда, которая вам нужна, нажмите ESC p ещё раз, чтобы найти следующее совпадение. ESC n работает аналогично, но поиск выполняется в прямом направлении. Вы можете использовать ESC p и ESC n вместе, чтобы перемещаться между соответствующими командами.

Поиск по строкам выполняется с помощью двух команд, которые позволяют выполнять инкрементальный поиск в стиле emacs. По умолчанию эти команды не привязаны ни к каким клавишам, поэтому перед их использованием необходимо привязать их к какой-либо клавише или последовательности клавиш. Например, чтобы привязать их к CTRL-X p и CTRL-X n, добавьте следующие команды в файл ~/.cshrc:

bindkey "^xp" i-search-back
bindkey "^xn" i-search-fwd

Эти две команды позволяют выполнять поиск в обратном или прямом направлении, чтобы при вводе строки командная строка, содержащая эту строку, извлекалась в буфер редактирования. Например, предположим, что ваша история выглядит так:

unexpand note.txt > note2.txt
man cal
cal 1066

Когда вы вводите CTRL-X p, редактор команд выводит bck: в качестве подсказки и готовится к поиску команд в обратном направлении. Если вы затем последовательно вводите a, n и d, tcsh извлекает команды в буфер редактирования в следующем порядке:

cal 1066                          # Команда соответствует a
man cal                           # Команда соответствует an
unexpand note txt > note2 txt     # Команда соответствует and

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

Нажмите ESC, чтобы завершить инкрементальный поиск и отредактировать отображаемую в данный момент команду. Или просто нажмите RETURN, чтобы выполнить команду.

Использование клавиш со стрелками в режиме Emacs

Вы можете использовать клавиши со стрелками для редактирования в режиме emacs. Стрелка вверх и стрелка вниз перемещают курсор вверх и вниз по списку истории, как CTRL-P и CTRL-N. Стрелка влево и стрелка вправо перемещают курсор влево и вправо на один символ, как CTRL-B и CTRL-F.

Режим редактирования vi

В этом разделе описано, как редактировать команды с помощью привязок vi. Обязательно выберите эти привязки, прежде чем пробовать какие-либо из описанных ниже команд:

% bindkey -v

Привязки vi предоставляют возможности, аналогичные привязкам emacs, но у них есть свои отличительные особенности. Конечно, сочетания клавиш для выполнения команд иногда отличаются; более существенное отличие заключается в том, что редактирование с помощью привязок vi на самом деле включает в себя два режима — как и в самом vi. В режиме вставки vi символы помещаются в буфер редактирования по мере их ввода. В командном режиме vi символы интерпретируются как команды редактирования. Например, если вы вводите x в режиме вставки, x помещается в командную строку в позиции курсора. Если вы введёте x в командном режиме, символ под курсором будет удалён.

Поскольку два режима vi ведут себя по-разному, важно знать правила переключения между ними:

Двойные режимы могут показаться запутанными, но они настолько неотъемлемая часть режима редактирования vi, что быстро становятся привычными. Некоторые из наиболее распространённых команд редактирования работают в любом режиме, что помогает избежать путаницы. Например, CTRL-P и CTRL-N перемещают вверх и вниз по списку истории, а RETURN и CTRL-C соответственно выполняют и отменяют текущую команду независимо от того, в каком режиме вы находитесь.

Использование режима вставки vi

Когда вы начинаете редактировать команду с помощью привязок vi, вы находитесь в режиме вставки, и большинство символов просто попадают в буфер редактирования в позицию курсора. Вы можете выполнять ограниченное перемещение курсора и удаление текста с помощью команд, перечисленных в таблице 7-3.

Таблица 7-3: Команды редактирования, доступные в режиме вставки vi
Команда Описание
CTRL-B Переместить курсор назад (влево) на один символ
CTRL-F Переместить курсор вперёд (вправо) на один символ
CTRL-A Переместить курсор в начало строки
CTRL-E Переместить курсор в конец строки
DEL или CTRL-H Удалить символ слева от курсора
CTRL-W Удалить слово назад
CTRL-U Удалить от начала строки до курсора
CTRL-K Удалить от курсора до конца строки
Использование командного режима vi

Чтобы внести изменения, которые невозможно внести в режиме вставки, нажмите ESC, чтобы перейти в командный режим. Команды для перемещения курсора, изменения текста или удаления текста в командном режиме более гибкие, чем в режиме вставки. (Также есть команда u, которая должна отменять последнее изменение, внесённое в командном режиме; к сожалению, я не нашёл способа заставить её работать надёжно.)

Команды перемещения курсора

В таблице 7-4 перечислены некоторые команды перемещения курсора, которые можно использовать в командном режиме. Команды передвижения по словам w, b и e останавливаются на SPACEах или знаках препинания, тогда как W, B и E останавливаются только на SPACEах. Следовательно, вы можете производить более крупные перемещения курсора с помощью команд верхнего регистра, в то время как команды нижнего регистра полезны для более мелких движений, таких как перемещение по последовательным компонентам имен путей.

0 аналогично ^ и CTRL-A, но перемещает курсор в первый столбец команды, тогда как ^ и CTRL-A перемещают его к первому символу без SPACEов.

Таблица 7-4: Команды позиционирования курсора (командный режим vi)
Команда Описание
h или CTRL-H Переместить курсор назад (влево) на один символ
l или SPACE Переместить курсор вперёд (вправо) на один символ
w Переместить курсор вперёд (вправо) на одно слово
b Переместить курсор назад (влево) на одно слово
e Переместить курсор к следующему окончанию слова
W, B, E Как w, b и e, но другое определение слова
^ или CTRL-A Переместить курсор в начало строки (к первому неSPACEьному символу)
0 Переместить курсор в начало строки
$ или CTRL-E Переместить курсор в конец строки

Попробуйте команды перемещения в командном режиме vi, введя следующую строку и оставив курсор в конце строки:

% echo this is a command 

Нажмите ESC, чтобы войти в командный режим, затем введите следующие команды. Вы увидите, как курсор перемещается, как показано ниже:

% echo this is a command        # Нажмите h
% echo this is a command        # Нажмите b
% echo this is a command        # Нажмите ^ или CTRL-A
% echo this is a command        # Нажмите SPACE или l
% echo this is a command        # Нажмите w
% echo this is a command        # Нажмите $ или CTRL-E
Повторение команд

Команды перемещения можно повторять в командном режиме vi, указав перед командой число. Например, 3b перемещает курсор на три слова назад, а 15 SPACE перемещает курсор на 15 символов вперёд. Это недопустимое количество повторений, так как это сама по себе команда (переместить курсор в начало строки).

Многие команды редактирования в командном режиме vi, описанные ниже, могут принимать количество повторений. В описаниях команд указано, какие из них могут принимать, а какие не могут.

Добавление текста

Чтобы добавить текст в командном режиме, используйте одну из команд из таблицы 7-5, чтобы перейти в режим вставки, а затем начните печатать. Новый текст добавляется в командный буфер до тех пор, пока вы не нажмете ESC, чтобы вернуться в командный режим.

Для команд, перечисленных в таблице 7-5, не работают счетчики повторов.

Таблица 7-5: Команды для вставки текста (командный режим vi)
Команда Описание
a Добавить новый текст после курсора до нажатия ESC
i Вставить новый текст перед курсором до нажатия ESC
A Добавить новый текст после конца строки до нажатия ESC
I Вставить новый текст перед началом строки до нажатия ESC
Удаление текста

Команды, показанные в таблице 7-6, удаляют текст из буфера редактирования, x и X удаляют отдельные символы. Команда dm полезна для удаления единиц текста — она удаляет текст от курсора туда, куда его поместила бы команда m. Например, dw и db удаляют слово вперед или назад.

Команды удаления в командном режиме могут выполнять подсчет повторений, например, 3dw (или d3w) удаляет три слова, а 5x - пять символов.

Таблица 7-6: Команды удаления текста (командный режим vi)
Команда Описание
x Удалить символ под курсором
X или DEL Удалить символ слева от курсора
dm Удалить от курсора до конца команды перемещения m
D Синоним для d$
CTRL-W Удалить слово в обратном направлении
CTRL-U Удалить от начала строки до курсора
CTRL-K Удалить от курсора до конца строки
Замена текста

Чтобы заменить часть буфера редактирования, вы можете удалить старый текст, а затем вставить новый. Однако в командном режиме vi есть набор команд для замены текста, которые объединяют операции удаления и вставки (см. таблицу 7-7). Команда cm действует так же, как dm, но также переводит вас в режим вставки. Например, чтобы изменить слово, введите cw, затем введите новое слово и нажмите ESC. Чтобы заменить символ под курсором, введите r, затем новый символ. R переводит вас в режим замены, в котором символы заменяются по мере ввода, пока вы не нажмете ESC. Команда s заменяет символы, которые вы вводите, на символ под курсором, пока вы не нажмете ESC.

Командам c и s можно задать количество повторений. Например, 4cw (или c4w) изменяет четыре слова, а 6s заменяет шесть символов, начиная с символа под курсором, текстом, который вы вводите после команды.

Таблица 7-7: Команды замены текста (командный режим vi)
Команда Описание
cm Изменить символы от курсора до конца команды перемещения m до нажатия ESC
C Синоним для c$
rc Заменить символ под курсором на символ c
R Заменить несколько символов до нажатия ESC
s Заменить символ под курсором на символы, введённые до нажатия ESC

Чтобы увидеть, как работает редактирование в командном режиме vi, попробуйте следующее:

% echo My typing skilks are not amazing.   # Введите простую командную строку
% echo My typing skilks are not amazing.   # Нажмите ESC, чтобы войти в командный режим, затем введите b
% echo My typing skilks are amazing.       # Введите db
% echo My typing skilks are amazing.       # Введите h несколько раз
% echo My typing skills are amazing.       # Введите rl
Команды для поиска в истории в режиме vi

В командном режиме vi вы можете использовать ? и / для поиска в обратном и прямом направлении по списку истории. Например, когда вы вводите ?, tcsh выводит ? в качестве подсказки, чтобы вы могли ввести строку, которую хотите найти. Введите строку и нажмите RETURN. Строка может содержать символы шаблона имени файла. Редактор выполняет поиск в обратном направлении по строке, которая соответствует строке, и извлекает её в буфер редактирования, помещая курсор в конец строки. Если команда не та, которая вам нужна, введите n (следующее совпадение), чтобы повторить поиск в том же направлении. N повторяет поиск в противоположном направлении. Вы можете использовать n и N вместе, чтобы переключаться между соответствующими командами.

Когда вы найдёте нужную команду, просто начните редактировать её как обычно (обратите внимание, что после поиска вы всё ещё будете находиться в командном режиме). Или вы можете нажать RETURN, чтобы выполнить её.

Команды поиска символов в режиме vi

Командный режим vi предоставляет набор команд для поиска символов в текущей командной строке (см. таблицу 7-8). Вы можете использовать их в качестве команд перемещения для перехода к определённому символу или комбинировать их с командами d или c для удаления или изменения текста от позиции курсора до этого символа.

Таблица 7-8: Команды перемещения для поиска символов (командный режим vi)
Команда Описание
fc Переместить курсор к следующему экземпляру c в строке
Fc Переместить курсор к предыдущему экземпляру c в строке
tc Переместить курсор вверх к следующему экземпляру c в строке
Tc Переместить курсор назад к предыдущему экземпляру c в строке
; Повторить предыдущую команду f или F
, Повторить предыдущую команду f или F в противоположном направлении

fc перемещает курсор вперед к следующему экземпляру символа c в команде. Fc перемещает курсор назад:

% echo abcdefghi     # Введите команду, оставив курсор в конце
% echo abcdefghi     # Нажмите ESC, чтобы войти в командный режим, затем Fo, чтобы вернуться к o
% echo abcdefghi     # Нажмите fg, чтобы перейти к g

Команда ; повторяет последнюю команду f или F. Команда , аналогична, но перемещает курсор в противоположном направлении. То есть команда , повторяет f как F и F как f. Эта функция полезна, если вы используете несколько команд ; для поиска последовательных вхождений символа и заходите слишком далеко:

% echo three games of tic tac toe    Введите команду, оставив курсор в конце
% echo three games of tic tac toe    Нажмите ESC, чтобы войти в командный режим, затем введите Ft
% echo three games of tic tac toe    Введите ; для повторного поиска
% echo three games of tic tac toe    Введите ; для повторного поиска
% echo three games of tic tac toe    Введите ; для повторного поиска
% echo three games of tic tac toe    Упс, слишком далеко; введите , для обратного поиска

tc и Tc похожи на fc и Fc, но первые перемещают курсор вверх или назад к c, то есть влево от c для t и вправо от c для T.

Вы можете использовать команды поиска символов с d или c, чтобы удалить или изменить текст. Например, dt/ удаляет до следующей косой черты (удобно для удаления частей путей к файлам), а 3c SPACE изменяет текст до третьего SPACE (пробела) после курсора.

Использование клавиш со стрелками в режиме vi

Стрелка вверх и стрелка вниз работают как CTRL-P и CTRL-N, как в режиме Emacs. Стрелка влево и стрелка вправо перемещают курсор влево и вправо на один символ. Однако есть одна особенность, на которую следует обратить внимание, если вы находитесь в режиме вставки. На многих терминалах клавиши со стрелками фактически отправляют последовательности символов, которые начинаются с ESC. Хотя клавиши со стрелками перемещают курсор, они также переключают вас в командный режим. Если вас это отвлекает, не используйте стрелки влево и вправо в режиме вставки, а используйте CTRL-B и CTRL-F.

Изучение и изменение привязок клавиш

tcsh позволяет отображать и изменять привязки клавиш с помощью команды bindkey. Различные формы команды bindkey приведены в таблице 7-9 и описаны ниже.

Таблица 7-9: Формы команды bindkey
Команда Описание
bindkey -e Выбрать привязки emacs
bindkey -v Выбрать привязки vi
bindkey -d Восстановить привязки по умолчанию
bindkey -u Отобразить сообщение об использовании bindkey
bindkey -l Перечислить команды редактирования и их значения
bindkey Перечислить все привязки клавиш
bindkey key Перечислить привязки для key
bindkey key cmd Привязать key к команде редактирования cmd
bindkey -c key cmd Привязать key к команде UNLX cmd
bindkey -s key str Привязать key к строке str
bindkey -r key Удалить привязку для key

Формы bindkey, принимающие аргумент key, также поддерживают следующие флаги:

-k Позволяет использовать key как up, down, left или right для обозначения клавиши со стрелкой.

-b Позволяет использовать key как C-X или M-X для обозначения CTRL-X или META-X.

-a Позволяет указать альтернативную раскладку клавиш (раскладку, используемую в командном режиме vi).

-- Может использоваться непосредственно перед key, чтобы сообщить bindkey прекратить обработку аргументов в качестве флагов. Этот флаг полезен, когда сама key начинается с дефиса.

-k и -b нельзя использовать одновременно в одной команде.

Выбор набора привязок

Чтобы массово выбрать набор привязок, используйте параметр -e или -v:

% bindkey -e           # Выбрать привязки emacs
% bindkey -v           # Выбрать привязки vi

При выборе любого из наборов все клавиши привязываются к настройкам по умолчанию для этого набора, отменяя все предыдущие привязки, которые вы могли установить. Чтобы привязать отдельные клавиши (как описано в разделе «Изменение привязок клавиш» ниже), вам следует делать это только после выполнения команд bindkey -e или bindkey -v.

bindkey -d восстанавливает все привязки к настройкам по умолчанию на вашем сайте. Это не очень полезно, если только вы не используете настройки по умолчанию. Вы также можете использовать bindkey -e или bindkey -v для явного выбора определённого набора.

Получение списка команд редактирования

Чтобы увидеть полный список имён команд редактирования и их значений, используйте следующую команду:

% bindkey -l
backward-char
    Move back a character
backward-delete-char
    Delete the character behind cursor
backward-delete-word
    Cut from beginning of current word to cursor - saved in cut buffer
    .
    .
    .

Команда bindkey -l полезна для определения того, какие команды редактирования можно привязать к клавишам или что делает та или иная команда. Однако отображаемые описания довольно краткие. В приложении C, Другие источники информации, перечислен документ, в котором более подробно описаны команды редактирования.

Отображение привязок клавиш

bindkey может отображать все текущие привязки клавиш или привязки для отдельных клавиш.

Отображение всех привязок

bindkey без аргументов выводит список всех текущих привязок клавиш:

% bindkey
Standard key bindings
"^@"           ->  set -mark- command
"^A"           ->  beginning-of -line
"^B"           ->  backward-char
"^C"           ->  tty-sigintr
"^D"           ->  delete-char-or-list-or-eof

Чтобы сделать вывод более удобным для восприятия, используйте grep. Например, чтобы узнать, какие клавиши привязаны к командам, которые открывают список истории, введите следующую команду:

% bindkey | grep history

bindkey сообщает о нажатиях клавиш с помощью обозначения, показанного в таблице 7-10. Символы с включённым битом 8 (обычно набираются с помощью клавиши META, если она у вас есть) сообщаются с помощью обозначения \nnn.

Таблица 7-10: Обозначение нажатий клавиш в bindkey
Последовательность Символ, представляемый последовательностью
^X CTRL-X
^[ ESC
^? DEL
\nnn Символ ASCII с восьмеричным кодом nnn

Список привязок клавиш, отображаемый функцией bindkey, разделён на четыре части:

Стандартные привязки клавиш

Команды, привязанные к одиночным нажатиям клавиш в стандартной раскладке клавиш. Для привязок vi это команды, которые активны в режиме вставки.

Альтернативные привязки клавиш

Привязки для альтернативной раскладки клавиш. Это односимвольные привязки, которые активны в командном режиме vi. Этот раздел пуст, если вы используете привязки emacs, потому что нет «командного режима» и, следовательно, нет альтернативной раскладки клавиш.

Многосимвольные привязки клавиш

Команды, привязанные к последовательностям нажатий нескольких клавиш.

Привязки клавиш со стрелками

Команды, привязанные к клавишам со стрелками.

Отображение отдельных привязок клавиш

Чтобы отобразить одну привязку, назовите клавишу или последовательность клавиш, которая вас интересует:

% bindkey ^A                   # Показать привязку для CTRL-A
"^A"    ->      beginning-of-line
% bindkey ^L                   # Показать привязку для CTRL-L
"^L"    ->      clear-screen

Если вы укажете односимвольный аргумент key, bindkey отобразит привязку из стандартной раскладки клавиш. Для привязок vi это отображение соответствует значению клавиши в режиме вставки. Чтобы увидеть, что означает клавиша в командном режиме vi, используйте параметр -a для отображения привязки из альтернативной раскладки клавиш:

% bindkey !                           # Показать привязку из стандартной раскладки клавиш
"!"    ->       self-insert-char
% bindkey -a !                        # Показать привязку из альтернативной раскладки клавиш
"!"    ->       expand-history
Указание аргумента клавиши

Аргумент key в bindkey может представлять собой один символ или строку символов, key может содержать специальные символы, а некоторые параметры bindkey изменяют интерпретацию аргумента key.

Следующие методы позволяют включать специальные символы в key:

Таблица 7-11: Последовательности специальных символов bindkey
Последовательность Символ, представленный последовательностью
^X CTRL-X
^[ ESC
^? DEL
\^ ^
\a CTRL-G (звонок)
\b CTRL-H
\e ESC
\f FORMFEED
\n NEWLINE
\r RETURN
\t TAB
\v CTRL-K (вертикальная табуляция)
\nnn Символ ASCII с восьмеричным кодом nnn

Например, чтобы проверить привязку для CTRL-C, вы можете ввести любую из этих команд:

% bindkey ^C
% bindkey CTRL-VCTRL-C
% bindkey "\003"
% bindkey \\003

В целом, рекомендуется заключать в кавычки аргумент key, содержащий последовательности обратной косой черты или символы, которые интерпретируются оболочкой особым образом, например |, ; или (. Обратите внимание, что обратную косую черту нужно вводить только один раз, если она используется внутри кавычек, но дважды, если она не используется в кавычках.

Параметры, изменяющие интерпретацию аргументов

Чтобы указать клавишу со стрелкой, используйте параметр -k и клавишу left, right, up или down в качестве имени клавиши, например:

% bindkey -k left        # Отобразить привязку для клавиши со стрелкой влево

Параметр -b позволяет использовать обозначения C-X или M-X для указания управляющих символов или символов META:

% bindkey -b C-A                # Показать привязку для CTRL-A
% bindkey -b M-A                # Показать привязку для META-A

Если вы используете имя клавиши со стрелкой или C-X/M-X, но забываете указать параметр -k или -b, аргумент клавиши интерпретируется как последовательность из нескольких символов, что не даст вам ожидаемых результатов:

% bindkey left
Unbound extended key "left"
% bindkey C-A
Unbound extended key "C-A"

В руководстве по tcsh говорится, что параметр -b позволяет использовать обозначение F-n для указания функциональных клавиш. К сожалению, эта функция не работает.

Изменение привязки клавиш

Вы можете настроить привязки, изменив привязки для отдельных клавиш. Функция bindkey позволяет сделать следующее:

Вы можете поэкспериментировать с привязками, изменив их в командной строке с помощью описанных ниже команд bindkey. Если вы решите сделать определенную привязку частью своей среды, поместите соответствующую команду в ~/.cshrc.

Привязка отдельной клавиши

Чтобы связать команду редактирования с клавишей, привяжите команду к клавише:

% bindkey key command

key указывается так, как описано ранее в разделе «Указание аргумента клавиши». command — это любое из имён команд редактирования, перечисленных в bindkey -l.

Если вы редактируете в режиме vi, отдельные привязки клавиш устанавливаются по умолчанию в стандартной раскладке клавиш, которая применяется в режиме вставки vi. Чтобы установить привязку для использования в командном режиме vi, используйте параметр -a для установки привязки в альтернативной раскладке клавиш. Например, CTRL-B и CTRL-F обычно не привязаны в командном режиме vi. Чтобы придать этим клавишам в командном режиме то же значение, что и в режиме вставки, используйте следующие команды:

% bindkey -a ^B backward-char
% bindkey -a ^F forward-char

-a можно использовать с -b или -k, а также с опциями -c, -d, -r и -s, описанными ниже.

Привязка клавиши к самой себе

Чтобы привязать клавишу к самой себе, привяжите её к self-insert-command:

% bindkey key self-insert-command

По сути, эта привязка отключает любое специальное значение клавиши для редактирования, так что при вводе клавиши она отображается в командной строке как сама по себе. Большинство буквенно-цифровых клавиш привязаны к self-insert-command в режиме emacs и режиме вставки vi.

Удаление привязки

Чтобы отвязать клавишу, удалите привязку:

% bindkey -r key

Удаление привязки отличается от привязки клавиши к самой себе. Привязанная клавиша отображается в командной строке как сама по себе, в то время как отвязанная клавиша становится неактивной, то есть при её нажатии ничего не происходит.

Привязка клавиши к команде оболочки

bindkey -c позволяет привязать клавишу к командам UNIX. Например, если вы хотите, чтобы при нажатии CTRL-X l выполнялась команда ls -l | more, используйте следующую привязку:

% bindkey -c ^Xl 'ls -l | more'

Когда вы вводите клавишу или последовательность клавиш, привязанную к команде UNIX, текущая командная строка остаётся неизменной. То есть команда UNIX выполняется немедленно, а когда она завершается, командная строка отображается так, как она выглядела до того, как вы ввели последовательность клавиш.

Необязательно добавлять символ новой строки в конце строки команды. Вы можете использовать специальные символы в команде так же, как и специальные символы в key, как описано выше в разделе «Указание аргумента клавиши». Однако в этом случае последовательности символов внутри кавычек интерпретируются буквально.

Привязка ключа к литеральной строке

bindkey -s позволяет привязать ключ к литеральной строке:

% bindkey -s key string

Нажатие key становится эквивалентным вводу string. Вы можете включать специальные символы в string, как и в key (см. «Указание аргумента клавиши»), за исключением того, что последовательности символов внутри кавычек интерпретируются буквально.

Если string содержит другие команды редактирования, они интерпретируются как таковые при использовании key в командной строке.

Привязку клавиши к строке можно использовать для назначения фрагментов команд UNIX клавишам. Предположим, вы часто ищете процессы с помощью этой команды:

% ps ax | grep string

Вы можете назначить первую часть команды последовательности клавиш, например, CTRL-X p:

% bindkey -s ^Xp 'ps ax | grep '

Затем, чтобы найти, например, процессы emacs, вы можете ввести следующее:

% CTRL-X pemacs
Конфликты между настройками терминала и привязками клавиш

Если клавиша не выполняет ожидаемую вами функцию, возможно, существует конфликт между тем, как драйвер терминала и редактор команд интерпретируют нажатия клавиш. Например, CTRL-W обычно интерпретируется драйвером терминала как символ werase (удаления слова). Но CTRL-W не выполняет функцию удаления слова, если вы используете привязки emacs, потому что CTRL-W привязан к команде редактора kill-region. Если вы подозреваете наличие конфликта, вы можете изменить настройки драйвера терминала с помощью stty (см. главу 5, Настройка терминала) или изменить привязку клавиш в редакторе команд с помощью bindkey.

Конфликты между привязками клавиш

Если вы укажете две многосимвольные привязки, начинающиеся с одного и того же префикса, вы не сможете использовать обе привязки. Вместо этого вторая привязка заменит первую:

% bindkey -s ^Xl ls
% bindkey -s ^Xlm 'ls | more'

Глава 8
Использование алиасов для создания сочетаний клавиш

В этой главе:

При работе с оболочкой вы заметите закономерности в своих действиях. Как только вы это сделаете, вы сможете экономить время, используя механизм алиасов оболочки для создания коротких альтернативных имен для часто используемых команд или последовательностей команд. В этой главе рассказывается о том, как определять и удалять алиасы, о том, в каких случаях алиасы полезны, а также о том, как управлять несколькими наборами алиасов.

Определение алиасов

Определение алиаса имеет следующий вид:

alias name definition

name — это то, что вы хотите назвать алиасом, а definition — это команда, которая будет выполняться при использовании имени в качестве команды. Например, следующие алиасы позволяют использовать h и m в качестве коротких названий для команд history и more:

alias h history
alias m more

Алиасы лучше всего размещать в файле ~/.cshrc, чтобы они были доступны в вашей оболочке входа в систему, а также в любых подоболочках. Однако не добавляйте алиас в ~/.cshrc, пока не убедитесь, что он работает правильно. Сначала определите алиас в командной строке, а затем протестируйте его:

% alias h history             # Определить алиас
% h                           # Попробовать его

Если алиас работает не так, как вы ожидали, используйте одну из следующих команд, чтобы определить, как оболочка интерпретирует ваше определение:

% alias name                # Показать определение для name алиаса
% alias                     # Показать определения для всех алиасов

Чтобы избавиться от алиаса, используйте команду unalias:

% unalias name                   # Удалить имя_алиаса
% unalias *                      # Удалить все алиасы

Команда unalias особенно полезна, когда вы тестируете алиас в командной строке, а затем решаете, что не хотите его использовать. unalias также можно использовать в ~/.cshrc, чтобы отменить действие общесистемного файла запуска, например /etc/csh.cshrc. Такой файл может обрабатываться автоматически до ваших собственных файлов запуска и содержать системные алиасы, которые вам не нужны. Используйте unalias, чтобы удалить их.

Алиасы используются так же, как и команды. Они могут принимать аргументы:

% h 5                        # Просмотреть последние пять команд в списке истории
% m ~/.cshrc                 # Посмотреть на свой файл ~/.cshrc

Их можно использовать в конвейерах:

% grep -i fang *.ms | m    # Поиск строки с использованием more для постраничного вывода

Определения алиасов могут содержать пробелы:

alias .. cd ..       # Сделать .. алиасом для cd ..

Но определения, содержащие специальные символы, такие как ;, | или *, необходимо заключать в кавычки:

alias nusers 'who | wc -l'     # Создать алиас для подсчета количества пользователей

Алиасы могут ссылаться на другие алиасы:

alias hm 'h | m'    # Сделайте hm эквивалентом history | more

Будьте осторожны, чтобы не создать цикл алиасов:

alias x y
alias y x

Оболочка обнаруживает цикл и предупреждает вас о нём:

% x
Alias loop.
% y
Alias loop.

Алиас имеет особое значение только при использовании в качестве имени команды:

% h               # h расширяется до history здесь
% echo h          # Здесь h — это просто h
Обращение к аргументам в алиасах

По умолчанию аргументы, следующие за алиасом, совпадают с аргументами, следующими за командой, которую обозначает алиас. Рассмотрим следующий алиас, который определяет команду ll для создания длинного списка каталогов:

alias ll ls -l

Любые аргументы для ll добавляются в конец команды ls:

% ll                         # Становится ls ~l
% ll -R                      # Становится ls -l -R
% ll /bin /etc               # Становится ls -l /bin /etc

Если вы хотите, чтобы аргументы располагались не в конце команды, а в другом месте, используйте \!* для указания этого места. При вызове алиаса \!* расширяется до указанных вами аргументов или до ничего, если аргументов нет. Следующий алиас определяет команду llm, которая генерирует длинный список и запускает его через more:

alias llm 'ls -l \!* | more'

В определении используется \!* чтобы убедиться, что любые аргументы связаны с ls, а не с more:

% llm                  # Становится ls -l | more
% llm -R               # Становится ls -l -R | more
% llm /bin /etc        # Становится ls -l /bin /etc | more

Вы также можете использовать \!^ и \!$ для обращения к первому и последнему аргументам.

Используйте \!:n для обращения к конкретным аргументам по позиции, например \!:2 для второго аргумента или \!:0 для имени команды. Например, если вы храните почтовые файлы в каталоге с именем ~/Mail, вы можете создать алиасы, которые позволят вам легко копировать файлы в этот каталог и из него:

alias tobox 'cp \!:1 ~/Mail/\!:2'
alias frombox 'cp ~/Mail/\!:1 \!:2'

Аргументы, указанные с помощью \~^ или \!:n, должны быть указаны при вызове алиаса, иначе возникнет ошибка:

% frombox mesg1           # Аргумент два отсутствует
Bad ! arg selector.
Обращение к списку истории в алиасах

Обычно не принято ссылаться на список истории в алиасе, но это можно сделать, и эта функция может быть весьма полезной. Предыдущая команда — это та, которую вы, скорее всего, будете использовать чаще всего. Поскольку !! ссылается на предыдущую команду в командной строке, вы можете ожидать, что \!\! будет делать то же самое в алиасе. К сожалению, вы ошибаетесь. Вместо этого нужно использовать \!-1. Таким образом, чтобы создать алиас для просмотра файла, имя которого указано в последнем аргументе предыдущей команды, используйте \!-1$, как показано ниже:

alias mf 'more \!-1$'
Привыкаем к алиасам

После определения алиаса не забывайте использовать его. «Ну конечно, это же очевидно», — скажете вы. На самом деле это не так. Возможно, вы настолько привыкли вводить длинные команды, что у вас выработалась привычка, от которой нужно избавиться. Как только вы научитесь последовательно использовать алиасы, вы заметите, насколько эффективнее стала работа с клавиатурой.

Время от времени запускайте команду alias без аргументов, чтобы просмотреть свои алиасы. Так вы сможете понять, не забыли ли вы какие-то алиасы, которые следует использовать. Возможно, вы даже обнаружите некоторые из них, которые оказались бесполезными и могут быть удалены из файла ~/.cshrc.

Использование алиасов

В этом разделе описаны различные способы использования алиасов, которые упрощают выполнение команд.

Алиасы экономят время при вводе

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

Алиасы могут переопределять команды

Имя алиаса может совпадать с именем команды, вызываемой определением алиаса. Это особый случай, который не является циклом. Вместо этого он фактически изменяет обычное значение команды. Например, если вы обычно выполняете поиск без учёта регистра с помощью grep, вы можете создать алиас для grep, чтобы по умолчанию использовался аргумент -i:

alias grep grep -i

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

% \grep hognose *.ms
% /bin /grep hognose *.ms

Однако не стоит переопределять значение опасных команд. Например, вы можете попробовать следующий алиас, чтобы сделать команду rm более безопасной:

alias rm rm -i

В результате использования этого алиаса вы начнёте ожидать, что команда rm будет запрашивать у вас подтверждение по умолчанию. Это предположение может привести к катастрофе[13]. Для безопасного удаления лучше использовать другое имя алиаса и не трогать rm:

alias askrm rm -i
  1. Предположим, вы переходите на другую учётную запись, где тот же алиас не действует. Или предположим, что друг приходит к вам и спрашивает, как удалить несколько файлов, а вы говорите: «Просто используйте rm *. Он запросит подтверждение каждого удаления». На самом деле он не запросит, если только у вашего бывшего друга нет того же алиаса.
Алиасы скрывают различия между системами

Если у вас есть учётные записи на нескольких типах компьютеров UNIX, вы, несомненно, заметили различия в командах, доступных на каждом из них. Алиасы могут обеспечить более единообразную рабочую среду, маскируя различия между системами. Потратив немного времени на создание подходящих алиасов, вы сможете избежать возможных проблем, связанных с различиями в командах. Следуйте приведённым ниже рекомендациям:

Использование наборов алиасов

Чем больше определений алиасов содержит ваш файл ~/.cshrc, тем дольше запускается оболочка. На быстрых компьютерах задержка не будет большой проблемой, но на медленных компьютерах она может раздражать. Логин и подоболочки (например, запущенные как команды оболочки из редактора или почтового клиента) могут занимать заметно больше времени.

Если некоторые из ваших алиасов используются только при особых обстоятельствах, подумайте о том, чтобы вынести их из ~/.cshrc, чтобы сократить время запуска. Например, если у вас есть алиасы, которые используются только для конкретного проекта, поместите их в файл с именем proj-aliases и разместите его в каталоге верхнего уровня проекта. Затем, когда вы перейдете в этот каталог для работы над проектом, активируйте алиасы следующим образом:

% cd ~/myproj
% source proj-aliases

(Команда source нужна только один раз за сеанс входа в систему.) Если вы хотите усложнить задачу, вы можете создать алиас в ~/.cshrc, который переходит в каталог проекта и автоматически считывает определения алиасов:

alias cdproj 'cd ~/myproj;source proj-aliases'

Глава 9
Сокращения для именования файлов

В этой главе:

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

Использование шаблонов имён файлов

Оболочка позволяет указывать имена файлов с помощью шаблона, который представляет собой обозначение, соответствующее группе имён файлов. Шаблоны удобны тем, что вы можете использовать их в качестве сокращённой формы ввода и позволить оболочке определять, какие имена файлов подходят. Вам не нужно вводить их самостоятельно. Символы для сопоставления шаблонов показаны в таблице 9-1.

Таблица 9-1: Операторы сопоставления шаблонов имён файлов
Оператор Описание
* Сопоставление последовательности символов произвольной длины
? Сопоставление одного символа
[...] Сопоставление любого символа, указанного в скобках
[^...] Сопоставление любого символа, не указанного в скобках (только для tcsh)
^pattern Сопоставление имён файлов, не соответствующих pattern (только для tcsh)

Чтобы понять, как работают различные шаблоны, полезно иметь несколько примеров имён файлов для работы. Предположим, вы находитесь в каталоге, содержащем следующие файлы:

% ls
Imakefile       makefile        part3         part8           xprog.h
Makefile        oot-greet.tar   part4         part9           xprog.o
Makefile.bak    part1           part5         xprog
argyle.tar      part1O          part6         xprog.c
blrgle.tar.gz   part2           part7         xprog.c.bak
Сопоставление нескольких символов

Звездочка (*) действует как подстановочный знак, сопоставляя любую строку. Таким образом, звездочка сама по себе позволяет легко выбрать все файлы в каталоге. Чтобы ограничить сопоставление, объедините * с частичным именем файла:

% ls part*
part1           part2           part4          part6          part8
part1O          part3           part5          part7          part9
% ls part1*
part1           part10
% ls *tar
argyle.tar      oot-greet.tar
% ls *tar*
argyle tar      blrgle tar gz   oot-greet.tar
% ls M*e
Makefile

Есть два важных момента, связанных с *, о которых вам следует знать:

Хотя * чаще всего используется в шаблонах для сопоставления нескольких имён, вы можете использовать шаблон с подстановочными знаками для краткого ввода одного имени. Например, если blrgle.tar.gz — единственный файл в текущем каталоге, который начинается с bl или заканчивается на .gz, следующие три команды эквивалентны, но последние две проще ввести:

% gunzip blrgle.tar.gz
% gunzip bl*
% gunzip *.gz
Сопоставление отдельных символов

Вопросительный знак (?) соответствует любому отдельному символу:

% ls part?
part1           part3           part5          part7          part9
part2           part4           part6          part8
% ls part??
part1O
% ls xprog.?
xprog.c         xprog.h         xprog.o
% ls ?akefile
Makefile        makefile

Обозначение в квадратных скобках ([...]) определяет класс символов. Оно соответствует любому одиночному символу, заключенному в квадратные скобки:

% ls part[1248]
part1           part2           part4          part8
% ls xprog.[ch]
xprog.c         xprog.h
% ls [mM]akefile
Makefile        makefile

Чтобы обозначить диапазон символов, используйте тире:

% ls part[3-7]
part3           part4           part5          part6          part7

Чтобы указать дефис в качестве одного из символов в классе, сделайте его первым из символов, указанных в скобках. Например, класс [-.] соответствует дефису или точке. (В tcsh и некоторых версиях csh дефис может находиться в начале или в конце класса, поэтому [-.] и [.-] эквивалентны.)

Объединение операторов шаблонов

В одном шаблоне можно использовать несколько операторов шаблонов. Первый шаблон ниже соответствует именам файлов длиной не менее десяти символов, второй — именам файлов, содержащим точку или заглавную букву:

% ls ??????????*
Makefile.bak     argyle.tar     blrgle.tar.gz     oot-greet.tar    xprog.c.bak
% ls *[.A-Z]*
Imakefile        Makefile.bak   blrgle.tar.gz     xprog.c          xprog.h
Makefile         argyle.tar     oot-greet.tar     xprog.c.bak      xprog.o



Шаблоны и dot-файлы

Наш пример каталога на самом деле содержит dot-файлы (файлы с именами, начинающимися с точки). Dot-файлы «невидимы» в том смысле, что ls не выводит их список, если вы не укажете опцию -a («показать все»):

% ls -a
.                Makefile.bak         part1             part5            xprog
..               argyle.tar           part1O            part6            xprog.c
.exrc            blrgle.tar.gz        part2             part7            xprog.c.bak
Imakefile        makefile             part3             part8            xprog.h
Makefile         oot-greet.tar        part4             part9            xprog.o

При сопоставлении шаблонов файлы с точкой в начале имени обычно не рассматриваются как кандидаты на совпадение. Чтобы соответствовать им, шаблон должен явно начинаться с точки:

% echo *cshrc ?cshrc [.]cshrc           # Эти шаблоны не соответствуют .cshrc
echo: No match.
% echo .c* .c????                       # Эти шаблоны соответствуют .cshrc
.cshrc .cshrc
Отрицание шаблонов

В tcsh, ^ отрицает соответствие шаблону в двух контекстах. Во-первых, ^pattern соответствует любому имени файла, которое не соответствует pattern:

% ls x*
xprog            xprog.c              xprog.c.bak       xprog.h          xprog.o
% ls ^x*
Imakefile        blrgle.tar.gz        part1O            part5            part9
Makefile         makefile             part2             part6
Makefile.bak     oot-greet.tar        part3             part7
argyle.tar       part1                part4             part8

Во-вторых, [^...] соответствует любому отдельному символу, который не указан в скобках:

% ls part[1-4]
part1            part2                part3             part4
% ls part[^1-4]
part5            part6                part7             part8            part9
% ls [mM]*file
Makefile         makefile
% ls [^mM]*file
Imakefile

^pattern не обрабатывается особым образом, если только pattern не является действительно шаблоном, а не буквальной строкой. То есть, pattern должен содержать хотя бы один из символов подстановки: *, ?, или [...]. Однако, если вы хотите сопоставить все имена файлов, кроме одного, вы часто можете добавить * к имени, чтобы сделать его шаблоном (например, ^xyz* будет соответствовать всему, кроме xyz). Этот метод работает, если имя не является префиксом другого имени файла.

Будьте осторожны с шаблонами

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

% rm abc*
% rm abc *

Вторая команда удаляет abc вместе со всеми файлами, соответствующими *; то есть она удаляет все файлы в текущем каталоге. Если вы заранее подготовитесь, то сможете избежать подобных проблем. Если вы используете tcsh, установите переменную rmstar в файле ~/.cshrc, чтобы избежать массового удаления файлов, как показано ниже:

set rmstar

Если переменная rmstar установлена, tcsh спросит, действительно ли вы хотите удалить файлы, если вы введете команду rm с * в качестве одного из аргументов. Это дает вам возможность отменить действие:

% rm abc *
Do you really want to delete all files? [n/y] n

Механизм rmstar работает, даже если ссылка на rm находится внутри алиаса. Если вы уверены, что хотите переопределить его, используйте rm -f («принудительное удаление» (force removal)).

Если вы используете csh (который не распознаёт rmstar) или просто хотите создать команду, которая не будет бездумно удалять файлы, создайте алиас для удаления файлов, который всегда запрашивает подтверждение:

alias askrm rm -i

Затем возьмите за правило использовать askrm в качестве стандартной команды для удаления файлов. Опция -i заставляет rm работать в интерактивном режиме: для каждого удаляемого файла запрашивается подтверждение. В тех случаях, когда вы не хотите получать запрос, используйте rm вместо askrm.

Иногда люди заменяют rm на rm -i. В главе 8, Использование алиасов для создания сочетаний клавиш, объясняется, почему этого делать не следует.

Предварительное тестирование шаблонов имён файлов

Шаблоны — это мощный инструмент, но вы не всегда можете быть уверены, какие имена файлов соответствуют заданному шаблону, особенно когда вы только начинаете использовать шаблоны или когда в каталоге много файлов. echo — хороший инструмент для предварительного тестирования шаблонов, чтобы увидеть, как оболочка их расширяет. С помощью echo можно создавать другие команды. Приведённая ниже команда тестирует шаблон, а оператор истории !$ повторяет его:

% echo pattern                 # Тестируем шаблон
% more !$                      # Передаём шаблон другой команде

Этот метод особенно полезен для таких опасных команд, как rm, которые могут удалить слишком много файлов, если шаблон соответствует большему количеству имён, чем вы предполагали. Если вы сначала используете echo для проверки шаблона, вам не грозит случайное удаление чего-либо.

Вы можете использовать echo в сочетании с операторами истории, чтобы уточнить шаблон, который является неправильным, но близок к тому, что вам нужно:

% echo *.tar*                  # Попробовать шаблон
argyle.tar blrgle.tar.gz oot-greet.tar
% ^r*^r                        # Изменить шаблон на *.tar и повторить попытку
echo *.tar                     # Оболочка выводит новую команду
argyle.tar oot-greet.tar
% rm !$                        # Использовать шаблон для удаления файла
rm *.tar                       # Оболочка выводит новую команду

Также можно использовать ls для просмотра попавших в шаблон файлов. И после этого заменять ls на rm. (Прим.пер.)

В tcsh вы можете использовать команду list-glob редактора команд, чтобы увидеть, во что преобразуется шаблон имени файла. Команда list-glob (привязанная к CTRL-X g) отображает совпадения с шаблоном имени файла непосредственно слева от курсора, как показано ниже:

% echo *.tar*                            # Ввести шаблон, затем CTRL-X g
argyle.tar blrgle.tar.gz oot-greet.tar   # tcsh выводит совпадающие имена...
% echo *.tar*                            # ...затем повторно выводит команду

Использование {} для создания аргументов

Шаблоны имён файлов можно использовать только для обращения к существующим файлам. Если вам нужно указать имена независимо от того, существуют ли файлы (обычно для создания новых файлов или присвоения новых имён существующим), используйте конструкцию {} оболочки.

Предположим, что вы хотите создать набор новых каталогов с именами от Project1 до Project5. Вы не можете использовать шаблон Project[1-5], потому что этот шаблон работает только для существующих имён, как показано ниже:

% mkdir Project[1-5]
mkdir: No match.

Вы можете ввести каждое имя:

% mkdir Project1 Project2 Project3 Project4 Project5

Но это утомительно. Гораздо проще использовать {} для создания аргументов:

% mkdir Project{1,2,3,4,5}

Оболочка просматривает строки, разделённые запятыми, между фигурными скобками и создаёт по одному аргументу для каждой строки.

Вы можете использовать {} для смешивания ссылок на существующие и несуществующие файлы. Следующая команда переименовывает chapter8 в chapter9, даже если chapter9 не существует:

% mv chapter{8,9}

Чтобы переименовать файл в исходное имя, выполните следующее:

% mv chapter{9,8}

Любая или все строки в {} могут быть пустыми. Поэтому следующие пары команд эквивалентны:

{} может быть не таким интуитивно понятным, как операторы шаблонов, поскольку его можно использовать для указания несуществующих файлов (или даже аргументов, которые вообще не относятся к файлам), но вы обнаружите, что он весьма полезен. Опять же, echo полезно, пока вы изучаете эту конструкцию, как и при изучении шаблонов имён файлов. В следующих примерах echo используется, чтобы продемонстрировать другие аспекты работы {}.

{} не обязательно должен находиться в конце аргумента:

% echo {y,d}abba doo, {w,bl}inken nod, t{i,a}c toe
yabba dabba doo, winken blinken nod, tic tac toe

Вы можете использовать {} более одного раза в аргументе:

% echo {a,b,c}{0,1,2}
aO al a2 bO b1 b2 cO c1 c2

Вы даже можете вкладывать {} друг в друга:

% echo part{a,b{1,2,3},c}
parta partb1 partb2 partb3 partc

Чтобы включить специальный символ или запятую внутри {}, перед ним поставьте обратную косую черту:

% echo "pease porridge "{hot\,,cold\!}
pease porridge hot, pease porridge cold!

Расширение аргументов с помощью {} происходит в указанном вами порядке. Если у вас есть два файла с именами parta и partb, то следующие команды будут разными. Первая команда получает файлы, соответствующие шаблону, в алфавитном порядке, потому что совпадения с шаблоном сортируются перед подстановкой в командную строку. Вторая команда получает файлы в порядке их имён:

% echo part[ba]
parta partb
% echo part{b,a}
partb parta

Сокращённое имя каталога

И в csh, и в tcsh есть сокращённые обозначения для обращения к домашним каталогам учётных записей пользователей, а в tcsh есть сокращённые обозначения для обращения к записям в стеке каталогов.

Обращение к домашним каталогам с помощью ~name

Оболочка интерпретирует ~ или ~name в начале пути как домашний каталог или домашний каталог пользователя name. Эти сокращения позволяют быстро обращаться к домашнему каталогу любого пользователя, не вводя (и даже не зная) фактический путь. Таким образом, если я хочу посмотреть, какие файлы есть у пользователя carl в его домашнем каталоге, мне не нужно знать, где находится этот каталог. Я просто ввожу следующую команду:

% ls ~carl

Я могу редактировать свой файл calendar, где бы я ни находился, с помощью следующей команды:

% vi ~/calendar

Предположим, что я нахожусь глубоко в иерархии своих каталогов и хочу скопировать файл intro.ms.new из каталога Thesis в текущий каталог. Я хочу избежать указания длинных абсолютных или относительных путей к файлу, как показано ниже:

% cp /usr/staff/dubois/Thesis/intro.ins.new      # (или)
% cp ../../../. ./Thesis/intro.ms.new .

Ни один из этих вариантов не является привлекательным. Абсолютный путь длинный, а при вводе относительного пути легко по ошибке подняться на слишком мало или слишком много уровней вверх. Гораздо проще ввести следующее:

% cp ~/Thesis/intro.ms.new .

Если файл intro.ms.new находится в чужой учётной записи, я могу легко получить его копию с помощью следующей команды:

% cp ~colleen/Thesis/intro.ms.new .
Обращение к записям стека каталогов с помощью =n

В tcsh записи из стека каталогов можно использовать для построения аргументов команд. Если вы начнёте аргумент с =n, это будет эквивалентно введению имени записи n из вашего стека каталогов. Это позволяет легко обращаться к этим каталогам и их файлам, не вводя длинные пути. Дальнейшее использование стека каталогов рассматривается в главе 13, Навигация по файловой системе.

Глава 10
Имя файла и автоматическое завершение

В этой главе:

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

В csh и tcsh есть встроенное завершение имён файлов, в tcsh также есть завершение имён команд, и вы можете программировать собственные типы завершения для каждой команды (когда встроенные средства завершения не работают должным образом). Например, вы можете указать tcsh завершать аргумент для команды mail именем пользователя, а не именем файла, или завершать аргументы для команды cd, используя только имена каталогов.

Использование встроенного завершения имён файлов

В tcsh автозаполнение имён файлов всегда активно: просто введите первую часть имени и нажмите клавишу TAB. tcsh определяет, какое имя соответствует префиксу, и вводит оставшуюся часть за вас. Если у вас есть файл с именем experiment.data, вы можете быстро ввести его имя следующим образом:

% more ex                         # Введите префикс ex, затем нажмите TAB
% more experiment.data            # Оболочка введет оставшуюся часть имени

В csh после ввода префикса нужно нажать ESC, а не TAB. Кроме того, автозаполнение имен файлов не работает, если вы не зададите переменную оболочки filec[14]. Поэтому сначала добавьте следующую команду в файл ~/.cshrc:

set filec

Если префикс соответствует более чем одному имени файла, оболочка не может определить, какой файл вам нужен. Автозаполнение по-прежнему полезно, потому что оболочка предоставляет ту часть имени, которая является общей для возможных совпадений, а затем издаёт звуковой сигнал, предупреждая о неоднозначности. Предположим, у вас есть файлы с именами experiment1.data, experiment2.data и experiment3.data. Если вы введёте ex и нажмёте клавишу завершения, оболочка предложит вариант periment:

% more ex             # Введите префикс, затем нажмите клавишу завершения
% more experiment     # Оболочка выполнит частичное завершение и издаст звуковой сигнал

Чтобы завершить работу, введите 1, 2 или 3, чтобы указать, какой файл вам нужен, и снова нажмите клавишу завершения. Оболочка добавит .data, и вы закончите работу.

tcsh добавляет пробел при завершении имени обычного файла и косую черту (/) после имён каталогов. Дополнительный символ служит визуальным индикатором успешного завершения. Кроме того, пробел полезен, потому что вам не нужно вводить его самостоятельно, если вы вводите другой аргумент, и в остальном он безвреден. Косая черта полезна, если вы вводите длинное имя пути, потому что вы можете завершить ввод каждого компонента имени, не вводя косую черту после каждого из них. Предположим, я хочу выполнить следующую команду:

% cd ~/Papers/References/Books

В tcsh я мог бы указать путь к каталогу, введя всего несколько символов: ~/P TAB R TAB B TAB.

csh ничего не добавляет к завершенным именам файлов. Вы по-прежнему можете завершить несколько компонентов пути, но вам придется самостоятельно вводить косые черты. Если вы хотите, чтобы tcsh тоже работал таким образом, добавьте следующее в файл ~/.cshrc:

unset addsuffix

Если слово, которое нужно дополнить, начинается с ~, то и csh, и tcsh дополняют его до ссылки на домашний каталог в виде ~name:

% cd ~du          # Введите префикс домашнего каталога, затем нажмите клавишу завершения
% cd ~dubois      # Оболочка дополняет ссылку на каталог

(tcsh также добавляет косую черту, потому что ~dubois — это каталог.)

  1. В некоторых версиях csh вместо filec используется переменная complete, а в некоторых системах (например, в ULTREX 31) в csh вообще не выполняется автозаполнение имён файлов (причина, по которой стоит перейти на tcsh).
Отображение совпадений при завершении ввода

При попытке завершить ввод неоднозначного префикса оболочка издаёт звуковой сигнал. Однако, если вы не можете вспомнить, какие имена соответствуют префиксу, нет необходимости отменять команду и запускать ls. Просто нажмите CTRL-D; оболочка выведет список совпадающих имён в стиле ls, а затем повторно выведет командную строку[15]. Вы можете продолжить ввод команды с того места, на котором остановились:

% more dat94                        # Введите префикс, затем нажмите CTRL-D
dat94.01    dat94.03    dat94.05    # Оболочка отобразит совпадающие имена файлов...
dat94.02    dat94.04
% more dat94                        # ...затем повторно отобразит командную строку

Сопоставление работает и для ссылок на домашний каталог. Чтобы увидеть, какие имена учётных записей начинаются с d, попробуйте следующее:

% echo ~d                         # Введите префикс, затем нажмите CTRL-D.
daemon   dan       david    deb      debby    dick     donna    dubois
dale     daniel    dc       debbie   deutsch  dom      dorder   dws
% echo ~d 

Если автозаполнение не работает из-за отсутствия совпадений, CTRL-D ничего не покажет, как показано ниже:

% echo xyz                 # Введите префикс, затем нажмите CTRL-D
% echo xyz                 # Нет совпадений
  1. На самом деле, вывод больше похож на ls -F. И csh, и tcsh указывают на исполняемые файлы или каталоги с помощью * или / после имени. tcsh также указывает на сокеты, блочные и символьные устройства, символические ссылки и файлы FIFO с помощью =, #, %, @ и |.
Сужение области поиска совпадений при автозаполнении

Чтобы игнорировать имена с определёнными суффиксами, установите переменную fignore. Эта функция может исключать целые классы имён файлов и чаще приводит к успешному завершению ввода за счёт уменьшения количества имён-кандидатов. Например, если вы не хотите использовать имена объектных файлов или резервных копий для завершения ввода, добавьте следующую команду в файл ~/.cshrc:

set fignore = ( .o .bak \~ )  # Не использовать для сопоставления имена файлов, оканчивающиеся на .o, .bak или ~

В этом примере перед ~ стоит обратная косая черта, поэтому оболочка не сразу преобразует его в путь к вашему домашнему каталогу.

fignore сам по себе игнорируется при следующих обстоятельствах:

Другие типы завершения

tcsh выполняет завершение и сопоставление для некоторых слов, которых нет в csh:

  1. Дополнительные сведения о стеке каталогов см. в главе 13, Навигация по файловой системе.
Автоматическое отображение совпадений при завершении

Если возможно несколько вариантов завершения, tcsh может автоматически отобразить совпадения. Задайте переменную оболочки autolist в файле ~/.cshrc с помощью одной из приведенных ниже команд:

set autolist
set autolist = ambiguous

Первая форма приводит к отображению совпадений при любом сбое завершения. Вторая форма приводит к автоматическому отображению только в том случае, если возможно несколько совпадений и если завершение не добавляет новых символов к имени для сопоставления.

Если вы часто работаете с каталогами, содержащими множество файлов, или с каталогами, подключёнными по медленной сети, то при использовании CTRL-D для поиска совпадений может быть медленной и/или выдавать много результатов. Настройка autolist может усугубить эту проблему. Однако в tcsh есть несколько переменных оболочки для настройки поведения при поиске совпадений:

Завершение и редактор команд tcsh

В tcsh TAB и CTRL-D выполняют завершение и вывод списка совпадений как часть командного редактора. Вы можете использовать другие функции редактора команд в дополнение к стандартному поведению завершения. В следующих разделах обсуждаются некоторые из возможностей.

Пошаговый просмотр возможных завершений

Команда редактора complete-word-fwd заменяет префикс слева от курсора на первое из слов, соответствующих этому префиксу. Если команда повторяется, текущее слово заменяется на последовательные совпадения. Это позволяет перемещаться по списку вариантов завершения, пока вы не найдёте нужный. Если вы дойдёте до конца списка, tcsh издаст звуковой сигнал и заменит текущее слово на исходный префикс. Команда complete-word-back работает аналогично, но перемещает по совпадающим словам в обратном порядке.

К сожалению, по умолчанию эти команды не привязаны ни к каким клавишам, поэтому вам нужно настроить собственные привязки. Например, если вы хотите использовать клавиши со стрелками влево и вправо для перехода по вариантам завершения ввода в прямом и обратном направлении, вы можете добавить следующие команды в файл ~/.cshrc:

bindkey -k left complete-word-back
bindkey -k right complete-word-fwd

Дополнительные сведения о создании собственных привязок клавиш см. в главе 7, Редактор командной строки tcsh.

Завершение в середине строки

Редактор команд tcsh позволяет перемещать курсор в любую точку текущей командной строки[17]. Таким образом, хотя автозаполнение чаще всего используется, когда курсор находится в конце строки, в tcsh есть возможность выполнять автозаполнение в середине строки. Автозаполняется только префикс слева от курсора, поэтому, если курсор находится в середине слова, некоторые символы после него могут стать лишними и их нужно будет удалить после выполнения автозаполнения.

При использовании с привязками vi, но не с привязками emacs, CTRL-D выводит список совпадений префиксов в середине команды.

  1. См. главу 7 для получения информации о редактировании команд.
Завершение и шаблоны имён файлов

Завершение имён файлов не работает для слов, содержащих символы шаблонов или {}, но такие слова можно расширить в tcsh с помощью команды expand-glob редактора команд. Команда expand-glob привязана к CTRL-X * в режиме emacs и к * в командном режиме vi. Таким образом, если вы редактируете команды с помощью привязок emacs, вы можете расширить шаблон следующим образом:

% more results.*                                    Введите шаблон, затем CTRL-X *
% more results.expt1 results.expt2 results.expt3    tcsb расширяет шаблон

Если вы хотите посмотреть, какие имена соответствуют шаблону, не расширяя командную строку, используйте команду list-glob (CTRL-X g для любого набора сочетаний клавиш). Например, вы можете использовать list-glob, чтобы проверить шаблон, который вы указываете в команде rm, и определить, удалит ли команда нужные файлы. Если нет, вы можете изменить шаблон.

Как и функция автозавершения, команды редактора expand-glob и list-glob работают в любой точке командной строки, расширяя или перечисляя расширения слова, находящегося непосредственно слева от курсора.

Запрограммированное автозавершение

В tcsh есть функция автозавершения, которая позволяет связывать определённые типы автозавершения с отдельными командами. Эта функция полезна, когда встроенное автозавершение, описанное в предыдущих разделах, не выполняет автозавершение слов так, как вам нужно. Например, вы можете захотеть дополнить аргумент именем пользователя, или дополнить некоторые аргументы иначе, чем другие, или определить, как дополнить слово, исходя из того, как выглядит предыдущее слово.

Запрограммированные завершения срабатывают так же, как и обычные (TAB завершает слово, а CTRL-D отображает возможные совпадения), но вы задаёте их поведение с помощью команды complete. Синтаксис команды complete довольно громоздкий, поэтому мы рассмотрим его более подробно в конце главы. Сначала мы рассмотрим несколько примеров команды complete, чтобы получить общее представление о том, как она работает. (Вы можете найти гораздо больше примеров запрограммированных завершений в файле complete.tcsh, который входит в исходный дистрибутив tcsh. Он предоставляет готовые дополнения, которые вы можете использовать, и даёт идеи для создания собственных. Если у вас нет этого дистрибутива, в Приложении C, Другие источники информации, указано, как получить complete.tcsh отдельно.)

Запрограммированные функции завершения лучше всего размещать в файле ~/.cshrc, чтобы они были доступны как в вашей оболочке входа в систему, так и в любых подоболочках[18]. Не помещайте полную команду в ~/.cshrc, пока не убедитесь, что она работает правильно. Сначала определите функцию завершения в командной строке, а затем протестируйте ее. Если функция завершения работает неправильно, используйте одну из следующих команд, чтобы определить, интерпретирует ли оболочка ваше определение так, как вы ожидаете:

% complete                  # Показать все определения завершения
% complete name             # Показать определение завершения для команды name

Давайте рассмотрим несколько примеров. Предположим, вы хотите повысить эффективность завершения для команды cd, игнорируя не-каталоги. Вы можете сделать это с помощью следующей команды завершения:

complete cd 'p/1/d/'

Первый аргумент, cd, указывает команду, для которой выполняется автозаполнение. Сложный аргумент, следующий за cd, — это правило автозаполнения: p указывает, что правило применяется к слову в заданной позиции, 1 определяет позицию (в данном примере — первое слово после имени команды), а d определяет способ завершения слова (как имени каталога).

Это завершение помогает вам, потому что файлы, не являющиеся каталогами, не имеют отношения к изменению местоположения. Исключив их из рассмотрения при завершении аргумента для команды cd, вы с большей вероятностью получите уникальное совпадение (и, следовательно, успешное завершение). Вы также получите меньший список имён, который будет проще просматривать, когда вы нажмёте CTRL-D, чтобы получить список совпадений. Это похоже на настройку fignore, за исключением того, что имена исключаются на основе типа файла, который они представляют, а не на основе их внешнего вида.

Можно использовать другие спецификаторы позиций. Например, rmdir принимает аргументы каталога, как и cd. Однако rmdir позволяет указывать несколько каталогов для удаления, поэтому более подходящим является правило завершения, применимое к любому аргументу. Для написания такого правила можно использовать спецификатор позиции * («все позиции»):

complete rmdir 'p/*/d/'

Доступные позиционные параметры показаны в таблице 10-1 (чаще всего используются 1 и *).

Программируемые завершения не ограничиваются именами файлов, поэтому их можно использовать для таких команд, как показано ниже, каждая из которых принимает аргументы, не являющиеся именами файлов:

% printenv name           # Отобразить значение переменной среды name
% alias name              # Отобразить определение алиаса name
% nail name               # Отправить письмо пользователю name

Вы можете настроить соответствующие завершения для каждой из команд, чтобы вам было проще вводить их аргументы (команда mail позволяет указать несколько получателей, поэтому для указания позиции используется *):

complete printenv 'p/1/e/'        # Завершить аргумент именем переменной среды
complete alias 'p/1/a/'           # Завершить аргумент именем алиаса
complete mail 'p/*/u/'            # Завершить аргументы именами пользователей

Типы слов, которые можно использовать для завершения, приведены в таблице 10-2. Большинство этих типов являются предопределенными, но вы также можете указать собственный список слов для завершения аргументов. Предположим, вы часто подключаетесь к нескольким компьютерам с помощью ftp. Вы можете упростить ввод их названий, как показано ниже, где список автозаполнения представлен в виде набора слов, разделённых пробелами, в скобках:

complete ftp 'p/1/(ftp.uu.net wuarchive.wustl.edu prep.ai.mit.edu info.cern.ch) /'

Если вы подключаетесь к сайту, которого нет в списке, вам нужно ввести его полное название. Но вы по-прежнему экономите время на вводе текста, поскольку список содержит компьютеры, к которым вы подключаетесь чаще всего. Этот пример иллюстрирует, что запрограммированные дополнения могут быть полезны, даже если они не охватывают все возможные аргументы.

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

Чтобы продемонстрировать правила на основе шаблонов, давайте рассмотрим команду find, у которой есть множество флагов. Правило завершения может помочь вам ввести их:

complete find 'c/-/(user group type name print exec mtime fstype perm size)/'

Буква c в начале правила указывает на то, что оно дополняет «текущее слово», то есть слово, соответствующее шаблону (дефис). Правило дополняет любое слово, начинающееся с -, одним из слов из списка в скобках:

% find . -g                   # Введите префикс флага, затем нажмите TAB
% find . -group               # tcsh дополняет имя флага

Поскольку список совпадений по префиксу работает с запрограммированными дополнениями, правило завершения поиска не только помогает дополнять названия флагов. Оно также предоставляет удобный способ получить помощь, если вы, как и я, не всегда помните названия различных флагов. Просто введите ltabc и нажмите CTRL-D, чтобы увидеть список флагов, как показано ниже:

% find . -                    # Введите дефис, затем нажмите CTRL-D
exec    group   name    print    type            # tcsh отобразит имена флагов
fstype  mtime   perm    size     user
% find . -                      

В этом примере правило завершения служит для запоминания, предоставляя своего рода онлайн-поддержку.

Правила завершения n-типа сопоставляют одно слово и завершают следующее. Они особенно полезны для завершения слова, которое следует за определённым флагом. Например, команду завершения поиска можно улучшить, добавив несколько правил для завершения слов, которые следуют за флагами -user и -group, в качестве имён пользователей и групп:

complete find \
         'c/-/(user group type name print exec mtime fstype perm size)/' \
         'n/-user/u/' \
         'n/-group/g/'

Приведённая выше команда показывает, что команда complete может принимать несколько правил завершения. Обратите также внимание на использование обратной косой черты для продолжения команды на нескольких строках. Это соглашение улучшает читаемость длинных команд complete.

В одной команде complete можно смешивать правила на основе позиций и шаблонов. Первый аргумент для find — это каталог, поэтому аргумент можно дополнить, добавив правило p-типа:

complete find \
         'p/l/d/' \
         'c/-/(user group type name print exec mtime fstype perm size)/' \
         'n/-user/u/' \
         'n/-group/g/'

Строка, соответствующая правилам на основе шаблонов, не обязательно должна начинаться с дефиса. Команда dd принимает аргументы if=file и of-file для указания входных и выходных файлов. Следующая команда complete позволяет сопоставлять слова, начинающиеся с префикса if= или of=, а затем дополнять всё, что следует за префиксом, до имени файла:

complete dd 'c/[io]f=/f/'

Команда показывает, как операторы шаблонов имён файлов могут использоваться в правиле завершения — шаблон соответствует как if=, так и of=.

Если правило завершения или набор правил можно применить к нескольким командам, вам не нужно писать несколько отдельных команд завершения, например:

complete cd 'p/1/d/'
complete pushd 'p/1/d/'

Вместо этого вы можете указать все имена команд в списке в фигурных скобках:

{cd,pushd} 'p/1/d/'
  1. complete — это команда, специфичная для tcsh, поэтому вам следует защитить ее от csh, используя инструкции из главы 4, Файлы запуска оболочки.

Синтаксис команды complete

Теперь, когда мы рассмотрели несколько примеров, мы можем более систематически рассмотреть синтаксис команды complete. Команда complete состоит из нескольких элементов, поскольку ей требуется несколько видов информации:

complete command word/pattern/list/suffix

command — это имя команды, которую нужно завершить. Следующий за ним аргумент — это правило, описывающее, как дополнять слова для команды.

Правила автозавершения состоят из следующих частей:

Правило завершения должно быть заключено в кавычки, если оно содержит специальные для оболочки символы, такие как *. Я считаю, что проще всего просто заключать все свои правила в кавычки. Части правила завершения обычно разделяются косыми чертами, но вы можете использовать другой символ, как показано ниже:

complete man 'p,*,c,'       # Разделитель запятая
complete cd 'p:l:d:'        # Разделитель двоеточие
Выбор слова для завершения

Значения word и pattern работают вместе, чтобы определить, к какому слову или словам применяется правило завершения. Вы можете применить правило завершения по позиции или по совпадению с шаблоном.

Выбор слова по позиции

Для правил, основанных на позициях, word — это p, а pattern определяет позиции слов, как показано в таблице 10-1. Шаблон * означает любую позицию, поэтому правило типа p с указанием позиции * применяется к любому из аргументов команды.

Таблица 10-1: Указание позиций слов для правил завершения типа p
Позиция Описание
n Слово n
m-n Слова с m по n
m* Слова с m по последнее слово
* Все слова
Выбор слов на основе шаблонов

Если word начинается с c, n, C или N, правило основано на шаблоне и активируется для любого слова, начальная часть которого соответствует шаблону. Шаблон может быть буквенной строкой или содержать операторы сопоставления с образцом (*, ?, []) или конструкцию {}.

Спецификаторы слов в правилах сопоставления с образцом выполняют доработку, как описано ниже:

c

Правила c-типа дополняют текущее слово (слово, соответствующее pattern). В качестве префикса для доработки используется только часть слова, следующая за начальной строкой, соответствующей pattern. Этот спецификатор позволяет вам сопоставить начальную часть слова, пропустить эту часть и завершить остальную часть слова.

n

Правила n-типа завершают следующее слово после слова, подобранного по pattern. Эти правила часто используются для соответствия определенному флагу и завершения слова, следующего за ним.

C

Как и c, за исключением того, что всё слово, включая часть, соответствующую pattern, используется в качестве префикса для завершения.

N

Как и n, но правило завершает второе слово после слова, соответствующего pattern.

Правила типа c и n используются часто. Правила типа C и N используются реже.

Завершение выбранного слова

Часть правила завершения, относящаяся к list, определяет, какое завершение нужно выполнить, то есть какое слово вы хотите получить в итоге. Различные спецификаторы list приведены в таблице 10-2. Большинство из них представляют собой односимвольные коды, обозначающие атрибут, которому должно соответствовать завершение (например, e указывает, что слово должно быть выбрано из списка переменных, которые в данный момент определены в вашей среде). Последние три спецификатора позволяют указать произвольный список слов, из которых можно выбирать.

Таблица 10-2. Типы Списков слов Правил завершения
Список Описание
a Имена алиасов
b Имена привязок клавиш (команды редактора командной строки)
c Имена команд
d Имена каталогов
e Имена переменных среды
f Имена файлов (любого типа, включая имена каталогов)
g Имена групп
j Имена заданий
l Имена ограничений ресурсов
n Нулевой список (подавляет автозаполнение)
s Имена переменных оболочки
S Имена сигналов
t Имена текстовых файлов (фактически, любых файлов, не являющихся каталогами)
v Имена переменных (любого типа)
u Имена пользователей
X Имена команд, для которых определены варианты завершения
x Пояснение; как n, но выводит сообщение, когда вы введете CTRL-D
C, D, F, T Как c, d, f, t, но выбирает вариант завершения из заданного каталога
(list) Выбирает вариант завершения из слов в заданном списке
$variable Выбирает вариант завершения из слов в значении переменной
'command' Выбирает вариант завершения из слов в выводе команды
Ограничение набора завершающих слов

Спецификаторы списка слов на основе атрибутов ограничивают автозаполнение указанным типом слова, но вы можете указать дополнительный критерий, чтобы ещё больше сузить допустимый выбор. Для этого укажите список в форме list:restrict, где restrict — это шаблон имени файла. Кандидатами для автозаполнения являются только те элементы list, которые соответствуют шаблону. В restrict можно использовать операторы сопоставления с образцом (*, ?, []) или конструкцию {}. Следующие команды указывают, что аргументы uncompress дополняются только именами файлов, оканчивающимися на .Z, а аргументы gunzip дополняются именами файлов, оканчивающимися на .z, .gz или .Z:

complete uncompress 'p/*/f:*.Z/'
complete gunzip 'p/*/f:*.{z,gz,Z}/'

Шаблон также может начинаться с ^ для изменения направления поиска. Например, маловероятно, что вы будете использовать vi для редактирования дампов ядра, объектных файлов (.o) или файлов библиотек (.a). Следующая полная команда ограничивает автозаполнение имён файлов, исключая эти файлы:

complete vi 'p/*/f:^{core,*.[oa]}/'

Функция restrict аналогична переменной оболочки fignore, которая используется со встроенными дополнениями для игнорирования имен с определенными суффиксами. Однако между restrict и fignore есть несколько отличий:

Выбор вариантов завершения из заданного каталога

Типы списков слов C, D, F и T аналогичны соответствующим типам c, d, f и t, за исключением того, что за ними должно следовать обозначение :path, указывающее на каталог. Автодополнение формируется на основе команд, каталогов и различных типов файлов, включая обычные, расположенных в указанном каталоге. Например, я могу вызвать программу elm, как показано ниже, чтобы прочитать почту из file, а не из моего системного почтового ящика:

% elm -f file

Если file указан с ведущим =, например =xyz, elm предполагает, что файл xyz находится в моём личном почтовом каталоге. elm предоставляет этот синтаксис в качестве удобного шортката, позволяющего мне легко читать файлы из моего домашнего каталога, независимо от моего местоположения. К сожалению, ведущий = также мешает встроенному дополнению имён файлов. Чтобы обойти эти проблемы, я могу использовать запрограммированное дополнение, чтобы сообщить tcsh, что слова, начинающиеся с =, на самом деле начинаются с пути к моему почтовому каталогу, как показано ниже:

complete elm 'c@=@F:/usr/staff/dubois/Mail@'

Правило завершения использует разделитель, отличный от косой черты (в данном случае @), поскольку имя каталога содержит косые черты.

Отображение сообщения вместо списка совпадений

Тип списка слов x (explain) подавляет завершение, подобное n, но принимает обозначение :message, которое определяет сообщение, которое будет отображаться, если вы попытаетесь перечислить совпадения для префикса. Например, x может использоваться для представления информации о том, что для перехода в режим сна требуется время в секундах, как показано ниже:

complete sleep 'p/*/x:specify one argument indicating a sleep time in seconds/'
Предоставление вашего собственного списка завершающих слов

Если ни один из односимвольных типов list не описывает набор слов, которые вы хотите использовать в правиле автозавершения, предоставьте свой собственный список. Это можно сделать тремя способами: указав явный набор слов в скобках, перечислив слова в переменной или выполнив команду, которая выводит слова.

Предположим, что вы обычно используете rlogin для подключения к одному из определенного набора хостов, используя одно из заданных имен пользователей, как показано ниже:

% rlogin host -l name

Поскольку имя компьютера является первым аргументом, а имя пользователя следует за флагом -l, вы можете написать завершение rlogin следующим образом:

complete rlogin \
          'p/l/(sidewinder cottonmouth massasauga diamondback)/' \
          'n/-l/(almanac ftpmail postgres majordom)/'

Затем вы можете ввести имя компьютера и имя пользователя, как показано ниже:

% rlogin s                         # Type hostname prefix, then hit TAB
% rlogin sidewinder                # tcsh completes the hostname
% rlogin sidewinder -l m           # Type -1 and username prefix, then hit TAB
% rlogin sidewinder -l majordom    # tcsh completes the username

Теперь предположим, что вы хотите использовать тот же список имён хостов для других сетевых команд, таких как telnet или rsh[19]. Вот один из способов сделать это:

complete rlogin \
          'p/l/(sidewinder cottonmouth massasauga diamondback)/' /
          'n/-l/(almanac ftpmail postgres majordom)/'
complete telnet 'p/l/ (sidewinder cottonmouth massasauga diamondback)/'
complete rsh 'p/l/(sidewinder cottonmouth massasauga diamondback)/'

Однако если вы захотите изменить список названий компьютеров позже, вам придётся изменить его в трёх местах. Вместо этого вы можете присвоить списку слов переменную и использовать её в правилах автозавершения:

set machines = (sidewinder cottonmouth massasauga diamondback)
complete rlogin \
          'p/l/$machines/' \
          'n/-l/ (almanac ftpmail postgres majordom)/'
complete telnet 'p/l/$machines/'
complete rsh 'p/l/$machines/'

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

Если спецификатор списка слов представляет собой команду оболочки в обратных кавычках, то дополнения выбираются из набора слов, сгенерированных этой командой. Предположим, вы хотите использовать команду talk для общения с другими пользователями на вашем компьютере. Вы можете указать tcsh дополнять аргумент talk именем пользователя, как показано ниже:

complete talk 'p/l/u/'

Однако это правило может дополнять слово именем пользователя, который даже не вошёл в систему. Чтобы использовать только имена активных пользователей, выполните команду, которая определяет набор активных пользователей, как показано ниже:

complete talk 'p/l/`who|cut -cl-8|sort -u`/'

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

  1. В некоторых системах rsh называется remsh.
Добавление суффикса к автозавершённому слову

При завершении работы tcsh обычно добавляет косую черту к именам каталогов и пробел к именам файлов и другим типам слов. Вы можете указать другой символ суффикса или даже не указывать суффикс вовсе. Символ суффикса указывается после разделителя, который следует за типом списка слов.

Команда finger обычно принимает аргумент в виде user@host, который сложно ввести за одну операцию. Однако вы можете указать первую часть аргумента в качестве имени пользователя и добавить суффикс @, чтобы упростить ввод имени хоста:

complete finger 'p/*/u/@'

Вы также можете полностью отключить добавление суффикса, добавив ещё один разделитель сразу после типа списка слов. Например, браузеры World Wide Web, такие как lynx или xmosaic, могут быть запущены с аргументом, указывающим универсальный указатель ресурса (URL) для информации, к которой вы хотите получить доступ. Приведённое ниже правило дополняет часть URL-адреса, относящуюся к ресурсу, и удаляет пробел, который обычно добавляется:

complete {lynx,xmosaic) 'p#l#(http:// ftp:// gopher:// wais:// mailto: news:)##'

Таким образом, вам не придётся возвращаться на SPACE перед вводом остальной части аргумента.

Указание нескольких правил завершения

Несколько правил завершения позволяют по-разному завершать одни аргументы по сравнению с другими, но следует помнить о следующих моментах.

Во-первых, все правила завершения для данной команды должны быть указаны в одной команде завершения. Не вводите отдельную команду завершения для каждого правила. Если вы попытаетесь указать завершение rlogin для аргументов имени хоста и имени пользователя, как показано ниже, ваша попытка не увенчается успехом. Вторая команда просто заменяет первую:

complete rlogin 'p/1/(sidewinder cottonmouth massasauga diamondback)/'
complete rlogin 'n/-1/(almanac ftpmail postgres majordcm)/'

Во-вторых, важно соблюдать порядок, в котором вы указываете несколько правил завершения. Правила проверяются слева направо, пока не будет найдено подходящее. Рассмотрим приведенную ниже команду завершения для mail. Цель состоит в том, чтобы завершить аргумент, следующий за -f, как имя файла, подавить завершение аргумента, следующего за -s, и завершить любой другой аргумент как имя пользователя:

complete mail 'p/*/u/' 'n/-f/f/' 'n/-s/n/'

Однако автозаполнение работает не так, как ожидалось. Правило p-типа применяется в первую очередь ко всем словам. Поэтому правила n-типа никогда не используются. Команду следует изменить и указать следующим образом:

complete mail 'n/-f/f/' 'n/-s/n/' 'p/*/u/'

Хорошее практическое правило: любое правило, применимое ко всем словам, должно быть указано последним, чтобы можно можно было проверить правила.

Отображение и удаление запрограммированных вариантов завершения

Чтобы отобразить все варианты завершения или конкретный вариант завершения, используйте приведенные ниже команды:

% complete                     # Показать все варианты завершения
% complete command             # Показать варианты завершения для conmand

Если вариант завершения работает не так, как нужно, попробуйте отобразить его определение. Возможно, вы обнаружите, что tcsh интерпретировал ваше определение не так, как вы ожидали.

Чтобы удалить автозаполнение, используйте uncomplete:

% uncomplete command           # Удалить автозаполнение для command
% uncomplete *                 # Удалить все автозаполнения

Когда не применяются запрограммированные автозаполнения

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

Глава 11
Цитаты и специальные символы

В этой главе:

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

Специальные символы

Оболочка обычно присваивает специальные значения нескольким символам (см. таблицу 11-1). По мере того, как вы набираетесь опыта работы с оболочкой и изучаете эти значения, тот факт, что эти символы не интерпретируются буквально, становится чем-то само собой разумеющимся. Например, после того, как вы узнаете, что & означает выполнение в фоновом режиме, и начнёте использовать его соответствующим образом, это соглашение станет вашей второй натурой — частью вашего набора навыков работы с оболочкой.

Однако этот набор навыков будет неполным, если вы не знаете, как использовать специальные символы буквально, потому что иногда вам нужно отключить их специальное значение. Предположим, у вас есть файл с именем Budget-R&D. Это вполне допустимое имя файла. Однако, поскольку имя содержит символ &, если вы попытаетесь использовать это имя, не отключив &, этот символ вызовет всплеск активности и несколько сообщений об ошибках:

% wc Budget-R&D
[1] 10413
wc: Budget-R: No such file or directory.
[1]    Exit 2                 wc Budget-R
D: Command not found.

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

Таблица 11-1: Символы, являющиеся специальными для оболочки
Символ(ы) Описание
* ? [ ] ^ { } ~ Сопоставление и расширение шаблонов имён файлов
$ Ссылка на переменную
| Конвейер
< > Перенаправление ввода и вывода
! ^ Ссылка на историю и быстрая замена
& Фоновое выполнение
; Разделитель команд
SPACE Разделитель аргументов
TAB Заполнение имён файлов (tcsh)
ESC Заполнение имён файлов (csh)
(...) Выполнение подкоманды
`...` Замена команды
\ ' " Символы кавычек

Символы экранирования в оболочке

Для экранирования используются четыре символа. Они отключают (или "экранируют") значения специальных символов:

  1. Символом lnext обычно является CTRL-V. Для получения дополнительной информации см. главу 5, Настройка вашего терминала.
Экранирование символов кавычек

Символы кавычек можно использовать для ввода буквальных символов кавычек, а не только для отключения специального значения других специальных символов.

Обратная косая черта и CTRL-V заключаются в кавычки сами по себе. Другими словами, \\ производит \, а CTRL-V CTRL-V производит CTRL-V.

Одинарные и двойные кавычки заключают друг друга в кавычки:

% echo "'" '"'
' "

Экранирование с обратной косой чертой:

% echo \' \"
' "

И экранирование обратной косой черты в кавычках:

% echo '\' "\"
\ \

В следующих разделах описано несколько практических способов использования символов кавычек.

Обращение к файлам с проблемными именами

Иногда вы можете обнаружить, что у вас есть файл с именем, содержащим специальные символы, такие как SPACE, ? или !, или, возможно, даже CTRL-H. Вы вряд ли случайно создадите такие имена в командной строке, но это относительно легко сделать в других обстоятельствах. Например, после сохранения элемента в сеансе gopher вы можете обнаружить, что у вас есть файл с таким прекрасным именем, как это:

<<** New Items! (READ THIS!!) **>>

Такое имя может появиться из-за того, что при сохранении элемента в файл некоторые клиенты gopher предлагают имя по умолчанию, которое совпадает с названием элемента в текущем меню.

Или вы можете использовать FTP для получения файлов с компьютера, на котором работает операционная система с другими соглашениями об именах файлов, чем в UNIX. Если имена получаемых вами файлов содержат символы, которые оболочка считает специальными, а ваша FTP-программа не сопоставляет их с обычными символами, вы получаете файлы, к которым трудно обращаться.

Обычно лучший способ работать со сложным именем файла — сразу изменить его на более простое для использования. Или вы можете удалить файл, потому что часто файлы с неудобными именами создаются случайно и являются ненужными.

Предположим, что у нас есть несколько файлов с именами, содержащими различные специальные символы, как показано ниже:

abc;1
Home Work
!abc
!abc and def
My Summer Vacation (Part 2)
REDCTRL-HADME
<<** New Items! (READ THIS!!) **>>

Для работы со сложными именами файлов, такими как те, что показаны выше, у вас обычно есть несколько вариантов:

Давайте рассмотрим эти варианты по порядку в следующем разделе.

Ввод сложных имён файлов с помощью автозаполнения

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

% rm Home                                         # Введите префикс имени файла
% rm Home\ Work                                   # Нажмите TAB; tcsh подставит оставшуюся часть имени

% mv My                                           # Введите префикс имени файла
% mv My\ Summer\ Vacation\ \(Part\ 2\)            # Нажмите TAB; tcsh подставит оставшуюся часть имени
% mv My\ Summer\ Vacation\ \(Part\ 2\) my-vac-2   # Введите оставшуюся часть команды

csh тоже может дополнять имена файлов, но не экранирует специальные символы. Поэтому csh не подходит для ввода сложных имен файлов таким образом.

Ввод сложных имен файлов с помощью шаблонов имен файлов

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

<<** New Items! (READ THIS!!) **>>

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

% echo *Items*                       # Проверьте шаблон
<<** New Items! (READ THIS!!) **>>   # Да, он соответствует только этому имени
% mv *Items* Newltems                # Переименуйте файл с помощью шаблона

Если команда echo показывает более одного совпадения, попробуйте другой шаблон. Когда вы найдёте подходящий шаблон, используйте его для переименования файла.

Если вы пытаетесь удалить файл, а не переименовать его, то шаблон может соответствовать другим именам в дополнение к тому, которое вас интересует, потому что вы можете использовать команду rm -i. Опция -i заставляет команду rm работать в интерактивном режиме, запрашивая подтверждение удаления для каждого файла. Ответьте y (да) для файла, который вы хотите удалить, и n (нет) для остальных, как показано ниже:

% rm -i *abc*
rm: remove !abc? n
rm: remove !abc and def? y
rm: remove abc;1? n

Не забудьте опцию -i, иначе rm удалит все файлы, соответствующие шаблону.

Если имя файла начинается с -, используйте ./pattern, чтобы rm не интерпретировал ведущий дефис как флаг.

Самостоятельное экранирование специальных символов

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

Передача специальных символов в команды

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

Обращение к файлу, если в его названии есть ведущий дефис

Если вы создадите файл с именем, начинающимся с дефиса, у вас могут возникнуть проблемы с его использованием. Многие команды считают аргументы, начинающиеся с дефиса, параметрами обработки, а не именами файлов, в частности mv и rm. Файлы с именами, начинающимися с дефиса, сложно переименовать или удалить:

% mv -myfile1 myfile1
usage: mv [-if] f1 f2 or mv [-if] f1 ... fn d1
% rm -myfile2
usage: rm [-rif] file ...

Эта проблема связана не с кавычками, а с дефиса, которое в этой ситуации обрабатывается особым образом, и вам нужно как-то с этим справиться. Попробуйте использовать эквивалентное имя файла, которое не начинается с дефиса:

% mv ./-myfile1 myfile1
% rm ./-myfile2

Символ +, если использовать его в качестве первого символа имени файла, вызовет меньше проблем, чем -, потому что меньше команд принимают параметры, начинающиеся с +. Тем не менее вам всё равно следует избегать таких имён файлов, как +abc, потому что некоторые часто используемые команды, такие как more и vi, ищут параметры +.

Использование частичных кавычек

Иногда нужно заключать в кавычки только часть аргумента. Предположим, вы хотите вывести содержимое ~ann/Volume II, то есть каталога Volume II в учётной записи ann. Вы не можете оставить имя без кавычек, потому что оно содержит пробел, но вы не можете заключить в кавычки всё целиком, потому что такие кавычки помешают правильному расширению ~ann:

% ls ~ann/Volume II
/usr/staff/ann/Volume not found
II not found
% ls "~ann/Volume II"
~ann/Volume II not found

Вместо этого заключите пробел в кавычки с помощью обратной косой черты или используйте кавычки для указания части имени. Следующие команды позволяют расширить ~ann, не позволяя пробелу выступать в качестве разделителя аргументов:

% ls ~ann/Volume\ II            # (или)
% ls ~ann/'Volume II'

Странности с кавычками

В правилах использования кавычек есть несколько исключений. Вы, вероятно, нечасто будете с ними сталкиваться, но знать о них полезно:

Глава 12
Использование команд для создания аргументов

В этой главе:

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

Подстановка команд

Оболочка помогает выполнять команды, предоставляя сокращённые способы указания аргументов команд. Самый распространённый метод — использовать шаблоны имён файлов для создания списка файлов, чтобы не вводить каждое имя файла вручную. Например, чтобы отредактировать все исходные файлы C в текущем каталоге, вы можете легко выбрать их с помощью следующего шаблона:

% vi *.c

Но шаблоны имён файлов имеют определённые ограничения. Вы не можете использовать их для выбора имён файлов на основе их содержимого, для поиска в иерархии каталогов или для выбора файлов по таким критериям, как возраст, владелец, размер, тип и т. д.

Для таких задач можно использовать другие стратегии выбора файлов. Например, можно относительно легко сгенерировать подходящие имена файлов с помощью команды. Предположим, вы хотите найти файлы, содержащие строку «gaboon», а затем изменить их так, чтобы вместо «gaboon» было «viper». Шаблон имени файла сам по себе не подскажет вам, какие файлы содержат «gaboon», но команда, состоящая из grep в сочетании с шаблоном, работает довольно хорошо, как показано ниже:

% grep -li gaboon *

Приведённая выше команда выводит имена подходящих файлов на ваш терминал. К сожалению, эта команда не поможет вам редактировать файлы, а вручную вводить имена файлов, полученные с помощью grep, в команду редактора — утомительное занятие, особенно если задействовано много файлов. В таких случаях полезен метод, называемый подстановкой команд. Подстановка команд позволяет выполнить команду grep, а затем вставить результат непосредственно в другую командную строку. Чтобы отредактировать файлы, содержащие «gaboon», с помощью подстановки команд, заключите команду grep в обратные кавычки:

% vi `grep -li gaboon *`

Командная оболочка выполняет команду grep, заключенную в обратные кавычки, и заменяет команду ее выводом (с заменой новых строк на пробелы). Затем выполняется результирующая командная строка vi. В результате, если grep выдает имена файлов index.ms, intro.ms, preface.ms, reference.ms и taxonomy.ms в качестве выходных данных, команда vi эквивалентна следующей:

% vi index.ms intro.ms предисловие.ms reference.ms taxonomy.ms

Команды в обратных кавычках часто используются для вывода списка имён файлов (как показано выше), но их можно использовать и для вывода других типов данных, например чисел или отчётов о состоянии. Например, вы можете добавить следующую команду в файл ~/.login, чтобы при каждом входе в систему узнавать, сколько человек в ней находится:

echo "There are "wholwc -1" users logged in."

Команды в обратных кавычках могут содержать ссылки на историю или переменные:

% which spell
/usr/bin/spell
% file `!!`
file `which spell`
/usr/bin/spell: executable shell script
% more !$
more `which spell`

% set dir = /usr/bin
% echo "$dir contains `ls $dir|wc -1` files."
/usr/bin contains 322 files.

Команды в обратных кавычках выполняются внутри двойных кавычек, но не внутри одинарных:

% echo "Mail queue backlog: `mailqlhead -1`"
Mail queue backlog: Mail Queue (176 requests)
% echo 'Mail queue backlog: `mailqlhead -1`'
Mail queue backlog: `mailqlhead -1`

Вы не можете поместить одну команду в обратных кавычках внутрь другой; обратные кавычки внутри других обратных кавычек недопустимы.

Поиск файлов

find - полезная утилита для указания аргументов имени файла, поскольку она может выполнять поиск по всему дереву каталогов. Предположим, вы находитесь на вершине проекта с несколькими каталогами, который содержит файлы README в нескольких своих каталогах. (Это может быть программный проект, исследовательский проект, содержащий файлы данных из нескольких связанных экспериментов, иерархия архивов gopher или ftp и т. д.) Команда find может помочь вам найти файлы:

% find . -name README -print

Эта команда find означает «начиная с . (т.е. с текущего каталога) найдите файлы с именем README и выведите (отобразите) их пути». Команда find полезна для подстановки команд, чтобы выбрать файлы README для других команд. Например, чтобы просмотреть файлы, сделайте следующее:

% more `find . -name README -print`

Чтобы вывести их на печать, сделайте следующее:

% pr `find . -name README -print` | lpr

Приведённые выше команды могут показаться немного пугающими, если вы не привыкли пользоваться find, но представьте, что вам нужно сделать то же самое, заходя в каждый каталог проекта в поисках файлов README и выполняя отдельные команды more или pr. Нет уж, спасибо!

В этой главе мы несколько раз будем использовать find в простой форме, но вам стоит заглянуть в его справочную страницу, чтобы понять, что ещё можно делать с помощью find. Другим ценным источником информации для find является книга UNIX Power Tools от O’Reilly & Associates.

Получение аргументов из файла

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

% command `cat names`

Имена можно создавать любым удобным для вас способом. Один из самых простых способов обработки набора имён файлов из каталога — вывести содержимое каталога в файл, отредактировать файл, удалив ненужные имена, а затем подставить содержимое файла в другую команду. Этот метод показан ниже:

% ls > names           # Перечислите имена файлов в names
% vi names             # Отредактируйте names, чтобы удалить лишние имена файлов
% command `cat names`  # Передайте оставшиеся имена файлов в command
Обработка аргументов по отдельности

Если вы хотите создать имена файлов с помощью команды, но обрабатывать их по отдельности, используйте цикл foreach. Предположим, что вы хотите создать резервную копию каждого из файлов «gaboon» перед их редактированием. Вы можете сделать следующее:

% foreach f (`grep -li gaboon *`)
? cp $f $f.bak
? end

foreach выполняет команды в цикле, по одной для каждого аргумента, указанного в скобках. При каждом проходе цикла переменной f присваивается имя следующего аргумента (в данном случае — следующего имени файла, созданного командой grep). До тех пор, пока вы не введёте завершающую строку, приглашение будет меняться, напоминая вам о том, что содержимое цикла собирается. Наконец, цикл выполняется.

Повторение замененных команд

Вы часто будете выполнять ряд операций с одним и тем же набором файлов, поэтому, когда вы используете команду для создания списка имён файлов, вам может понадобиться использовать этот список несколько раз. Предположим, вы хотите просмотреть файлы «gaboon», а затем отформатировать и распечатать каждый файл по отдельности. Вы можете сделать следующее:

% vi `grep -li gaboon *`
% foreach f (`grep -li gaboon *`)
? groff -ms $f | lpr
? end

Однако описанный выше метод предполагает неэффективный ввод текста. Команда в обратных кавычках считается одним аргументом в командной строке; поэтому вы можете легко повторить команду с помощью оператора истории:

% vi `grep -li gaboon *`
% foreach f (`!$`)              # Повторите последний аргумент предыдущей команды
foreach f (`grep -li gaboon *`)
? groff -ms $f | lpr
? end

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

Один из способов выполнить команду один раз, но использовать её вывод несколько раз, заключается в том, чтобы сохранить вывод в переменной, а затем обращаться к этой переменной, когда вам понадобится использовать список имён файлов:

% set args = `grep -li gaboon *`
% vi $args
% foreach f ($args)
? groff -ms $f | lpr
? end

Другой способ избежать многократного выполнения команды, занимающей много времени, — сохранить вывод команды в файл, а затем подставить содержимое файла в другие команды с помощью cat. Я использую этот метод, чтобы просматривать файлы Imake в дистрибутиве X Window System и видеть, как используются различные параметры конфигурации. Программное обеспечение X состоит из тысяч файлов, поэтому по возможности следует запуска find в иерархии X. Вместо этого я создаю один раз основной список im.list путей ко всем файлам Imake:

% cd top-of-X-tree
% find . -name Imakefile -print > im.list

Если у меня есть этот список, мне не нужно повторять команду find каждый раз, когда я хочу найти файлы Imake. Я могу просто повторить вывод, вставив содержимое списка файлов в другие команды:

% grep -l CrossCompiling 'cat im.list'
% grep -l Threads.tmpl `cat im.list'
% и т. д.

Отложенная подстановка команд

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

Проверка списка аргументов

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

Работа с неожиданным выводом

Команда, генерирующая аргументы, может выдать не тот тип вывода, который вы ожидаете. Разница в одном символе между следующими командными строками существенна:

% vi `grep -li gaboon *`
% vi `grep -i gaboon *`

Команда grep в первой командной строке выводит только имена файлов, содержащих строки, соответствующие строке поиска. Это желаемый результат. Команда grep во второй командной строке выводит сами строки, соответствующие строке поиска. Это не желаемый результат. Если вы случайно забудете добавить параметр -l, то в результате командная строка будет содержать содержимое совпадающих строк, а не имена файлов, которые вы хотите отредактировать.

Отложенная подстановка команд дает вам возможность проверить аргументы и изменить команду, генерирующую аргументы, прежде чем использовать результат:

% grep -i gaboon * > names # Сгенерируйте аргументы
% cat names                # Проверьте вывод, обратите внимание, что он некорректен
% !g:s/-i/-li              # Исправьте параметры grep и снова сгенерируйте аргументы
grep -li gaboon * > names
% cat names                # Проверьте ещё раз; на этот раз вывод правильный
% vi `!!`                  # Отредактируйте файлы
vi `cat names`
Работа с отсутствующим выводом

Команда, генерирующая аргументы, может вообще не выдавать никакого результата. Если это произойдёт, команда, которая должна была обрабатывать файлы, может просто ожидать ввода с терминала. Рассмотрим команду для поиска и вывода на печать файлов README в дереве каталогов:

% pr `find . -name README -print` | lpr

Если в дереве нет файлов README, команда find не выдаст никакого результата, и команда будет эквивалентна этой:

% pr | lpr

В результате вы ожидаете, что команда выведет на печать несколько файлов, а команда ожидает, что вы введёте данные в терминале.

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

% find . -name README -print > names # Сгенерировать список аргументов
% cat names                          # Проверить список
% pr `!!` | lpr                      # Если список имён не пуст, вывести файлы
pr `cat names` | lpr

Если бы файл names был пустым, вы бы просто не стали запускать команду pr.

Проверка аргументов с помощью tee

Генерацию и проверку аргументов можно объединить в одну команду с помощью tee, которая одновременно выводит вводимые данные на терминал и записывает их в файл. Приведённые выше последовательности команд можно выполнить с помощью tee следующим образом:

% grep -i gaboon * | tee names
% grep -li gaboon * | tee names
% vi `cat names`

% find . -name README -print | tee names
% pr `cat names` | lpr

Аргумент имени файла для команды tee — это выходной файл, а не входной; поэтому при использовании команды tee не используйте > для сохранения вывода.

Изменение списка аргументов

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

Предположим, что вы хотите найти и, возможно, сжать файлы в своей учётной записи, размер которых превышает 500 блоков. Используйте команду find, чтобы создать первоначальный список имён файлов-кандидатов. Затем отредактируйте список, удалив имена файлов, которые вы хотите оставить несжатыми (или которые уже были сжаты). Наконец, сожмите оставшиеся в списке файлы. Последовательность команд может выглядеть следующим образом:

% find ~ -type f -size +500 -print > names # Определите большие файлы
% vi names                                 # Отредактируйте список имён файлов
% compress `cat names`                     # Сожмите файлы в полученном списке

Другой тип двухэтапного процесса возникает, когда вы создаёте список имён файлов, из которого генерируете вторичные списки для подстановки в другие команды. Приведённый ранее пример, в котором я искал файлы Imake в дистрибутиве X, является примером, где этот метод полезен. Первый шаг — создание файла im.list, содержащий пути к Imakefile. Из этого списка я создаю вторичный список, в котором описываю, какие файлы Imake содержат определённый символ:

% grep -l symbol `cat im.list` > names # Определите, какие файлы Imake содержат symbol

Теперь я могу подставить вторичный список в команды:

% more `cat names`   # Посмотрите на файлы
% pr !$ | lpr        # Выведите их на печать

Поскольку я оставил исходный список нетронутым, я могу продолжать использовать его для других поисков.

Когда следует избегать подстановки команд

В некоторых обстоятельствах подстановку команд использовать сложно. В таких обстоятельствах может потребоваться дополнительная осторожность, а в других — совершенно другой метод обработки списка аргументов.

Имена файлов, содержащие специальные символы

Не используйте подстановку команд для создания списка аргументов filename, если имена содержат специальные символы. Имена файлов, содержащие пробелы или другие символы со специальными значениями, превращаются в множественные или искаженные аргументы. Предположим, вы хотите отредактировать файлы, содержащие определенную строку, используя следующую команду:

% vi `grep -l string *`

Если один из соответствующих файлов, созданных grep, называется Some File, файл отображается в команде vi в виде двух аргументов (Some и File), а не одного. Вы можете избежать этой проблемы, заключив имена файлов в кавычки следующим образом:

% vi "grep -l string * | sed "s/.*/'&'/"`

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

Использование xargs вместо подстановки команд

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

% grep -l string `find . -type f -print`
Too many words from ``.

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

Утилита xargs предоставляет альтернативу подстановке команд, когда вам нужно обработать большое количество файлов. Аргументы xargs состоят из команды, которую вы хотите выполнить, за исключением того, что вы не указываете имена файлов. Входные данные для xargs состоят из имён обрабатываемых файлов. Поэтому вместо ввода следующего:

% grep -l string `find . -type f -print`

Вы можете переписать командную строку, чтобы использовать xargs:

% find . -type f -print | xargs grep -l string

Поскольку имена файлов, созданные find, представляются xargs в качестве входных данных, а не в командной строке, их может быть любое количество, xargs считывает имена, разбивает их на меньшие списки и передает каждый список в качестве аргументов отдельному вызову команды, которую xargs должен выполнить. Такое поведение позволяет сохранить разумный размер отдельных списков аргументов[21].

Если у вас уже есть список имён файлов в файле, вы можете использовать xargs следующим образом:

% xargs command < names

Чтобы получить опыт работы с xargs, используйте его для выполнения команды echo. Так вы сможете увидеть, как xargs разбивает входные данные на списки аргументов. Для простой демонстрации выведите содержимое любого каталога, в котором есть несколько файлов, и посмотрите на результат:

% ls /bin | xargs echo

xargs получает список имён файлов в качестве входных данных от ls, разбивает имена на более мелкие списки, а затем передаёт каждый список в echo.

  1. xargs предоставляет опции для управления тем, как он разделяет входные аргументы и передает их вызываемой команде. Обратитесь к странице руководства для получения дополнительной информации.
Ограничения xargs

xargs не работает должным образом, если имена файлов содержат пробелы или другие специальные символы, как при подстановке команд.

xargs не работает, если выполняемая команда на самом деле является алиасом.

Глава 13
Навигация по файловой системе

В этой главе:

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

По мере того, как вы будете лучше ориентироваться в пространстве, вы заметите, как легко забыть, где вы находитесь. В главе 14, Отслеживание своего местоположения, рассказывается о том, как не «заблудиться» в файловой системе.

Перемещение по пространству

Основной командой для изменения местоположения в файловой системе является cd (change directory), которая может переместить вас в любой каталог, на который у вас есть разрешение. Чтобы эффективно использовать команду cd, вам следует изучить основные идиомы:

% cd                 # Перейти в домашний каталог
% cd ..              # Перейти к родительскому каталогу текущего каталога
% cd dir1            # Перейти в каталог dir1 в текущем каталоге
% cd dir1/dir2/dir3  # Перейти в каталог на несколько уровней ниже текущего
% cd /               # Перейти в корневой каталог
% cd /dir1           # Перейти в каталог dir1 в корневом каталоге
% cd /dir1/dir2/dir3 # Перейти в каталог на несколько уровней ниже корневого

Для перехода в другие каталоги удобно использовать сокращения ~ (для перехода в домашний каталог) и ~name (для перехода в домашний каталог пользователя name). Эти сокращения приведены ниже:

% cd ~/Mail             # Перейти в свой каталог Mail
% cd ~mary              # Перейти в домашний каталог учетной записи mary
% cd ~terrell/Projects  # Перейти в каталог Projects учетной записи terrell

Вы обнаружите, что использовать имя, например ~mary, намного проще, чем использовать абсолютный путь, например /usr/staff/admin/mary; в первом случае нужно меньше печатать, и вам даже не нужно знать соответствующий путь.

Работа в нескольких местах

Ваша работа, вероятно, связана с доступом к информации, которая хранится более чем в одном каталоге. Например, предположим, что вы работаете в каталоге A, а затем переключаетесь в каталог B, чтобы быстро что-то проверить, прежде чем продолжить работу в каталоге A. В других ситуациях вы можете переключаться между каталогами на более длительное время. Предположим, что вы работаете в ~/src/myprog, чтобы изменить исходный код программы myprog, но иногда вам нужно просмотреть содержимое некоторых системных заголовочных файлов в /usr/include. Один из способов перемещения между каталогами — вводить путь каждый раз при смене каталога:

% cd /usr/include
% cd ~/src /myprog
% cd /usr/include
% cd ~/src /myprog
% # и т. д.

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

Использование команды cd для возврата в предыдущий каталог

В tcsh команда cd - возвращает вас в предыдущее местоположение, поэтому последовательные команды cd - обеспечивают удобный способ переключения между двумя каталогами. Если вы находитесь в ~/src/myprog, вы можете переключаться между /usr/include, как показано ниже:

% cd /usr/include    # Перейти в /usr/include
% cd -               # Вернуться в ~/src/myprog
% cd -               # Вернуться в /usr/include
% cd -               # Вернуться в ~/src/myprog
% # и т. д.

Однако механизм - запоминает только один каталог. Если в /usr/include вы вводите cd sys, чтобы перейти в /usr/include/sys, tcsh забывает, что вы когда-то были в ~/src/myprog. Это означает, что вы не можете использовать cd - для возврата в него. Чтобы вы могли легко вернуться в ~/src/myprog, независимо от того, куда вы переместились, вы должны сохранить ~/src/myprog в стеке каталогов.

Использование стека каталогов

У команды cd есть две родственные команды: pushd (вставить каталог) и popd (удалить каталог), которые могут изменить ваше местоположение в файловой системе. Эти команды также позволяют запоминать каталоги и возвращаться к ним позже. Они работают с помощью стека каталогов оболочки, который содержит текущий каталог и любые другие каталоги, которые вы хотите запомнить. В отличие от команды cd - (которая доступна только в tcsh), команды для работы со стеком доступны как в csh, так и в tcsh[22].

pushd добавляет записи в стек, а popd удаляет их. Обе команды показывают содержимое стека после смены каталога. Если вы забыли, какие каталоги находятся в стеке, команда dirs отобразит стек без смены каталога. Распространённые формы команд pushd и popd приведены в таблице 13-1.

Использование стека каталогов похоже на расстановку закладок в книге, чтобы можно было вернуться к определённым местам, просто открыв соответствующую закладку. Вы вводите имя каталога явно только при первом переходе в него, а затем возвращаетесь к нему позже, используя обозначение, которое быстрее и проще, чем повторный ввод имени.

Таблица 15-1. Команды стека каталогов
Команда Описание
pushd dir Добавить dir в стек и переключиться на него
pushd Поменять местами две верхние записи в стеке
pushd +n Повернуть стек так, чтобы запись n оказалась сверху
popd Удалить верхнюю запись и вернуться к предыдущей записи
popd +n Удалить запись n из стека (tcsh, некоторые версии csh)
dirs Показать содержимое текущего стека

Пересмотрите сценарий переключения между ~/src/myprog и /usr/include с учётом команд управления стеком. Ваш текущий каталог всегда находится в верхней части стека, поэтому в нём всегда есть хотя бы одна запись. Во время входа в систему верхней записью является ваш домашний каталог. Когда вы перемещаетесь в ~/src/myprog с помощью команды cd, верхняя запись меняется, чтобы отразить ваше новое местоположение:

% dirs                    # Стек каталогов во время входа в систему
~
% cd ~/src/myprog ; dirs  # Переместиться в ~/src/myprog, затем показать стек
~/src/ntyprog

Команда pushd с аргументом каталога переключается в этот каталог и помещает его в стек. Использование pushd аналогично использованию команды cd, за исключением того, что предыдущее местоположение остается в стеке под новой записью:

% pushd /usr/include
/usr/include ~/src/myprog

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

Если в стеке есть два каталога, pushd без аргументов меняет их местами. Это позволяет легко переключаться между двумя местоположениями, не вводя постоянно имена каталогов:

% pushd                       # Вернуться в ~/src/myprog
~/src/myprog /usr/include
% pushd                       # Вернуться в /usr/include
/usr/include ~/src/myprog

Когда вы закончите работу в каталоге, команда popd удалит верхнюю запись из стека, вернет вас в каталог, указанный предыдущей записью, и отобразит новое содержимое стека:

% popd                  # Выйти из /usr/include, вернуться в ~/src/myprog
~/src/myprog

В tcsh команда pushd интерпретирует символ - как предыдущую директорию, так же как это делает cd. Следовательно, если вы выходите из текущего каталога с помощью popd, а затем решаете, что он вам всё ещё нужен, команда pushd возвращает каталог в стек:

% pushd -                    # Вернуть /usr/include в стек и переместиться туда
/usr/include ~/src/myprog

Дополнительные команды pushd dir помещают в стек больше элементов:

% pushd /usr/local/lib
/usr/local/lib /usr/include ~/src/nyprog
% pushd ~/Mail
~/Mail /usr/local/lib /usr/include Vsrc/myprog

Однако, если в стеке более двух элементов, вам понадобится более общий способ обращения к каждому каталогу (pushd без аргументов обращается только к двум верхним элементам и, как следствие, является недостаточным). Элементы стека нумеруются, начиная с 0, и вы обращаетесь к ним с помощью обозначения +n. Например, чтобы перейти в /usr/include, используя стек из приведённого выше примера, начните с 0 и считайте слева направо, чтобы увидеть, что /usr/include — это второй элемент. Затем переключитесь на этот элемент, как показано ниже:

% pushd +2
/usr/include ~/src/myprog ~/Mail /usr/local/lib

Посмотрите внимательно на то, что происходит со стеком: pushd +2 поворачивает стек, чтобы поместить вторую запись сверху. Поскольку записи нумеруются с нуля, а не с единицы, вторая запись является третьей, а pushd +2 поворачивает стопку три раза вместо двух. Помните об этом тонком моменте, иначе вы всегда будете отставать на одну запись.

В tcsh и некоторых версиях csh вы можете использовать popd +n для удаления записи n без изменения текущего местоположения:

% popd +3                         # Удалить /usr/local/lib из стека
/usr/include ~/src/nyprog ~/Mail

Чтобы очистить весь стек, используйте dirs -c (только в tcsh).

  1. На самом деле это не совсем так. В некоторых версиях csh не реализован стек каталогов. Если вы используете одну из таких версий, подумайте о переходе на tcsh, поскольку доступ к механизму стека важен для эффективного использования оболочки.
Форматы отображения стека

В csh записи стека обычно отображаются в виде полных путей, за исключением того, что каталоги в вашем домашнем каталоге отображаются с использованием обозначения ~, tcsh предоставляет более полное обозначение, используя ~name для отображения каталогов в учетных записях других пользователей.

csh позволяет вам использовать dirs -l для отображения записей стека с использованием длинных имен (т. е. с расширением обозначения ~ до полных путей). Этот параметр также является единственным, который csh предоставляет для изменения отображения стека; следовательно, остальная часть этого раздела применима только к tcsh.

В дополнение к -l в tcsh предусмотрены другие параметры отображения, которые можно применять к другим командам. В приведенных ниже примерах используется команда dirs. cd, pushd и popd также принимают показанные флаги.

Предположим, что стек выглядит следующим образом:

% dirs
/usr/include ~/Mail ~ftp/pub ~

Как и в csh, команда dirs -l позволяет использовать длинные имена:

% dirs -l
/usr/include /usr/staff/dubois/Mail /usr/ftp/pub /usr/staff/dubois

dirs -n форматирует отображение таким образом, что если запись выходит за пределы экрана и обтекает его, то вместо этого эта запись печатается полностью в следующей строке. Такой стиль форматирования может облегчить чтение на дисплее.

dirs -v выводит данные "по вертикали", то есть каждая запись находится в отдельной строке. Кроме того, отображаются номера записей:

% dirs -v
0    /usr/include
1    ~/Mail
2    ~ ftp/pub
3    ~

dirs -v полезен, когда вы хотите ссылаться на записи, используя +n (для pushd или popd) или =n (в аргументах командной строки), потому что вы можете видеть номера записей без необходимости их подсчета. Вы можете использовать несколько флагов, например, dirs -lv выводит вертикальный вывод с использованием длинных имен.

pushd и popd обычно выводят стек. Если вам не нужна эта обратная связь, установите переменную оболочки pushdsilent в вашем файле ~/.cshrc:

set pushdsilent

Чтобы указать pushd или popd печатать стек, даже если установлена переменная pushdsilent, используйте -p (или -l, -n или -v, если вам нужен один из альтернативных форматов отображения стека).

Ссылка на записи стека в аргументах команды

В tcsh можно начинать аргументы команды с =n или =-, чтобы обратиться к n-й или последней записи в стеке. Эта запись позволяет легко получить доступ к каталогам, названным в вашем стеке, без перехода в них. Предположим, вы находитесь в ~/src/myprog, и ваш стек выглядит так:

% dirs -v
0    ~/src /myprog
1    /usr/include
2    ~/Mail

Если вы хотите посмотреть файл /usr/include/syslog.h, вы можете переключиться в /usr/include, запустить команду more syslog.h, а затем вернуться в ~/src/myprog. Но вы потратите меньше времени, если останетесь на месте и посмотрите файл с помощью одной команды:

% more =1/syslog.h

tcsh расширяет =1 до записи 1 в стеке (/usr/include). Чтобы найти в ~/Mail файлы, содержащие сообщения, относящиеся к myprog, вы можете использовать любую из этих команд:

% grep myprog =2/*
% grep myprog =-/*

Автодополнение имени файла работает для аргументов, начинающихся с =n:

% more =1/lo                    # Введите префикс, затем нажмите TAB
% more =1/locale.h              # tcsh дополняет имя

обозначение =n настолько удобно, что вы можете обнаружить, что помещаете каталоги в стек, даже если вы не собираетесь часто в них меняться. Помещая каталог в стек, вы можете ссылаться на его файлы, используя =n вместо ввода путей к каталогам.

Альтернатива стеку каталогов

Если вы используете оконную систему, вы можете открыть несколько окон и перейти в другой каталог в каждом из них. Затем, переключая окна, вы можете переключаться между каталогами без использования стека.

Вероятно, вы захотите выбрать наиболее подходящий для ваших обстоятельств метод. Если вам просто нужно перейти в другой каталог, чтобы выполнить одну-две короткие команды, вы, скорее всего, воспользуетесь стеком. С другой стороны, если вам нужно неоднократно обращаться к содержимому файла при выполнении других команд, лучше оставить файл открытым в отдельном окне.

Позволяем оболочке находить каталоги за вас

Стек каталогов упрощает повторный переход в каталог после того, как вы в нём побывали, но вам всё равно придётся вводить имя каталога при первом переходе в него. Оболочка может упростить эту задачу, сократив количество вводимых имён каталогов. Оболочка выполняет эту задачу, позволяя вам настроить путь поиска в каталоге — механизм, аналогичный пути поиска команд.

Когда вы запускаете команду, вы обычно вводите только базовое имя команды (последний компонент полного пути к ней). Оболочка находит команду, просматривая каталоги, указанные в переменной path. Аналогичным образом, если вы задаёте переменную оболочки cdpath, оболочка понимает, что её значение — это список местоположений, в которых нужно искать, когда вы указываете аргумент каталога для команд cd или pushd. Другими словами, если вы введёте cd dir или pushd dir и оболочка не найдёт dir в текущем каталоге, она будет искать каталоги, указанные в cdpath[23]

Рисунок 13-1. Простое дерево каталогов

Предположим, что структура каталогов вашей учётной записи выглядит так, как показано на рисунке 13-1, и вы хотите последовательно перейти в каталоги Programs, shell, Mail и tokenscan. Если вы не задали cdpath, вам пришлось бы вводить пути следующим образом:

% cd ~/Projects/Programs
% cd ~/Projects/Books/shell
% cd ~/Mail
% cd ~/Projects/Programs/tokenscan

Большую часть этого ввода можно исключить, задав cdpath. Например, чтобы указать оболочке искать каталоги в вашем домашнем каталоге, а также в каталогах Projects, Books и Programs, задайте cdpath в файле ~/.cshrc следующим образом:

set cdpath = ( ~ ~/Projects ~/Projects/{Books,Programs} )

Теперь вы можете переходить в свои каталоги, вводя только их базовые имена:

% cd Programs
% cd shell
% cd Mail
% cd tokenscan

Дерево каталогов, показанное на рисунке 13-1, относительно простое; поэтому, если вы зададите cdpath для списка нескольких ключевых местоположений, вы сможете перейти в любой из каталогов, используя базовые имена. Если структура вашей учётной записи более обширная, у вас не всегда будет такая возможность. Однако, выбрав только те каталоги, в которых вы обычно выполняете текущие задачи, вы сможете значительно сократить или даже полностью отказаться от ввода путей[24].

Каталоги, указанные в cdpath, могут находиться где угодно, не только в вашей учётной записи. Например, системный администратор может часто переходить в подкаталоги /usr/spool с помощью таких команд, как:

% cd /usr/spool/lpd
% pushd /usr/spool/mqueue

В таком случае /usr/spool было бы хорошим дополнением к cdpath, потому что приведённые выше команды стали бы проще:

% cd lpd
% pushd mqueue

Один из каталогов, который не нужно включать в cdpath, — это текущий каталог (.), поскольку команды cd и pushd в любом случае сначала ищут его.

  1. Оболочка игнорирует cdpath для путей, которые начинаются с /, ./ или . ./, поскольку, начиная путь таким образом, вы явно «привязываете» его к корневому каталогу, текущему каталогу или родительскому каталогу текущего каталога. Это позволяет обойти механизм поиска, если вы хотите.
  2. Это означает, что по мере изменения ваших действий вам может потребоваться время от времени корректировать cdpath.
Ограничения cdpath

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

Использование алиасов и переменных для перемещения

В этом разделе рассказывается о том, как использовать алиасы, чтобы упростить выполнение команд по изменению каталога, и как использовать переменные для предоставления аргументов для этих команд.

Перемещение с помощью алиасов

Один из простых способов упростить навигацию по файловой системе — создать более короткие имена команд с помощью алиасов:

alias pu pushd
alias po popd

Некоторые идиоматические формы команды cd также легко превратить в алиасы. Те, что показаны ниже, позволяют вводить .., / или - для перехода в родительский каталог, корневой каталог или предыдущий каталог:

alias .. cd ..
alias / cd /
alias - cd -             # (Этот работает только в tcsh)

Если вы часто посещаете определённые места, алиасы могут упростить доступ к ним. Системному администратору, который часто работает в каталоге очереди почты или в /usr/adm, могут пригодиться следующие алиасы:

alias mq cd /usr/spool/mqueue
alias adm cd /usr/adm

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

alias ui cd /usr/include
alias uis cd /usr/include/sys
alias ul cd /usr/lib
Перемещение с помощью переменных

К часто используемым каталогам можно получить доступ с помощью переменных, а не алиасов. Например, чтобы получить альтернативный способ перехода в /usr/include, задайте переменную в файле ~/.cshrc следующим образом:

set ui = /usr/include

Затем используйте переменную в командах для смены каталога:

% cd $ui
% pushd $ui

Смена каталога с помощью алиаса обычно требует меньше нажатий клавиш, чем смена с помощью переменных, потому что вы набираете одно слово (ui), а не два (cd $ui). Однако алиас можно использовать только одним способом (для перехода в заданный каталог). Переменную, которая ссылается на каталог, можно использовать множеством других способов. Например, вы можете получить доступ к содержимому каталога независимо от вашего местоположения:

% ls $ui/sys             # Список файлов в /usr/include/sys
% more $ui/stdio.h       # Просмотр /usr/include/stdio.h
% grep NFILE $ui/*.h     # Поиск файлов в /usr/include по NFILE

В tcsh переменные, указывающие пути, также можно использовать для завершения имени файла:

% more $ui/me            # Введите префикс, затем нажмите TAB
% more $ui/memory.h      # tcsh завершает имя
Объединение алиасов и переменных

Алиасы и переменные предоставляют несколько отличающиеся друг от друга удобства. Чтобы воспользоваться преимуществами обоих, используйте их вместе. Предположим, вы управляете установкой Usenet и выполняете задачи, которые часто требуют использования следующих каталогов:

/usr/lib/news                  # Каталог библиотеки новостей
/usr/log/news                  # Каталог журналов новостей
/usr/spool/news                # Каталог очереди новостей
/usr/spool/news/out.going      # Каталог исходящей очереди новостей

Чтобы перемещаться между этими каталогами и получать доступ к их файлам, вы можете добавить в файл ~/.cshrc определения переменных и алиасов, показанные ниже:

set nlib = /usr/lib/news
set nlog = /usr/log/news
set nspool = /usr/spool/news
set nout = $nspool/out.going
alias nlib cd $nlib
alias nlog cd $nlog
alias nspool cd $nspool
alias nout cd $nout

Алиасы позволяют быстро перемещаться по любому из четырёх основных каталогов. Переменные позволяют легко получать доступ к файлам и подкаталогам, даже если вы не находитесь в нужном каталоге:

% emacs $nlib/newsfeeds        # Редактировать /usr/lib/news/newsfeeds
% ls $nspool/junk | wc -l      # Подсчитать статьи в /usr/spool/news/junk
% tail -f $nlog/news.notice    # Наблюдать за /usr/log/news/news.notice
% du $nout                     # Проверить размер очереди 
                               # в /usr/spool/news/out.going

Этот же метод можно применить к любой задаче, связанной с частым использованием определённого набора каталогов, например, при разработке программного обеспечения в проекте с несколькими каталогами, управлении FTP-архивом или ведении списка рассылки.

Глава 14
Отслеживание вашего местоположения

В этой главе:

Когда вы активно работаете в каталоге, вы обычно можете запомнить свое текущее местоположение. Однако:

Один из способов определить своё местоположение — использовать командную строку. Команда pwd («print working directory») показывает название текущего каталога, команда dirs выводит список каталогов, а на большинстве компьютеров команды hostname, uname -n или who am i показывают название компьютера, на котором вы вошли в систему. Однако есть и более эффективные способы узнать своё местоположение. В этой главе рассказывается о том, как настроить файл ~/.cshrc, чтобы оболочка автоматически предоставляла эту информацию, и вам не приходилось тратить время на выполнение команд, чтобы понять, где вы находитесь.

Типы отчётов о местоположении

Один из способов получения информации о местоположении — заставить оболочку сообщать об изменениях в каталоге при использовании команд cd, pushd или popd. Команды pushd и popd автоматически выводят список каталогов. Чтобы команда cd делала то же самое, добавьте её в файл ~/.cshrc следующим образом:

alias cd 'cd \!*;dirs'

Альтернативная стратегия обеспечивает непрерывную передачу данных о местоположении. Эта стратегия позволяет мгновенно определять ваше местоположение независимо от того, меняете ли вы каталог. Непрерывная передача данных особенно полезна в многосессионной среде, где часто приходится переключаться между окнами.

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

Поскольку цель отображения текущего местоположения — информировать вас во время работы в командной строке, команды в ~/.cshrc, которые настраивают отображение, нужно выполнять только для интерактивных оболочек. Вы должны поместить эти команды в следующую конструкцию, которая определяет, является ли оболочка интерактивной, проверяя переменную prompt:

if ($?prompt) then
    commands to set up location display
endif

prompt имеет значение по умолчанию только в интерактивных оболочках. Поэтому неинтерактивные оболочки (например, те, которые запускаются для выполнения сценариев или для выполнения команд оболочки из редактора или почтового клиента) пропускают команды внутри оператора if.

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

Отображение вашего местоположения в командной строке

csh и tcsh различаются по средствам, которые они предоставляют для вывода информации в вашу командную строку. Сначала я покажу команды, которые работают в обеих командных оболочках, но предназначены в первую очередь для пользователей csh. Во-вторых, я расскажу о специальных возможностях форматирования строки приглашения в tcsh. Для обеих оболочек я покажу несколько типичных настроек приглашения. Вы, конечно, можете поэкспериментировать, чтобы найти настройки, которые лучше соответствуют вашим предпочтениям.

Использование csh для отображения вашего местоположения

Чтобы добавить имя хоста в приглашение, установите переменную prompt в файле ~/.cshrc следующим образом:

set prompt = "`hostname`%"

Если в вашей системе имя компьютера отображается не командой hostname, выполните соответствующую замену.

Чтобы включить в приглашение имя текущего каталога, создайте алиас setprompt, который устанавливает приглашение с использованием текущего местоположения. (setprompt использует переменную cwd, которая всегда содержит путь к текущему рабочему каталогу.) Затем создайте алиасы для команд изменения каталога (cd, pushd, popd), чтобы они вызывали setprompt. Добавьте следующие команды в файл ~/.cshrc, чтобы приглашение состояло из символа %, перед которым будет указан путь к текущему каталогу:

alias setprompt 'set pronpt = "$cwd% "'
setprompt
alias cd 'cd \!*;setprompt'
alias pushd 'pushd \!*;setprompt'
alias popd 'popd \!*;setprompt'

Обратите внимание, что setprompt выполняется после его определения. Это необходимо для установки начального значения подсказки. В противном случае приглашение не будет отображаться до тех пор, пока вы не измените каталог в первый раз.

Если вы хотите отображать только последнюю часть (последний компонент) пути к текущему каталогу, измените $cwd на $cwd:t в определении setprompt:

alias setprompt 'set prompt = "$cwd:t% "'

Если вы хотите, чтобы в командной строке отображались имя хоста и текущий каталог, измените определение setprompt на одно из приведённых ниже. В каждом определении отображаются имя хоста и имя каталога, но в первом определении отображается полный путь, а во втором — только последний компонент:

alias setprompt 'set prompt = "`hostname`:$cwd% "'
alias setprompt 'set prompt = "`hostname`:$cwd:t% "'

Для первого определения ваша подсказка может выглядеть следующим образом:

viper: /usr/staff/dubois% cd /usr/spool/mqueue
viper: /usr/spool/mqueue% cd ~/Projects/Programs/tokenscan
viper: /usr/staff/dubois/Projects/Programs/tokenscan%

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

viper:dubois% cd /usr/spool/mqueue
viper:mqueue% cd ~/Projects/Programs/tokenscan
viper:tokenscan%
Использование многострочного приглашения

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

alias setprompt 'set prompt = "$cwd%"'

затем измените его на этот:

alias setprompt 'set prompt = "-- $cwd --\\
% "'

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

-- /usr/staff/dubois --
% cd /usr/spool/mqueue
-- /usr/spool/mqueue --
% cd ~/Projects/Programs/tokenscan
-- /usr/staff/dubois/Projects/Programs/tokenscan --
%

Разбиение приглашения на несколько строк дает вам достаточно места для отображения информации и предоставляет вам всю ширину терминала для ввода команд. Формат также помогает вам находить символ %, сохраняя его на постоянном расстоянии от края экрана, даже если длина имени каталога различается.

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

Использование tcsh для отображения вашего местоположения

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

Вот несколько полезных последовательностей для отображения имени каталога или компьютера:

%/

Полное имя текущего каталога.

%~

Текущий каталог с использованием ~ или ~name в качестве сокращений для первой части пути (если возможно). %~ обычно приводит к более коротким подсказкам, чем %/.

%c

Последний компонент текущего каталога (все, что находится после последней косой черты в полном пути).

%cn

Последние n компонентов текущего каталога, например, %c2 для последних двух компонентов. %cn сокращает пути так же, как %~.

%cOn

Как %cn, за исключением того, что при выводе приглашения, если путь к каталогу содержит более n компонентов, количество пропущенных компонентов указывается специальным префиксом. Например, /3 указывает на 3 пропущенных компонента. В качестве альтернативы, если вы хотите, чтобы пропущенные компоненты обозначались многоточием (...), установите переменную оболочки ellipsis в файле ~/.cshrc следующим образом:

set ellipsis
%C, %Cn, %C0n

Как %c, %cn и %cOn, но без использования сокращения пути ~.

%m, %M

Первый компонент машины или полное имя. Для имени, например xyz.corp.com, %m — это xyz, а %M — это xyz.corp.com.

%%

Символ %. % за которым следует обычный символ (например, пробел), также преобразуется в %.

Например, чтобы настроить приглашение так, чтобы оно отображало текущий каталог с помощью обозначения, вам нужно добавить только следующую команду в файл ~/.cshrc:

set prompt = "%~% "

Чтобы задать приглашение в виде host:dir%, где host — это первый компонент имени хоста, а dir — текущий каталог, используйте следующую команду:

set prompt = "%m:%~% "

Если вам нужно многострочное приглашение, добавьте в строку приглашения символ новой строки. Предыдущую команду set prompt можно переписать следующим образом:

set prompt = "-- %m:%~ --\
% "

Отображение местоположения в заголовке окна

Если вы используете оконную систему, вы также можете отображать информацию о местоположении в строке заголовка окон терминала. В следующем разделе объясняется, как это сделать для xterm (терминальной программы X Window System), и даются некоторые советы по адаптации инструкций xterm для других программ.

В этом разделе используются несколько коротких последовательностей команд для запуска файлов. Если вы не хотите их вводить, вы можете получить их из архива, упомянутого в приложении C, Другие источники информации. Архив также содержит команды для изменения строки заголовка для программ, отличных от тех, которые рассматриваются здесь, а также документацию по управляющим последовательностям xterm, упомянутым ниже.

Взаимодействие с xterm

Вы можете указать заголовок окна в качестве аргумента командной строки при запуске xterm или в качестве значения ресурса в ~/.Xdefaults, но ни один из этих методов не подходит для постоянного изменения заголовка при перемещении по файловой системе. Однако xterm также понимает определенные управляющие последовательности, одна из которых задает заголовок окна. Эта последовательность может быть отправлена в xterm в любое время с помощью echo, а затем заголовок может быть изменен по запросу. Для систем BSD UNIX команда echo для установки заголовка окна в значение title выглядит следующим образом:

echo -n "ESC]2;titleCTRL-G"

Для версий UNIX на базе System V команда немного отличается:

echo "ESC]2;titleCTRL-G\c"

Обе команды подавляют новую строку, которую обычно выводит команда echo. (Новая строка не является частью управляющей последовательности; если вы не подавляете её, xterm пропускает новую строку в ваше окно, и вы получаете нежелательную пустую строку.) Команды echo отличаются только тем, что команда BSD echo использует флаг -n для подавления новой строки, а команда System V echo вместо этого использует \c. Вам нужно будет выбрать команду, подходящую для вашей системы. Если вы не знаете, какую команду использовать, попробуйте первую, а затем, если вы видите -n в своём окне при каждом изменении заголовка, переключитесь на вторую команду. В приведённых ниже примерах используется версия BSD; при необходимости выполните соответствующую замену.

Настройка заголовка окна в xterm

Чтобы настроить оболочку так, чтобы она отображала ваше местоположение в заголовке, настройте отправку xterm последовательности смены заголовка при каждом изменении каталога. Вы можете сделать это, создав алиасы для cd, pushd и popd так же, как мы настроили команды для изменения приглашения в csh ранее в этой главе.

Создайте в своём домашнем каталоге файл .settitle, содержащий приведенные ниже команды:

alias settitle 'echo -n "ESC]2;$cwdCTRL-G"'
settitle
alias cd 'cd \!*;settitle'
alias pushd 'pushd \!*;settitle'
alias popd 'popd \!*;settitle'

Чтобы ввести в файл с помощью редактора буквальные символы ESC и CTRL-G, вам может потребоваться ввести перед ними CTRL-V.

При желании вы можете изменить определение алиаса settitle. Чтобы в заголовке отображался только последний компонент вашего каталога, измените $cwd на $cwd:t в команде echo, как показано ниже:

alias settitle 'echo -n "ESC]2;$cwd:tCTRL-G"'

В качестве альтернативы вы можете отобразить стек каталогов. Возможность сразу увидеть весь стек полезна при использовании pushd +n и =n для ссылки на элементы стека в аргументах команд. Чтобы отобразить стек каталогов, используйте следующую команду:

alias settitle 'echo -n "ESC]2;`dirs`CTRL-G"'

После создания команды settitle добавьте следующую строку в файл ~/.cshrc:

if (xterm =~ $TERM) source ~/.settitle

xterm устанавливает переменную среды TERM в значение xterm, что позволяет оболочке определять, работает ли она в окне xterm. Если окно xterm активно, команды в .settitle выполняются; в противном случае команды пропускаются (например, если вы используете терминал ASCII или входите в систему через модем со своего домашнего компьютера).

Установка заголовка окна в других терминальных программах

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

HP-UX hpterm

Терминальная программа HP-UX hpterm использует другую последовательность для установки заголовка окна, чем xterm. К сожалению, часть этой последовательности — это длина строки заголовка. В tcsh есть операторы для определения длины строки, а в csh их нет. Кроме того, вы можете сгенерировать последовательность с помощью следующего короткого скрипта на perl:

#!/usr/local/bin/perl
printf "\e&f0k%dD%s", length ($ARGV[0]), $ARGV[0] unless $#ARGV < 0;

Если вы назовете скрипт hptitle, вы сможете использовать hptitle string в алиасе settitle для установки заголовка окна hpterm[25]. Создайте в домашнем каталоге файл .settitle-hp, который выглядит следующим образом:

alias settitle 'hptitle "$cwd"'
settitle
alias cd 'cd \!*;settitle'
alias pushd 'pushd \!*;settitle'
alias popd 'popd \!*;settitle'

Затем добавьте следующую строку в ~/.cshrc, чтобы обрабатывать .settitle-hp при запуске окна hpterm:

if (hpterm =~ $TERM) source ~/.settitle-hp

Если вы используете как xterm, так и hpterm, вы можете использовать более подробный тест для обработки файла, соответствующего типу окна:

if (xterm =~ $TERM) then
    source ~/.settitle
else if (hpterm =~ $TERM) then
    source
endif
  1. Установите скрипт на perl в каталог, указанный в вашей переменной path, например ~/bin. Возможно, вам потребуется изменить первую строку скрипта, чтобы она отражала расположение perl в вашей системе. В архиве, упомянутом в приложении C, Другие источники информации, есть короткая программа на C, которая эквивалентна и работает быстрее, если вы готовы её скомпилировать.
NCSA Telnet для Macintosh

Управляющая последовательность xterm для установки строки заголовка работает с NCSA Telnet 2.6 для Macintosh, если вы выберете «Последовательности xterm» в диалоговом окне настроек терминала[26]. К сожалению, NCSA Telnet не устанавливает переменную TERM, поэтому вы не можете проверить эту переменную, чтобы определить, следует ли автоматически выполнять команду .settitle. Чтобы обойти эту проблему, добавьте в файл ~/.cshrc алиас ncsa в дополнение к проверке переменной TERM:

if (xterm =~ $TERM) source ~/.settitle
alias ncsa source ~/.settitle

Если вы используете NCSA Telnet, то можете указать оболочке выполнить .settitle, введя ncsa после входа в систему.

  1. Вы попадаете в это диалоговое окно, выбрав Preferences/Terminals в меню Edit.

Собираем все вместе

Ниже приведен полный пример для ~/.cshrc, который выводит информацию о местоположении в строке заголовка окна при запуске xterm или hpterm, а в остальных случаях — в командной строке:

if ($?prompt) then                    # verify that shell is interactive
    if (xterm =~ $TERM) then          # xterm is running
        source ~/.settitle
    else if (hpterm =~ $TERM) then    # hpterm is running
        source ~/.settitle-hp
    else                              # xterm/hpterm are not running
        if ($?tcsh) then              # shell is tcsh
            set prompt = "%~% "
        else                          # shell is csh
            alias setprompt 'set prompt = "$cwd:t% "'
            setprompt
            alias cd 'cd \!*;setprompt
            alias pushd 'pushd \!*;setprompt
            alias popd 'popd \!*;setprompt
        endif
        alias ncsa source ~/.settitle
    endif
endif

Самый внешний if-тест гарантирует, что только интерактивные оболочки обрабатывают внутренние команды. Эти внутренние команды определяют, являются ли xterm или hpterm запущенными, и предпринимают соответствующие действия:

Отображение других типов информации

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

Отображение имени пользователя

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

Чтобы отобразить ваше имя в командной строке с помощью tcsh, просто добавьте %n в настройку переменной prompt. В следующем примере отображается name@host:dir%:

set prompt = "%n@%m:%~% "

Чтобы отобразить имя в командной строке csh, измените алиас setprompt, чтобы он ссылался на соответствующую переменную среды (вероятно, USER или LOGNAME, в зависимости от того, какая у вас система; здесь мы будем использовать USER). Например, чтобы отобразить имя пользователя и последний компонент имени каталога, используйте определение setprompt, которое выглядит так:

alias setprompt 'set prompt = "${USER} $cwd:t% "'

Чтобы отобразить имя пользователя в заголовке окна, измените алиас settitle в файле .settitle. Следующее определение отображает name@host, за которым следует стек каталогов:

alias settitle 'echo -n "ESC]2;${USER}@`hostname` `dirs`CTRL-G"'

В tcsh имя хоста доступно в переменной среды HOST. Обращение к переменной более эффективно, чем выполнение команды hostname, поэтому алиас можно переписать следующим образом:

alias settitle 'echo -n "ESC]2;${USER}@${HOST} `dirs`CTRL-G"'
Настройка значка окна в xterm

Управляющая последовательность xterm для изменения текста значка окна аналогична той, которая устанавливает строку заголовка, как показано ниже:

echo -n "ESC]1;stringCTRL-G"

Если вы используете команду echo в алиасе, вы можете легко задать текст значка. Следующий алиас seticon задает значок для name@host:

alias seticon 'echo -n "ESC]1;${USER}@`hostname`CIRL-G"'

Если вы используете tcsh, используйте следующий алиас seticon:

alias seticon 'echo -n "ESC]1;${USER}@${HOST}CTRL-G"'

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

alias seticon 'echo -n ESC]1;\!*CTRL-G"'

Глава 15
Управление заданиями

В этой главе:

Каждая команда, которую вы вводите, запускает то, что оболочка называет заданием. Оболочка отслеживает все задания, которые не были завершены, и предоставляет средства для управления этими заданиями. В результате вы получаете большой контроль над выполнением ваших команд. Управление заданиями имеет множество применений:

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

Состояния заданий

Вы запускаете задание, введя команду. Задание может находиться в одном из трёх состояний: на переднем плане, в фоновом режиме или остановлено (приостановлено)[27]. Обычно команда выполняется как задание на переднем плане:

% grep include *.[ch]      # Запустить задание на переднем плане

Если вы завершаете командную строку символом &, оболочка запускает фоновое задание и выводит номер задания и идентификатор процесса:

% tar xf archive.tar &     # Запустить задание в фоновом режиме
[1] 27163                  # Оболочка выводит номер задания и ID процесса

Если вы нажмете CTRL-Z[28] во время выполнения задания на переднем плане, задание прекратит выполнение и будет приостановлено:

% sort mydata > mydata2    # Запустите задание на переднем плане
CTRL-Z                    # Приостановите его
Stopped                    # Оболочка сообщает, что задание остановлено

Одновременно может существовать только одно задание на переднем плане, но вы можете остановить или запустить несколько заданий в фоновом режиме.

Если вы обнаружите, что не можете остановить задания, вы можете предпринять два действия. Во-первых, убедитесь, что у вас задан символ приостановки:

% stty susp ^z

Во-вторых, некоторые системы требуют явного указания «нового» драйвера терминала, чтобы управление заданиями работало:

% stty new

Попробуйте выполнить приведенные выше команды в командной строке. Если какая-либо из них включает управление заданиями, добавьте ее в свой файл ~/.login. В противном случае, возможно, ваша система просто не поддерживает управление заданиями. Проконсультируйтесь со своим системным администратором.

  1. Термины «остановлен» и «приостановлен» взаимозаменяемы; оба означают, что работа не выполняется.
  2. Или любой другой символ, который вы используете. Если вы не знаете, что это такое, см. главу 5, Настройка терминала.

Получение информации о заданиях

Команда jobs сообщает о любых заданиях, которые выполняются в фоновом режиме, и о любых остановленных заданиях. На рисунке 15-1 показан список заданий, который может появиться во время сеанса анализа набора файлов данных.

Рисунок 15-1: Пример вывода команды jobs

Если задание состоит из конвейера с несколькими командами, завершенные команды в конвейере отображаются в другой строке, чем те, которые все еще выполняются. Третье задание на рисунке 15-1 демонстрирует этот тип отображения: grep и cut завершили выполнение, но anova все еще работает.

jobs -l отображает задания в длинном формате. Длинный формат сообщает ID процесса вместе с обычной информацией.

В tcsb вы можете настроить автоматическое выполнение заданий при их остановке, если зададите переменную оболочки listjobs в файле ~/.cshrc следующим образом:

set listjobs

Если вы предпочитаете, чтобы выполнялось jobs -l, задайте для listjobs значение long, как показано ниже:

set listjobs = long
Определение времени завершения заданий

По умолчанию, когда задание завершается (или иным образом изменяет состояние), командная оболочка сообщает вам, что задание завершено, только когда она должна напечатать другое приглашение[29]. Если вы хотите получать уведомления немедленно, установите переменную командной строки notify в вашем файле ~/.cshrc, как показано ниже:

set notify

set notify обеспечивает более быстрое уведомление. Однако, если уведомление появляется в середине вывода другой команды, вы можете не заметить его в общей суматохе. Возможно, это не будет проблемой, поскольку вы всегда можете использовать jobs, чтобы узнать, выполняется ли задание. Попробуйте использовать оба способа уведомления и выберите наиболее удобный.

  1. Таким образом, если вы запустите команду в фоновом режиме, а затем просто подождете, пока оболочка сообщит вам, когда задание будет выполнено, этого никогда не произойдет. Вам нужно, по крайней мере, время от времени нажимать RETURN, чтобы получить новое приглашение.
Текущие и предыдущие задания

Выходные данные jobs указывают на два специальных задания: текущее и предыдущее. Эти задания отмечены знаками + и - рядом со столбцом состояния (смотрите четвертое и первое задания на рисунке 15-1). Когда задание остановлено (или переведено в фоновый режим, когда остановленных заданий нет), оно становится текущим заданием. Любое задание, которое было текущим в то время, становится предыдущим заданием. Когда текущее задание завершается, предыдущее задание снова становится текущим заданием.

Изменение состояния задания

Задание можно перевести из одного состояния (активное, фоновое или приостановленное) в любое другое. Команды, используемые для управления заданиями, перечислены в таблице 15-1; %j обозначает задание, с которым вы хотите работать. Команды fg, bg, kill и stop могут принимать несколько аргументов задания, каждый из которых обрабатывается по очереди. В таблице 15-2 показаны различные формы, которые может принимать %j.

Таблица 15-1: Команды управления заданиями
Команда Действие команды
CTRL-Z Остановить задание на переднем плане
CTRL-C Прервать (завершить) задание на переднем плане
fg %j Вывести остановленное или фоновое задание на передний план
bg %j Переместить остановленное задание в фоновый режим
kill %j Убеить (завершить) остановленное или фоновое задание
stop %j Остановить фоновое задание
suspend Приостановить текущую оболочку (если это не оболочка для входа в систему)
jobs Отобразить текущий список заданий
Таблица 15-2: Спецификаторы заданий
Спецификатор Задание, на которое ссылается спецификатор
% Текущее задание (%+ и %% являются синонимами %)
%- Предыдущее задание
%n Номер задания n
%str Задание, командная строка которого начинается с str
%?str Задание, командная строка которого содержит str

Часто проще ссылаться на задание по имени, чем по номеру, хотя %str и %?str неоднозначны, если они соответствуют более чем одному заданию в вашем списке заданий. В таких случаях оболочка выдает предупреждение. Например, в нашем списке заданий есть два задания, начинающиеся с vi, и два задания, содержащие reference.ms. В результате следующие команды являются неоднозначными:

% fg %vi
%vi: Ambiguous.
% fg %?ref
%?ref: Ambiguous.

Если вы используете %?str для обращения к заданию и оболочка отвечает No match, оболочка интерпретирует ? как символ сопоставления с образцом. Если это происходит, попробуйте экранировать ? обратной косой чертой, то есть использовать %\?str. В некоторых версиях оболочки обратная косая черта требуется для fg, bg, kill и stop. В других она требуется только для kill и stop.

Команды управления заданиями, которые вы используете для управления заданиями, переводя их из одного состояния в другое, описаны в следующих разделах и обобщены на рисунке 15-2.

Остановка задания

CTRL-Z останавливает текущее задание на переднем плане. Некоторые программы игнорируют CTRL-Z, например, vi нельзя остановить, если вы находитесь в режиме вставки.

Чтобы остановить фоновое задание, используйте команду stop. Например, любая из следующих команд остановит конвейер grep/cut/anova, показанный на рисунке 15-1:

% stop %3
% stop %gr
% stop %?ano

Вы также можете остановить фоновый процесс, выведя его на передний план (см. «Возобновление процесса» ниже), а затем нажав CTRL-Z.

Остановка остановленного процесса не имеет эффекта, как показано ниже:

% stop %1
%1: Already stopped

Рисунок 15~2: Команды, перемещающие задания из одного состояния в другое

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

Возобновление работы

fg выводит на передний план остановленную или выполняемую в фоновом режиме работу:

% fg %4   # Возобновить выполнение второй команды vi
% fg %pr  # Переместить задание на печать из фонового режима на передний план

bg возобновляет остановленное задание в фоновом режиме. Если вы запускаете команду и решаете, что она выполняется слишком долго, вы можете остановить ее с помощью CTRL-Z, а затем использовать bg, чтобы переместить ее в фоновый режим. После этого вы можете продолжить работу над другими задачами.

Если фоновое задание пытается считывать данные с терминала, оно останавливается. Чтобы взаимодействовать с заданием, выведите его на передний план.

Сокращённые формы команд fg и bg

Команды fg и bg имеют несколько сокращённых форм:

Эти правила проиллюстрированы в таблице 15-3.

Таблица 15-3: Альтернативные формы команд fg и bg
Команды fg Синоним(ы) Команды bg Синоним(ы)
fg % fg или % bg % bg или %
fg %3 %3 bg %3 %3&
fg %pr %pr bg %pr %pr&
fg %?ano %?ano bg %?ano %?ano&

Завершение задания

Задание может быть завершено, если оно остановлено, выполняется на переднем плане или в фоновом режиме. Символ прерывания (обычно CTRL-C) обычно завершает текущее задание на переднем плане. Если задание остановлено или выполняется в фоновом режиме, используйте команду kill. Например, чтобы завершить задание 5, выполните следующие действия:

% kill %5
[5]    Terminated             pr Results2 | lpr

В качестве альтернативы выведите задание на передний план, а затем нажмите CTRL-C.

Задания сохраняют присвоенный им номер. Например, если вы завершите задание 1, задания 2 и выше не будут перенумерованы.

Завершение «упрямых» заданий

Некоторые задания перехватывают CTRL-C и поэтому не могут быть завершены с его помощью. В этом случае попробуйте остановить задание с помощью CTRL-Z, а затем выполните команду завершения. Иногда даже команда kill не завершает работу (некоторые программы перехватывают сигнал, который посылает команда kill). В таких случаях можно использовать команду kill -9, чтобы отправить сигнал, который невозможно перехватить.

Приостановка работы оболочки без входа в систему

Команда suspend заданиий работает только во вложенных оболочках (не являющихся оболочками входа в систему). Она приостанавливает работу во вложенной оболочке и возвращает вас в родительскую оболочку. Вы можете возобновить работу во вложенной оболочке, как и в случае с любым другим заданием, с помощью fg.

Приостановка suspend особенно полезна для вложенных оболочек, запущенных с помощью su, поскольку вам нужно вводить пароль только при запуске во вложенной оболочке. После этого вы можете просто переходить во вложенную оболочку и выходить из неё. suspend ещё удобнее, если у вас одна из тех раздражающих версий su, которая не считывает файл ~/.cshrc учётной записи, на которую вы переключаетесь. В таких случаях su вынуждает вас явно считывать его (выполнять source) при запуске подоболочки. С suspend вам нужно считывать файл только один раз.

Чтобы упростить использование suspend, добавьте следующий алиас в ~/.cshrc учётной записи, на которую вы переключаетесь:

alias z suspend

Другие способы применения управления заданиями

В этом разделе описаны другие способы применения управления заданиями.

Управление выводом заданий в фоновом режиме

Запуск команды в фоновом режиме удобен, если вы хотите заниматься другими делами во время выполнения задания, но команда может выводить результаты на терминал в неудобное время. Если вы редактируете файл или составляете электронное письмо, вам может не понадобиться, чтобы фоновое задание выводило результаты на весь экран. Или, если у вас несколько фоновых заданий, их выходные потоки могут мешать друг другу. Чтобы избежать этих проблем, вы можете использовать следующую команду, чтобы принудительно останавливать фоновые задания, когда они будут готовы выводить результаты на терминал:

% stty tostop

Когда вы будете готовы увидеть вывод фонового задания, которое остановлено в ожидании записи, выведите его на передний план.

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

% stty -tostop

Следующая последовательность команд иллюстрирует разницу между stty tostop и stty -tostop:

% stty tostop                       # Включение tostop
% date &                            # Запустить команду в фоновом режиме
[1] 24980                           # Оболочка сообщает номер задания и ID процесса
[1]  + Suspended (tty output) date  # Задание остановится, когда будет готово к выводу
% fg                                # Вывод задания на передний план
date                                # Оболочка повторяет командную строку
Mon Sep 12 11:59:14 CDT 1994        # Задание записывает вывод
% stty -tostop                      # Выключение tostop
% date &                            # Запустить команду в фоновом режиме
[1] 24982                           # Оболочка печатает номер задания и ID процесса
Mon Sep 12 11:59:21 CDT 1994        # Задание записывает выходные данные без остановки
[1]    Done       date              # Оболочка уведомляет вас о завершении задания

Чтобы указать тип вывода, который вы хотите получить для фоновых заданий, добавьте соответствующую команду stty в свой файл ~/.login.

Фоновые интерактивные задания

Интерактивные команды обычно предполагают чтение и запись в ваш терминал. Некоторые интерактивные команды, такие как more и vi, бесполезны в фоновом режиме, потому что они сразу же пытаются прочитать данные с терминала и останавливаются. Но другие команды можно запускать в фоновом режиме во время длительной операции, которая не требует вашего внимания. Например, если вы используете анонимный FTP для передачи файлов, последовательность команд FTP может выглядеть примерно так:

% ftp some.machine.name
User: anonymous
Password: (type your e-mail address here)
ftp> cd pub
ftp> mode binary
ftp> get software.tar.Z
ftp> bye

Если операция get выполняется медленно, вы можете заняться другой работой. Для этого запустите ftp в интерактивном режиме до команды get, затем остановите задание и переведите его в фоновый режим:

% ftp some.machine.name
User: anonymous
Password: (type your e-mail address here)
ftp> cd pub
ftp> mode binary
ftp> get software.tar.Z
CTRL-Z
Stopped.
% bg
[1]  ftp some.machine.name &

Если вы переведёте ftp в фоновый режим, передача будет продолжаться, пока вы занимаетесь другими делами. После завершения передачи ftp попытается прочитать терминал, чтобы получить от вас следующую команду, и остановится. Затем оболочка сообщает вам, что ftp ожидает продолжения ввода:

[1]  + Stopped (tty input)  ftp some.machine.name

Верните задание на передний план, чтобы возобновить сеанс ftp:

% fg       # Вывести ftp на передний план

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

Использование управления заданиями для повышения скорости отклика системы

Если у вас так много фоновых заданий, что система работает неприемлемо медленно, вам, вероятно, следует остановить некоторые из них. Предположим, что вы запускаете множество больших заданий сортировки в фоновом режиме:

% sort data1 -o data1 &
[1] 8273
% sort data2 -o data2 &
[2] 8274
.
.
.
% sort data10 -o data10 &
[10] 8282

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

% stop %2 %3 %4 %5 %6 %7 %8 %9 %10

После завершения первого задания снова запустите второе задание в фоновом режиме:

% %2 &

Когда второе задание завершится, перезапустите третье задание и т. д. В качестве альтернативы вы можете перезапускать задания последовательно, как показано ниже:

% %2 ; %3 ; %4 ; %5 ; %6 ; %7 ; %8 ; %9 ; %10

Контроль работы и оконные системы

Если вы используете систему, которая позволяет открывать несколько окон терминала, вы можете переключаться между окнами в качестве альтернативной формы управления заданиями (например, если команда выполняется медленно в одном окне, вы можете переключиться на другое окно). Однако, даже если у вас есть доступ к нескольким окнам, есть причины использовать управление заданиями:

Мне удобнее использовать несколько окон, если мне нужно переключаться между задачами и если каждая задача требует полноэкранного отображения. В остальном я обычно нахожу, что проще переключаться между заданиями в одном окне с помощью управления заданиями.

Часть III
Приложения

Приложение A
Получение и установка tcsh

В этом приложении:

В этом приложении описано, как получить, собрать, протестировать и установить tcsh. На момент написания этой статьи tcsh имеет версию 6.06. Если была выпущена более новая версия, просто замените номер версии 6.06 на новый в следующих командах, в которых он встречается.

Первым шагом при установке tcsh является определение того, установлена ли в вашей системе актуальная версия tcsh. Если да, то вам не нужно ничего делать, кроме как изменить оболочку входа в систему на tcsh. (См. раздел «Выбор оболочки» в главе 1, Введение.) В противном случае вам необходимо получить текущую версию, а затем установить ее.

Чтобы узнать, установлена ли tcsh и каков ее путь, обратитесь к системному администратору или выполните следующую команду:

% which tcsh

Если tcsh присутствует, определите его версию с помощью следующей команды. Используйте одинарные кавычки, как показано, но замените фактическое имя пути, если оно отличается от /bin/tcsh:

% /bin/tcsh -c 'echo $version'
tcsh 6.00.02 (Cornell) 08/05/91 options 8b,nls,dl,al,dir

Если вывод этой команды указывает на то, что ваша версия tcsh является старой (как в приведённом выше примере), скачайте текущую версию и установите её.

Получение исходного дистрибутива

Исходный дистрибутив tcsh доступен в Интернете по анонимному FTP. Подключитесь к ftp.deshaw.com, перейдите в каталог /pub/tcsh и загрузите файл tcsh-6.06.tar.gz в двоичном режиме. После получения дистрибутива распакуйте его и извлеките файлы:

% gunzip < tcsh-6.06.tar.gz | tar xf -

Или, в системах System V:

% gunzip < tcsh-6.06.tar.gz | tar xof -

Если у вас нет gunzip, укажите имя файла без суффикса .gz как tcsh-6.06.tar при получении дистрибутива. FTP-сервер распакует файл за вас. Затем выполните одну из следующих команд:

% tar xf tcsh-6.06.tar        # (Для систем, отличных от System V)
% tar xof tcsh-6.06.tar       # (Для систем System V)

Команда tar создаст каталог tcsh-6.06 в вашем текущем каталоге. Перейдите в этот каталог с помощью команды cd tcsh-6.06, и вы готовы начать процесс сборки.

Если вы хотите использовать браузер World Wide Web для получения дистрибутива, используйте следующий URL-адрес:

ftp://ftp.deshaw.com/pub/tcsh/tcsh-6.06.tar.gz

Или, чтобы получить несжатую версию:

ftp://ftp.deshaw.com/pub/tcsh/tcsh-6.06.tar

После получения файла распакуйте его, следуя приведённым выше инструкциям.

Если вы не можете подключиться к ftp.deshaw.com, дистрибутив также доступен на ftp.gw.com в каталоге /pub/unix/tcsh и на ftp.primate.wisc.edu в каталоге /pub/csh-tcsh-book.

Создание дистрибутива — краткие инструкции

Если вам не терпится, вы можете попробовать создать дистрибутив быстро, чтобы приступить к работе раньше.

Если на вашем компьютере установлены imake, xmkmf и файлы конфигурации X11, вы сможете собрать tcsh следующим образом:

% xmkmf            # Сгенерировать Makefile из Imakefile
% make depend      # Сгенерировать зависимости (опционально)
% make             # Собрать tcsh

Если вы не используете imake, создайте Makefile из стандартного шаблона и используйте его для сборки tcsh:

% cp Makefile.std Makefile        # Скопировать Makefile из стандартного шаблона
% cp config/fiie config.h         # Создать файл config.h из соответствующего
                                  # файла в каталоге config
% make                            # Собрать tcsh

Если команда make выполнена успешно, у вас должен быть исполняемый файл tcsh, независимо от используемого вами метода. Перейдите к разделу «Тестирование и установка tcsh». В противном случае воспользуйтесь подробными инструкциями в следующем разделе для сборки tcsh.

Сборка дистрибутива — подробные инструкции

Если быстрая сборка не работает или вы хотите просмотреть и, возможно, изменить параметры конфигурации, следуйте инструкциям, приведённым в этом разделе. Прежде чем продолжить, прочтите всю описанную ниже процедуру.

Файлы, содержащие информацию о сборке tcsh, перечислены ниже:

Перед продолжением я рекомендую ознакомиться с этими файлами.

Обзор процесса сборки

Вот краткое описание шагов, необходимых для сборки tcsh:

При настройке для сборки tcsh вам может потребоваться внести изменения в один или несколько файлов, упомянутых выше. Используйте следующую процедуру, чтобы сохранить копию любого файла, который вам нужно изменить:

% cp file file.orig    # Сохранить копию исходного файла
% chmod 644 file       # Сделать рабочую копию доступной для
                       # записи, чтобы вы могли ее изменить

Таким образом, у вас останется исходный файл для справки, пока вы будете изменять рабочую копию.

Выберать каталог установки

Прежде чем собирать tcsh, подумайте о том, где вы собираетесь его установить. По умолчанию каталог установки — /usr/local/bin, но вы можете изменить его. Например, я устанавливаю tcsh в /bin, чтобы иметь возможность использовать его даже при отключённой файловой системе /usr.

tcsh лучше всего устанавливать в один из каталогов в стандартном пути поиска вашей системы, чтобы обеспечить доступ к нему для всех пользователей вашей системы. Если у вас нет разрешения на установку файлов в какой-либо из этих каталогов, попросите системного администратора установить tcsh для вас.

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

Во многих случаях каталог, используемый в скомпилированном пути и в командах установки, совпадает. Например, вы можете скомпилировать путь к /bin/tcsh в tcsh, а затем установить полученный двоичный файл в /bin.

Однако вы можете захотеть настроить эти два каталога так, чтобы они отличались друг от друга. Возможно, вам нужна стабильность, чтобы иметь возможность ссылаться на tcsh с помощью фиксированного имени, например /bin/tcsh, но вы также можете захотеть иметь возможность размещать исполняемый файл в любом месте, например /usr/local/new/tcsh. Этих целей можно достичь, используя /bin/tcsh в качестве скомпилированного пути и установив tcsh в /usr/local/new, а затем сделав /bin/tcsh символической ссылкой на /usr/local/new/tcsh. В качестве альтернативы вы можете провести различие между скомпилированным путем и местом, где на самом деле установлен tcsh, если ваши системы работают в среде, использующей NFS или AFS для совместного использования файловых систем по сети.

Настроить Makefile

Makefile управляет процессом сборки, генерируя команды, необходимые для компиляции промежуточных объектных файлов и окончательного исполняемого файла tcsh.

Если вы используете imake, Makefile генерируется из Imakefile и imake.config с помощью команды xmkmf. Изучите imake.config, чтобы понять, нужно ли вносить какие-либо изменения. Если вы хотите изменить путь, по которому компилируется tcsh, определите TcshPath. Например, чтобы использовать /bin/tcsh, добавьте следующую строку:

idefine TcshPath /bin/tcsh

Чтобы изменить каталог, используемый командами установки, определите DestBin следующим образом:

#define DestBin /bin

Страница руководства по умолчанию устанавливается в /usr/local/man/man1/tcsh.1. Если вы хотите изменить это расположение, определите DestMan как каталог установки, а ManSuffix — как расширение, используемое для файла в этом каталоге. Например, чтобы установить tcsh.man в /usr/man/mann/tcsh.n, добавьте в imake.config следующие строки:

#define DestMan /usr/man/mann
#define ManSuffix n

После того как вы просмотрели imake.config и внесли необходимые изменения, создайте Makefile и сгенерируйте исходный файл зависимостей как показано ниже[30]:

% xmkmf            # Сгенерировать Makefile
% make depend      # Сгенерировать зависимости (необязательно)

Если вы не используете imake, процесс настройки будет другим. Сначала создайте Makefile для работы, скопировав шаблон Makefile.std:

% cp Makefile.std Makefile  # Скопировать рабочий Makefile из Makefile.std
% chmod 644 Makefile        # Сделать его доступным для записи

Затем отредактируйте Makefile, чтобы выбрать подходящие параметры конфигурации для вашей системы. В Makefile содержится много информации о настройках для разных систем, и вы также можете ознакомиться с Ported, чтобы узнать, какие специальные флаги могут потребоваться для вашей машины. (Системы одного производителя не обязательно перечислены в Ported вместе; обязательно просмотрите весь список, чтобы найти наиболее подходящую для вашей системы.)

Ниже перечислены наиболее важные параметры конфигурации. Обязательно ознакомьтесь с возможными настройками в Makefile и выберите наиболее подходящие для вашей системы:

CC
Компилятор C
DFLAGS
Флаги -D и -U для передачи компилятору C
LDFLAGS
Флаги загрузчика (компоновщика)
LIBES
Библиотеки ссылок
CFLAGS
Специальные флаги для передачи компилятору C

Для каждого параметра может быть несколько возможных настроек, описанных в Makefile. Ведущий символ # используется для того, чтобы сделать каждый параметр комментарием, кроме одного, который является параметром по умолчанию. Чтобы выбрать другой параметр, поставьте # перед параметром по умолчанию и уберите ведущий # из параметра, который вы хотите использовать.

Если вы собираетесь установить tcsh в другое место, отличное от места по умолчанию, вам нужно внести два изменения в Makefile. Предположим, вы хотите установить tcsh в /hin/tcsh. Сначала укажите путь, который будет скомпилирован в двоичный файл tcsh. Найдите строку DFLAGS, которую вы используете, и добавьте в неё определение для макроса _PATH_TCSHELL. Если строка DFLAGS выглядит так:

DFLAGS=

то измените её на следующую (не забудьте ввести кавычки, как показано):

DFLAGS= -D_PATH_TCSHELL='"/bin/tcsh"'

(Если DFLAGS имеет непустое значение, просто добавьте -D_PATH_TCSHELL='"/bin/tcsh"' в конец существующего значения.)

Во-вторых, при установке tcsh укажите каталог, который будет использоваться командами установки. Найдите строку, которая устанавливает переменную DESTBIN:

DESTBIN = $(TCSHTOP)/bin

Измените эту строку на следующую:

DESTBIN = /bin

Чтобы изменить место установки справочной страницы, укажите DESTMAN на каталог установки и MANSECT на расширение файла в этом каталоге. Чтобы установить tcsh.man в /usr/man/mann/tcsh.n, настройки должны выглядеть следующим образом:

DESTMAN = /usr/man/mann
MANSECT = n
  1. Если вы позже измените файл Imakefile или imake.config, вам нужно будет повторно запустить xmkmf и команду make depend, чтобы обновить Makefile и зависимости.
Настройка config.h

config.h содержит некоторые общие системные флаги конфигурации, используемые во время компиляции. config.h — это один из файлов в каталоге конфигурации.

Если вы используете intake, вам не нужно создавать config.h. В файле Makefile, созданном на основе Imakefile, есть команда, которая создает config.h, выбирая нужный файл из каталога конфигурации.

Если вы не используете imake, изучите каталог config и определите, какой из файлов лучше всего подходит для вашей системы. Затем скопируйте файл в основной каталог дистрибутива tcsh в качестве config.h. Например, файл hpux8 работает как в HP-UX 8.xx, так и в HP-UX 9.xx. На моём HP 715 с HP-UX 9.05 я делаю следующее:

% cp config/hpux8 config.h    # Создать config.h из файла поставщика
% chmod 644 config.h          # Сделать config.h доступным для записи

Обычно вам не нужно изменять файл config.h, но вы можете изучить его на случай, если какие-то незначительные изменения будут полезны. (Если вы всё-таки решите изменить config.h, сначала сделайте его копию для справки, потому что оригинал будет удалён, если вы позже запустите команду make clean.)

Настройка файла config_f.h

Файл config_f.h содержит несколько флагов компиляции, которые включают или отключают различные возможности tcsh. Изучите его, чтобы понять, нужно ли вам изменить какой-либо из флагов. Например, если в вашей системе нет файла locale.h и вы не можете скомпилировать программу с поддержкой системы национальных языков (NLS), включите эту функцию, заменив следующую строку:

#define NLS

на эту:

#undef NLS

Если вы хотите, чтобы редактор команд tcsh по умолчанию использовал сочетания клавиш vi, а не emacs, замените следующую строку:

#undef VIDEFAULT

на эту:

#define VIDEFAULT
Компиляция tcsh

После того как вы отредактировали файлы сборки, чтобы в них были правильные параметры конфигурации, сгенерируйте tcsh, как показано ниже:

% make

Если команда make не создаёт исполняемый файл tcsh, посмотрите последнюю часть файла README, чтобы узнать, есть ли известные способы решения возникающих проблем. Также прочтите файл FAQ и раздел Ported, чтобы убедиться, что вы не пропустили какие-либо флаги, необходимые для сборки tcsh в вашей системе.

Если у вас возникли проблемы с imake, свяжитесь со мной по адресу dubois@primate.wisc.edu.

Перенос tcsh в новую систему

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

После этого отправьте свои изменения по адресу tcsh@mx.gw.com, чтобы их можно было включить в будущие версии.

Тестирование и установка tcsh

После сборки tcsh вы должны протестировать его, как показано ниже:

% ./tcsh                     # Запустите только что собранный tcsh
% # ...run some commands...  # Посмотрите, как это работает
% exit                       # Завершите работу

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

Когда вы убедитесь, что tcsh работает стабильно, установите двоичный файл и справочную страницу с помощью следующих команд:

% make install         # Установить двоичный файл tcsh
% mate install .man    # Установить справочную страницу

Если у вас возникнут проблемы, попробуйте определить, при каких обстоятельствах они возникают. Ознакомьтесь с файлами README и FAQ и убедитесь, что вы скомпилировали tcsh со всеми необходимыми для вашей системы специальными флагами.

Сделать tcsh оболочкой входа в систему

После установки tcsh вы почти закончили. Последний шаг — убедиться, что tcsh можно использовать в качестве оболочки для входа в систему. Обычно оболочку для входа в систему выбирают с помощью команды chsh или passwd -s. Эти команды, вероятно, потребуют, чтобы tcsh был зарегистрирован в системе как доверенная оболочка. Кроме того, ваш FTP-сервер может отклонять подключения к учетным записям, для которых в качестве оболочки входа используется tcsh, если tcsh не зарегистрирован как доверенная оболочка.

Наиболее распространённым способом информирования системы о том, какие оболочки являются доверенными, является файл /etc/shells. Чтобы узнать, относится ли это к вам, проверьте, существует ли страница руководства getusershell(5). Как правило, список доверенных оболочек определяется следующим образом:

Записи в /etc/shells должны быть полными путями. Ниже приведен пример из одной из моих систем:

/bin/sh
/bin/csh
/bin/ksh
/bin/tcsh

После изменения /etc/shells попробуйте изменить оболочку входа в систему на tcsh, чтобы убедиться, что система её принимает. Вы также сможете подключиться к своему компьютеру с помощью ftp, используя обычное имя пользователя и пароль, как показано ниже:

% ftp yourhost
Name: youmame
Password: yourpassword
Если ваша система не использует /etc/shells

Некоторые системы используют не /etc/shells, а другой файл для определения допустимых оболочек, и этот файл может иметь другой формат. Например, в AIX /etc/shells заменяется строкой shell= в /etc/security/login.cfg. Для получения более подробной информации обратитесь к документации вашей системы.

Приложение B
Краткий справочник по csh и tcsh

В этом приложении:

В этом приложении кратко описаны функции и характеристики оболочки. Примеры и дополнительные комментарии можно найти в других разделах этого руководства. См. также справочные страницы csh и tcsh.

Структура команд

Простая команда (обозначенная и описанная ниже) состоит из имени команды, за которым может следовать один или несколько аргументов. Эта базовая форма может быть изменена или объединена с другими командами для формирования более сложных последовательностей команд:

cmd               # Выполнить cmd
cmd &             # Выполнить cmd в фоновом режиме
cmd > file        # Записать вывод cmd в file (перезаписать file)
cmd >> file       # Записать вывод cmd в file (дописать file)
cmd < file        # Получить ввод в cmd из file
cmd1 ; cmd2       # Выполнить cmd1, затем cmd2
cmd1 | cmd2       # Записать вывод cmd1 в качестве ввода для cmd2
(cmd1 ; cmd2)     # Выполнить cmd1 и cmd2 в подоболочке
cmd1 `cmd2`       # Использовать cmd2 для создания аргументов для cmd1

Файлы запуска и завершения работы

При запуске оболочка считывает один или несколько файлов из вашего домашнего каталога и, возможно, один файл при завершении работы. Файлы описаны в следующей таблице. Если какой-либо из указанных файлов не существует, ошибка не возникает.

Файл Описание
~/.cshrc Читается при запуске
~/.tcshrc Читается вместо ~/.cshrc, если он существует (только для tcsh — если вы используете tcsh, читайте ссылки на ~/.cshrc как «~/.tcshrc, если он существует, в противном случае ~/.cshrc»)
~/.login Читается оболочками входа в систему при запуске
~/.history Читается оболочками входа в систему при запуске для инициализации списка истории
~/.cshdirs Читается оболочками входа в систему при запуске для инициализации стека каталогов (только для tcsh)
~/.logout Читается оболочками входа в систему при завершении работы

При запуске оболочка входа в систему последовательно считывает ~/.cshrc, ~/.history, ~/.login и (только для tcsh) ~/.cshdirs. Оболочка без входа в систему при запуске считывает только ~/.cshrc.

При завершении работы оболочка входа в систему считывает ~/.logout и записывает ~/.history и (только для tcsh) ~/.cshdirs, если заданы соответствующие переменные. (~/.history сохраняется, если задана переменная savehist. В tcsh ~/.cshdirs сохраняется, если задана переменная savedirs.) Оболочка без входа в систему просто завершает работу.

Чтобы выполнить команды в ~/.cshrc, которые будут применяться только к интерактивным оболочкам, поместите их в следующую конструкцию:

if ($?prompt) then
    commands
endif

Чтобы выполнять команды только для tcsh, поместите их в эту конструкцию:

if ($?tcsh) then
    commands
endif

Переменные

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

Некоторые полезные переменные оболочки перечислены в таблице ниже.

Переменная Описание
autologout Если установлено, автоматический выход из системы происходит после того, как вы не будете активны в течение часа. Если установлено число, выход из системы происходит после указанного количества минут бездействия. Некоторые оболочки по умолчанию устанавливают autologout при входе в систему. Чтобы отключить, удалите параметр autologout в ~/.cshrc.
cdpath Список каталогов, в которых командная оболочка ищет каталоги, указанные в качестве аргументов для cd или pushd.
correct Если установлено значение cmd, включается коррекция орфографии для названий команд. Если установлено значение all, включается коррекция орфографии для всей командной строки (только для tcsh).
cwd Устанавливается оболочкой в ваш текущий рабочий каталог при изменении вашего каталога.
fignore Список суффиксов имен файлов. Имена файлов, заканчивающиеся на любой из этих суффиксов, игнорируются при заполнении имени файла.
filec В csh включается функция завершения имени файла. (Не требуется для tcsh.)
history Если задано, указывает количество команд для сохранения в списке истории.
home Путь к вашему домашнему каталогу.
ignoreeof Если этот параметр установлен, сочетание клавиш CTRL-D не завершает работу командной строки. Вам необходимо явно ввести exit или logout.
mail Путь к файлу, который необходимо периодически проверять на наличие новой почты.
notify Если этот параметр установлен, оболочка немедленно уведомляет вас о завершении фоновых заданий. В противном случае она ожидает непосредственно перед следующим запросом.
path Список каталогов, в которых оболочка выполняет поиск команд.
prompt Ваша строка запроса. Устанавливается только для интерактивных оболочек. Можно протестировать, чтобы отличить интерактивные оболочки от неинтерактивных.
rmstar Если задано, tcsh спросит, «действительно ли вы это имеете в виду», когда увидит символ *, указанный в качестве аргумента для команды rm (только для tcsh).
savedirs Если этот параметр установлен, оболочки входа в систему сохраняют стек каталогов в ~/.cshdirs при выходе из системы. Стек считывается обратно при повторном входе в систему (только tcsh).
savehist Если этот параметр установлен, оболочки входа в систему сохраняют список истории в ~/.history при выходе из системы. Список истории будет прочитан при повторном входе в систему.
shell Путь к вашей командной строке входа в систему.
tcsh Задайте номер версии tcsh (только tcsh; можно сначала протестировать, чтобы отличить tcsh от csh).
term Ваш тип терминала.
user Ваше имя пользователя (логин).
version Информация о версии оболочки и конфигурации (только для tcsh).

Многие переменные среды (например, HOME, PATH, SHELL, TERM и USER) используются как соответствующие переменные оболочки с именами в нижнем регистре. Другие полезные переменные среды перечислены в таблице ниже.

Переменная Описание
DISPLAY Спецификация отображения, используемая системой X Window.
EDITOR Путь к предпочитаемому вами редактору.
HOST Текущее имя компьютера (только для tcsh).
LOGNAME Как USER.
PWD Как cwd.
VISUAL Путь к предпочитаемому вами полноэкранному редактору.
Определение, удаление и изучение переменных

Вы можете определять переменные оболочки и среды, проверять их значения или удалять их, как указано ниже.

Команда Описание
set var Определение переменной оболочки без значения (просто включить)
set var = value Определение переменной оболочки с явным значением
set var = (str1 str2 str3) Определение переменной оболочки со значением, состоящим из нескольких строк
setenv VAR value Определение переменной среды
set Отображение всех значений переменных оболочки
setenv Отображение всех значений переменных среды
unset var Удаление переменной оболочки
unsetenv VAR Удаление переменной среды

Доступная только для чтения переменная оболочки может быть определена с помощью set -r вместо set. Доступные только для чтения переменные нельзя изменять или удалять.

Переменные оболочки обычно устанавливаются в ~/.cshrc. Переменные среды обычно устанавливаются в ~/.login.

Использование переменных

Чтобы использовать переменную, называйте ее $name или ${name}. Модификаторы могут быть применены к ссылке на переменную (в виде $name:m или ${name:m}), чтобы извлечь часть значения переменной.

Модификатор Описание
r Корень значения (все, кроме расширения после точки)
e Расширение значения (суффикс после точки)
h Начало значения (все, кроме последнего компонента пути)
t Конец значения (последний компонент пути)

Специальные символы

Несколько символов имеют особое значение для оболочки.

Символ(ы) Описание
* ? [ ] ^ { } ~ Сопоставление и расширение шаблона имени файла
$ Ссылка на переменную
| Канал
< > Перенаправление ввода и вывода
! ^ Ссылка на историю и быстрая замена
& Фоновое выполнение
; Разделитель команд
SPACE Разделитель аргументов
TAB Завершение имени файла (tcsh)
ESC Завершение имени файла (csh)
(...) Выполнение подоболочки
`...` Замена команды
\ ' " Экранирование символов
Специальные символы в именах файлов

Аргументы имени файла могут содержать следующие специальные символы для сопоставления с образцом или подстановки домашнего каталога.

Символ(ы) Описание
* Соответствует последовательности символов произвольной длины
? Соответствует одному символу
[...] Соответствует любому символу, указанному в скобках
[^...] Соответствует любому символу, не указанному в скобках (только в tcsh)
^pattern Соответствует именам файлов, не соответствующим шаблону (только tcsh)
{...} Оператор расширения строки
~ Расширяет до пути к вашему домашнему каталогу
~name Расширяет до пути к домашнему каталогу для пользователя name

Экранирование

Экранирование отключает любое специальное значение символа, позволяя использовать его как обычный символ.

Символ(ы) Описание
\ Экранировать следующий символ.
'...' Экранировать символы, заключенные в одинарные кавычки. !event по-прежнему оценивается как подстановка из истории.
"..." Экранировать символы, заключенные в двойные кавычки. !event, $var и `cmd` по-прежнему оцениваются как подстановки из истории, переменных и команд.

История команд

Механизм истории оболочки позволяет вам вспоминать предыдущие события (команды), а затем повторять их. Чтобы включить историю команд, установите переменную history в ~/.cshrc на количество событий, которые вы хотите, чтобы оболочка запоминала. Чтобы сохранять историю при входе в систему, установите переменную savehist в оболочке.

Команда history отображает вашу текущую историю:

history
Показать весь список истории
history n
Показать последние n событий из списка истории
Спецификаторы событий истории

Ссылки на историю начинаются с символа !. Когда оболочка видит такую ссылку, она заменяет её в командной строке, выводит на экран полученную команду и выполняет её.

Перечисленные ниже спецификаторы событий выбирают команды из списка истории:

Спецификатор Описание
!! Повторить предыдущую команду
!n Повторить команду n
!-n Повторить предпоследнюю команду
!str Повторить последнюю команду, начинающуюся с str
!?str? Повторить последнюю команду, содержащую str
!# Повторить текущую командную строку, набранную до сих пор
Обозначения слов

Перечисленные ниже обозначения слов извлекают определённые слова из события:

Обозначение Описание
0 Слово 0 (имя команды)
n Слово n (аргумент n)
^ Слово 1
$ Последнее слово
m-n Слова с m по n
-n Слова с 0 по n
m- Слова с m по (но не включая) последнее слово
- Слова с 0 по (но не включая) последнее слово
m* Слова с m по последнее слово
* Слова с 1 по последнее слово или пустые, если аргументов нет
% После спецификатора события !?str? слово, соответствующее str

Обозначения слов обычно отделяются от предшествующего спецификатора события двоеточием. Однако можно использовать некоторые сокращения: если обозначение начинается с *, ^, $ или %, можно опустить двоеточие; если вы применяете обозначение к предыдущей команде (!!), можно сократить !! до !; и можно обозначить все аргументы, первый аргумент или последний аргумент предыдущей команды с помощью !*, !^ или !$.

Модификаторы истории

Чтобы исправить или изменить слово из предыдущей команды, используйте ^old^new:

% mroe file1 file2 file3
mroe: Command not found.
% ^ro^or
more file1 file2 file3

Другие модификаторы перечислены ниже. Они добавляются к ссылкам на историю, которые начинаются с !, и отделяются от ссылки двоеточием.

Модификатор Описание
r Корень имени файла (все, кроме расширения после точки)
e Расширение имени файла (суффикс после точки)
h Начало пути (все, кроме последнего компонента)
t Конец пути (последний компонент)
s/old/new/ Выполнить подстановку, заменив old на new
& Повторить предыдущую s замену
g Применить модификатор после g глобально к каждому слову
p Вывести результирующую команду, не выполняя ее
q Заключить слова в кавычки (предотвращает расширение шаблона имени файла)
x Как q, но разбить на слова через пробел
u Сделать первую строчную букву прописной (только tcsh)
l Сделать первую строчную букву строчной (только tcsh)
a Применить модификаторы после a как можно больше раз к слову. Если используется с g, то a применяется ко всем словам (только в tcsh)

Перемещение по файловой системе

Чтобы перемещаться по файловой системе, вы указываете имя каталога в качестве аргумента команды смены каталога. Приведённые ниже каталоги имеют специальные имена.

Имя Описание
. Текущий каталог
.. Родительский каталог текущего каталога
~ Ваш домашний каталог
~name Домашний каталог для имени пользователя

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

cd               # Перейти в ваш домашний каталог
cd dir1          # Перейти на один уровень ниже в каталог dir1
cd dir1/dir2     # Перейти на два уровня ниже, через каталог dir1 в каталог dir2
cd ..            # Подняться на один уровень вверх до родительского каталога
cd ../..         # Подняться на два уровня вверх до родительского каталога родительского каталога
cd ../dir3       # Подняться на один уровень вверх, затем вернуться в каталог dir3
cd /             # Перейти в корневой каталог (верхнюю часть файловой системы)
cd ~dubois       # Перейти в домашний каталог пользователя dubois
cd -             # Перейти в последнее местоположение (только для tcsh)

Оболочка поддерживает стек каталогов. Элементы стека нумеруются, начиная с 0. Команды pushd и popd изменяют каталог (как cd), но они также добавляют и удаляют элементы из стека, как показано ниже:

pushd dir      # Добавить dir в стек и перейти в него
pushd          # Поменять местами две верхние записи в стеке
pushd +n       # Провернуть стека так, чтобы элемент n оказался сверху
popd           # Удалить верхний элемент и вернуться к предыдущему элементу
popd +n        # Удалить элемент n из стека (tcsh, некоторые версии csh)

Команда dirs отображает или очищает стек каталогов:

dirs         # Отобразить стек
dirs -l      # Отобразить стек с использованием полных имен (без сокращений ~name)
dirs -n      # Отобразить стек, завершая вывод (только в tcsh)
dirs -v      # Отобразить стек, включая номера записей, по одной строке на запись (только в tcsh)
dirs -c      # Очистить стек (только в tcsh)

В tcsh флаги -l, -n и -v также могут использоваться с командами cd, pushd и popd и имеют то же значение, что и для dirs.

В tcsh ввод =n в начале аргумента команды эквивалентен вводу значения записи стека n. =- относится к последней записи. С аргументами, начинающимися с =n/ или =-/, можно использовать автозаполнение имён файлов.

Алиасы

Алиасы позволяют присваивать командам или последовательностям команд короткие имена. Вызов алиаса эквивалентен вызову соответствующих команд. Для создания или отображения определений алиасов, а также для удаления алиасов используйте следующие команды:

alias name definition   # Определение алиаса name
alias name              # Отобразить определение алиаса name
alias                   # Отобразить все определения алиасов
unalias name            # Удалить алиас name
unalias *               # Удалить все алиасы

Если определение содержит специальные символы, его следует заключить в кавычки.

При вызове алиаса любые аргументы добавляются в конец команды, к которой относится алиас. Чтобы разместить аргументы в определенном месте команды, используйте одну из следующих последовательностей в определении алиаса.

Последовательность Описание
\!* Все аргументы
\!^ Первый аргумент
\!$ Последний аргумент
\!:n Аргумент n

Завершение имени файла

Чтобы использовать завершение имени файла, введите префикс имени файла и нажмите клавишу завершения. Если префикс уникален, оболочка введет за вас оставшуюся часть имени файла. В противном случае она введет столько символов, сколько является общим для всех совпадений, а затем издаст звуковой сигнал. В tcsh клавиша завершения — TAB, и завершение имени файла всегда активно. В csh клавиша завершения — ESC; кроме того, для включения завершения имени файла необходимо установить переменную filec в ~/.cshrc.

Чтобы вывести список совпадений для префикса (например, если префикс неоднозначен), нажмите CTRL-D.

Слова, начинающиеся с ~, дополняются ссылками на домашний каталог. В tcsh слова, начинающиеся с $, дополняются как имена переменных, а слова, начинающиеся с =n, дополняются так, как если бы они начинались с каталога, имя которого указано в стеке каталогов n.

Если для переменной fignore оболочки задан список суффиксов имён файлов, то имена, заканчивающиеся на эти суффиксы, игнорируются при дополнении.

Запрограммированное дополнение

В tcsh можно задать запрограммированное дополнение с помощью команды complete, как показано ниже:

complete command word/pattern/list/suffix

command - это команда, к которой применяется завершение. Аргумент, следующий за командой, представляет собой правило завершения, которое определяет, как завершить слово или слова из команды. Хотя разделителем между частями правила завершения часто является дефис, это может быть любой символ.

Может быть более одного правила завершения. Каждое правило состоит из частей, перечисленных ниже.

Часть Описание
word Указывает, как выбирать слова из команды. Должно быть p, c, n, C или N (описано ниже).
pattern Определяет, к каким словам применяется правило.
list Список слов, из которых выбираются варианты завершения. Доступные списки описаны ниже.
suffix Необязательный суффикс, добавляемый к завершённым словам. Если он отсутствует, к завершённым именам каталогов добавляется косая черта, а в остальных случаях — пробел. Если он присутствует, должен быть одним символом. Если символ совпадает с разделителем между частями правила завершения, суффикс к завершенным словам не добавляется.

Спецификатор слова определяет, как интерпретируется pattern. Если word равно p, pattern указывает позицию слова или позиции, к которым применяется правило. В противном случае pattern - это шаблон имени файла, и правило применяется к любому слову, крайняя левая часть которого соответствует шаблону.

Слово Описание
p

Завершение на основе позиции, pattern — это число или диапазон чисел, указывающий, к каким словам применяется правило:

n        # Слово n
m-n      # Слова с m по n
m*       # Слова с m по последнее слово
*        # Все слова
c Завершить текущее слово (слово, соответствующее pattern). Часть, соответствующая шаблону, не считается частью префикса, который нужно завершить.
n Завершить следующее слово после слова, соответствующего pattern.
C Завершить текущее слово. В отличие от c, в качестве префикса, который нужно завершить, используется всё слово.
N Завершить слово, стоящее через два слова после слова, соответствующего pattern.

Списки слов, из которых можно выбрать дополнения, приведены ниже.

Список Описание
a Имена алиасов
b Имена привязок клавиш (команды редактора командной строки)
c Имена команд
d Имена каталогов
e Имена переменных среды
f Имена файлов (любого типа, включая имена каталогов)
g Имена групп
j Имена заданий
l Имена ограничений ресурсов
n Нулевой список (подавляет автозаполнение)
s Имена переменных оболочки
S Имена сигналов
t Имена текстовых файлов (фактически, любых файлов, не являющихся каталогами)
v Имена переменных (любого типа)
u Имена пользователей
X Имена команд, для которых задано автозавершение
x Пояснение; как n, но выведет сообщение при нажатии CTRL-D.
C, D, F, T Как c, d, f, t, но выберет автозавершение из заданного каталога.
(list) Выберет автозавершение из слов в заданном списке
$variable Выберет автозавершение из слов в значении переменной
`command` Выберет автозавершение из слов в выводе команды

Управление заданиями

Управление заданиями позволяет приостанавливать или завершать задания, а также перемещать задания между фоновым и основным режимами. Команды управления заданиями приведены ниже. При использовании %j указывает на интересующее задание.

Команда Описание
CTRL-Z Остановить задание на переднем плане
CTRL-C Прервать (завершить) задание на переднем плане
fg %j Вывести остановленное или фоновое задание на передний план
bg %j Переместить остановленное задание на задний план
kill %j Убить (завершить) остановленное или фоновое задание
stop %j Остановите фоновое задание
suspend Приостановить текущую оболочку (если это не оболочка входа в систему)
jobs Отобразить список текущих заданий

Идентификатор задания %j имеет следующие формы.

Спецификатор Описание
% Текущее задание (%+ и %% являются синонимами %)
%- Предыдущее задание
%n Номер задания n
%str Задание, командная строка которого начинается с str
%?str Задание, командная строка которого содержит str (если оболочка сообщает No match, используйте %\?str)

Команды fg и bg имеют сокращённые формы, перечисленные ниже.

Спецификатор Описание
%j Эквивалентно fg %j
fg или % Эквивалентно fg %
%j& Эквивалентно bg %j
bg или %& Эквивалентно bg %

Если задана переменная оболочки notify, оболочка немедленно уведомляет вас о завершении фоновых заданий. В противном случае уведомление появляется при выводе следующего приглашения.

Используйте stty, чтобы указать, могут ли фоновые задания записывать данные на ваш терминал, как показано ниже:

stty tostop      # Принудительно останавливать фоновые задания
                 # при готовности к записи на терминал
stty -tostop     # Разрешить фоновым заданиям запись на терминал

Редактирование команд в tcsh

tcsh позволяет в интерактивном режиме просматривать список истории, выбирая и редактируя команды перед их выполнением.

Используйте CTRL-P и CTRL-N (или стрелки вверх и вниз) для перемещения вверх и вниз по списку истории. Каждая вызванная команда отображается в текущей командной строке. Чтобы выполнить команду, нажмите RETURN. Чтобы отменить её, нажмите CTRL-C.

Для редактирования команд в tcsh предусмотрен редактор командной строки, использующий привязки клавиш emacs или vi. Выберите подходящий набор с помощью bindkey -e или bindkey -v соответственно. Некоторые из наиболее полезных команд редактирования приведены в оставшейся части этого раздела. (Используйте bindkey без аргументов, чтобы увидеть все свои привязки клавиш.)

Команды редактирования в режиме emacs

В режиме emacs символы вставляются в командную строку, если они не являются командами редактирования. Вы можете перемещать курсор или удалять символы с помощью приведенных ниже команд.

Команды перемещения курсора
Команда Описание
CTRL-B Переместить курсор назад (влево) на один символ
CTRL-F Переместить курсор вперед (вправо) на один символ
ESC b Переместить курсор назад на одно слово
ESC f Переместить курсор вперед на одно слово
CTRL-A Переместить курсор в начало строки
CTRL-E Переместить курсор в конец строки
Команды удаления текста
Команда Описание
DEL или CTRL-H Удалить символ слева от курсора
CTRL-D Удалить символ под курсором
ESC d Удалить слово
ESC DEL или ESC CTRL-H Удалить слово в обратном направлении
CTRL-K Удалить от курсора до конца строки
CTRL-U Удалить всю строку

Если перед командой ввести ESC n, команда будет повторяться n раз.

Чтобы найти в списке истории команду, содержащую строку, введите строку, а затем ESC p. Соответствующая команда будет добавлена в буфер редактирования. Чтобы найти команду в обратном направлении, введите строку и ESC n. Строка может содержать символы шаблона имени файла. Чтобы повторить поиск, просто введите ESC p или ESC n.

Команды редактирования в режиме vi

В режиме vi есть два режима редактирования. В режиме вставки все символы (за некоторыми исключениями, перечисленными ниже) вставляются в командную строку. В командном режиме символы интерпретируются как команды редактирования.

Нажмите ESC в режиме вставки, чтобы перейти в командный режим. В командном режиме несколько команд переводят в режим вставки до тех пор, пока вы не нажмете ESC. Если вы не знаете, в каком режиме находитесь, нажимайте ESC, пока не услышите звуковой сигнал tcsh, что означает, что вы оказались в командном режиме.

Некоторые распространённые команды для обоих режимов приведены ниже.

Команды перемещения курсора (в режиме вставки)
Команда Описание
CTRL-B Переместить курсор назад (влево) на один символ
CTRL-F Переместить курсор вперёд (вправо) на один символ
CTRL-A Переместить курсор в начало строки
CTRL-E Переместить курсор в конец строки
Команды удаления текста (в режиме вставки)
Команда Описание
DEL или CTRL-H Удалить символ слева от курсора
CTRL-W Удалить слово назад
CTRL-U Удалить от начала строки до курсора
CTRL-K Удалить от курсора до конца строки
Команды перемещения курсора (в командном режиме)
Команда Описание
w Переместить курсор вправо на одно слово
b Переместить курсор влево на одно слово
e Переместить курсор к следующему окончанию слова
W, B, E Как w, b и e, но с другим определением слова
^ или CTRL-A Переместить курсор к началу строки (к первому непробельному символу)
0 Переместить курсор к началу строки
$ или CTRL-E Переместить курсор к концу строки

w, b и e останавливаются на пробелах или знаках препинания. W, B и E останавливаются только на пробелах.

Команды перемещения по символам (командный режим)
Команда Описание
fc Переместить курсор к следующему экземпляру c в строке
Fc Переместить курсор к предыдущему экземпляру c в строке
tc Переместить курсор к следующему экземпляру c в строке
Tc Переместить курсор назад к предыдущему экземпляру c в строке
; Повторить предыдущую команду f или F
, Повторить предыдущую команду f или F в противоположном направлении
Команды вставки текста (командный режим)
Команда Описание
a Добавить новый текст после курсора до нажатия ESC
i Вставить новый текст перед курсором до нажатия ESC
A Добавить новый текст после конца строки до нажатия ESC
I Вставить новый текст перед началом строки до нажатия ESC
Команды удаления текста (командный режим)
Команда Описание
x Удалить символ под курсором
X или DEL Удалить символ слева от курсора
dm Удалить от курсора до конца команды перемещения m
D Синоним для d$
CTRL-W Удалить слово назад
CTRL-U Удалить от начала строки до курсора
CTRL-K Удалить от курсора до конца строки
Команды замены текста (командный режим)
Команда Описание
cm Изменить символы от курсора до конца команды перемещения m до ESC
C Синоним для c$
rc Заменить символ под курсором на символ c
R Заменить несколько символов до ESC
s Заменить символ под курсором на символы, введённые до ESC

В командном режиме vi вы можете повторять большинство команд. Просто введите количество повторений перед командой, например, 3dw, чтобы удалить три слова.

Чтобы выполнить поиск в списке истории в командном режиме vi, введите ? за которым следует строка, а затем нажмите RETURN. Чтобы выполнить поиск в обратном направлении, используйте /. Команда, содержащая строку, будет извлечена в буфер редактирования. Строка может содержать символы шаблона имени файла. Чтобы повторить поиск в том же или противоположном направлении, используйте n или N.

Команда bindkey

bindkey используется для выбора, проверки и определения привязок клавиш. Она имеет несколько форм:

bindkey -e            # Выберать привязки emacs
bindkey -v            # Выберать привязки vi
bindkey -d            # Восстановить привязки по умолчанию
bindkey -u            # Отобразить сообщение об использовании bindkey
bindkey -l            # Вывести список команд редактирования и их значения
bindkey               # Вывести список всех привязок клавиш
bindkey key           # Вывести список привязок для клавиши key
bindkey key cmd       # Привязать клавишу key к команде редактирования cmd
bindkey -c key cmd    # Привязать клавишу key к команде UNIX cmd
bindkey -s key str    # Привязать клавишу key к строке str
bindkey -r key        # Удалить привязку для клавиши key

bindkey -l выводит полный список названий команд редактирования с краткими описаниями каждой из них. Приложение C, Другие источники информации, содержит ссылку на документ, в котором более подробно описаны значения команд.

Перечисленные ниже флаги изменяют интерпретацию аргумента key. Флаги -k и -b не могут использоваться одновременно в одной команде.

Флаг Описание
-a Привязка ключа применяется к альтернативной раскладке (раскладке командного режима vi)
-k Позволяет использовать значение key как up, down, left или right для обозначения клавиши со стрелкой
-b Позволяет key быть C-X или M-X, чтобы указывать CTRL-X или META-X
-- Если key начинается с -, предшествующий флаг -- указывает bindkey не обрабатывать key как флаг

Символы в аргументе key могут быть обычными символами или одной из перечисленных ниже последовательностей для указания специальных символов.

Последовательность Символ, представляемый последовательностью
^X CTRL-X
^[ ESC
^? DEL
\^ ^
\a CTRL-G (звонок)
\b CTRL-H
\e ESC
\f FORMFEED
\n NEWLINE
\r RETURN
\t TAB
\v CTRL-K (вертикальная табуляция)
\nnn Символ ASCII с восьмеричным кодом nnn

Последовательности с символом «кавычки» имеют особое значение независимо от того, заключены они в кавычки или нет. Обратная косая черта в последовательностях с обратной косой чертой должна быть удвоена, если последовательность не заключена в кавычки.

\c для c, не показанного выше, создаёт буквальное c. CTRL-V CTRL-X создаёт буквальное CTRL-X

Те же последовательности можно использовать для аргументов cmd и str в bindkey -c и bindkey -s, за исключением того, что последовательности, начинающиеся с обратной косой черты, интерпретируются буквально внутри кавычек.

Приложение C
Другие источники информации

В этом приложении:

В этом приложении приведены ссылки на другие источники информации о csh и tcsh.

Документация

Перечисленные ниже документация доступна в различных местах в Интернете. Для вашего удобства я собрал ее в одном месте, которое я буду называть «архивом». Вы можете получить доступ к архиву с помощью браузера World Wide Web, используя следующий URL-адрес:

http://www.primate.wise.edu/software/csh-tcsh-book/index.html

Через анонимный FTP-сервер подключитесь к ftp.primate.wisc.edu и найдите каталог /pub/csh-tcshhook. Клиенты Gopher могут подключиться к gopher.primate.wisc.edu, выбрать пункт «Primate Center Software Archives», а затем выбрать «Using csh & tcsh».

Архив содержит следующие материалы:

Архив также содержит фрагменты команд и короткие программы для таких задач, как установка заголовков окон. В главе 14, Отслеживание того, где вы находитесь, описывается как они используются.

Группы новостей

Группа новостей Usenet comp.unix.shell служит центром обмена информацией по всем видам вопросов, связанных с оболочкой. Если у вас возникла проблема с оболочкой, которая, как вы подозреваете, характерна для реализации конкретного поставщика, также может быть полезна одна из других групп comp.unix.* или одна из групп comp.sys.*.

Списки рассылки

Для tcsh существует три списка рассылки.

Чтобы сообщить об ошибках, отправьте сообщение на адрес tcsh-bugs@mx.gw.com. Вам не нужно быть участником tcsh-bugs, чтобы отправить такое письмо, но, пожалуйста, убедитесь, что вы сообщаете об ошибке, а не просто о том, что вам непонятно. tcsh-bugs не предназначен для общих консультаций по tcsh. Поэтому не отправляйте вопросы в стиле «как мне ...?» или «как работает ...?». Такие вопросы останутся без ответа. Группа новостей comp.unix.shell — лучший форум для общих консультационных вопросов.

Списки рассылки tcsh и tcsh-diffs предназначены для разработчиков, которые хотят помогать поддерживать tcsh (обсуждать и внедрять новые функции и исправлять ошибки). Эти два списка связаны между собой. Подписчики tcsh-diffs получают весь трафик списка tcsh, а также исправления для каждого релиза разработки.

Чтобы подписаться на любой из этих списков, отправьте сообщение на адрес listserv@mx.gw.com. Тело сообщения (не строка темы) должно содержать одну из следующих строк:

subscribe tcsh-bugs Your Name
subscribe tcsh Your Name
subscribe tcsh-diffs Your Name

Замените Your Name на своё настоящее имя.

Об авторе

Пол Дюбуа — программист в Висконсинском региональном исследовательском центре приматов при Университете Висконсин-Мэдисон. Он ведет спокойную жизнь, у него мало интересов за пределами семьи, церкви и программирования.

Колофон

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

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

Животное, изображенное на обложке журналов Using csh and tcsh, — это пегий кулик-сорока, болотная береговая птица, обитающая на всех континентах, кроме Антарктиды. Эта поразительно выглядящая птица имеет резко контрастирующее черно-белое оперение, алые радужки и длинный ярко-оранжевый клюв, сжатый по бокам.

Большинство кулик-сорок образуют постоянные пары. Места их размножения обычно находятся на небольшом расстоянии вглубь материка от мест их нагула, и многие пары возвращаются на одно и то же место размножения каждую весну. Инкубационный период составляет от 25 до 28 дней, в среднем по три яйца на кладку. Кулик-сороки необычны среди береговых птиц тем, что они выкармливают своих детенышей в течение первых шести недель или около того. Рацион кулик-сорок состоит в основном из двустворчатых моллюсков, таких как ракушки, мидии и устрицы, крабов, барвинков, луговых и дождевых червей. Птенцы учатся охотиться на червей в возрасте шести недель, используя тельца Хербста, тактильные органы на своих клювах, чтобы находить их в песке. Однако кулик-сороке могут потребоваться годы, чтобы усовершенствовать технику вскрытия раковин моллюсков.

Существует два способа открывать раковины моллюсков: битьё и прокалывание. При битье раковина подносится к камню и по ней многократно бьют, пока она не откроется. При прокалывании кулик-сорока использует свой длинный клюв, чтобы поддеть приоткрывшуюся раковину и разорвать приводящие мышцы, которые удерживают её закрытой. Некоторые кулики-сороки бьют по раковине, а другие прокалывают её, в зависимости от того, какому способу их научили в детстве. Точно так же кулик-сороки едят либо моллюсков, либо крабов, опять же в зависимости от их воспитания. Известно, что птенцы, поедающие моллюсков, пугаются крабов.

Эди Фридман разработала дизайн обложки этой книги, используя гравюру 19 века из архива Dover Pictorial Archive. Макет обложки был выполнен с помощью Quark XPress 3-3 с использованием шрифта ITC Garamond.

Внутренняя вёрстка была разработана Эди Фридман и Нэнси Прист и реализована в gtroff Ленни Мюлльнером. Шрифты для текста и заголовков — ITC Garamond Light и Garamond Book. Иллюстрации, которые вы видите в книге, были созданы Крисом Рейли в Macromedia Freehand 5.0. Колофон был написан Клэрмари Фишер О’Лири. По возможности в наших книгах используется RepKover — прочный и гибкий переплёт. Если количество страниц превышает лимит RepKover, используется клеевой переплет.