Введение
Unix shell
C-шелл (csh или улучшенная версия, tcsh) — это Unix-оболочка, созданная Биллом Джоем, когда он был аспирантом Калифорнийского университета в Беркли в конце 1970-х годов. Она получила широкое распространение, начиная с выпуска 2BSD Berkeley Software Distribution (BSD), который Джой впервые распространил в 1978 году. Другими ранними участниками, внесшими вклад в идеи или код, были Майкл Убелл, Эрик Оллман, Майк О'Брайен и Джим Кулп. C-шелл — это командный процессор, который обычно запускается в текстовом окне, позволяя пользователю вводить и выполнять команды. C-шелл также может читать команды из файла, называемого скриптом. Как и все Unix-оболочки, он поддерживает подстановку имен файлов с использованием подстановочных знаков, конвейеры, here-документы, подстановку команд, переменные и структуры управления для проверки условий и итераций. C-шелл отличался от других, особенно в 1980-х годах, своими интерактивными возможностями и общим стилем. Новые функции сделали его использование более простым и быстрым. Общий стиль языка был больше похож на C и считался более читаемым. На многих системах, таких как macOS и Red Hat Linux, csh фактически является tcsh, улучшенной версией csh. Часто один из двух файлов является либо жесткой ссылкой, либо символической ссылкой на другой, так что любое имя указывает на одну и ту же улучшенную версию C-шелла. Оригинальный исходный код csh и исполняемый файл являются частью NetBSD. В Debian и некоторых производных дистрибутивах (включая Ubuntu) существует два разных пакета: csh и tcsh. Первый основан на оригинальной версии BSD csh, а второй — на улучшенном tcsh. tcsh добавил автодополнение имен файлов и команд, а также редактирование командной строки, заимствованные из системы Tenex, откуда и взялась буква "t" в названии. Поскольку tcsh только добавлял функциональность и не изменял существующую, он оставался обратно совместимым с оригинальным C-шеллом. Хотя он начинался как ответвление от исходного дерева кода, созданного Джоем, tcsh теперь является основной ветвью для текущей разработки. tcsh очень стабилен, но новые выпуски продолжают появляться примерно раз в год, в основном содержащие незначительные исправления ошибок.
Цели и особенности проектирования
Основными целями разработки C-shell были её большая схожесть с языком программирования C и улучшенная пригодность для интерактивной работы.
Скорее, как С.
Система Unix была написана почти исключительно на C, поэтому первоочередной задачей оболочки C было создание языка команд, более стилистически согласующегося с остальной системой. Ключевые слова, использование круглых скобок, встроенная грамматика выражений и поддержка массивов в оболочке C находились под сильным влиянием C.
By today's standards, C shell may not seem particularly more C like than many other popular scripting languages. But through the 80s and 90s, the difference was seen as striking, particularly when compared to Bourne shell (also known as sh), the then dominant shell written by Stephen Bourne at Bell Labs. This example illustrates the C shell's more conventional expression operators and syntax. The Bourne sh lacked an expression grammar. The square bracketed condition had to be evaluated by the slower means of running the external test program. sh's if command took its argument words as a new command to be run as a child process. If the child exited with a zero return code, sh would look for a then clause (a separate statement, but often written joined on the same line with a semicolon) and run that nested block. Otherwise, it would run the else. Hard linking the test program as both "test" and "[" gave the notational advantage of the square brackets and the appearance that the functionality of test was part of the sh language. sh's use of a reversed keyword to mark the end of a control block was a style borrowed from ALGOL 68. By contrast, csh could evaluate the expression directly, which made it faster. It also claimed better readability: Its expressions used a grammar and a set of operators mostly copied from C, none of its keywords were reversed and the overall style was also more like C.
Here is a second example, comparing scripts that calculate the first 10 powers of 2. Again because of the lack of an expression grammar, the sh script uses command substitution and the expr command. (Modern POSIX shell does have such a grammar: the statement could be written or .) Finally, here is a third example, showing the differing styles for a switch statement. In the sh script, ";;" marks the end of each case because sh disallows null statements otherwise.
По современным меркам оболочка C может показаться не намного более похожей на C, чем многие другие популярные скриптовые языки. Однако в 80-х и 90-х годах эта разница казалась разительной, особенно по сравнению с оболочкой Борна (также известной как sh), доминирующей в то время оболочкой, разработанной Стивеном Борном в Bell Labs. Этот пример иллюстрирует более привычные операторы и синтаксис выражений оболочки C. В оболочке Борна отсутствовала грамматика выражений. Условие в квадратных скобках приходилось вычислять более медленным способом – запуском внешней программы `test`. Команда `if` в sh воспринимала аргументы как новую команду для выполнения в качестве дочернего процесса. Если дочерний процесс завершался с кодом возврата 0, sh искал ветвь `then` (отдельное утверждение, но часто записываемое в одной строке с точкой с запятой) и выполнял этот вложенный блок. В противном случае выполнялась ветвь `else`. Символическая связь программы `test` под именами "test" и "[" давала преимущество в виде квадратных скобок и создавала впечатление, что функциональность `test` является частью языка sh. Использование sh обратных ключевых слов для обозначения конца блока управления было заимствовано из ALGOL 68. В отличие от этого, csh могла вычислять выражение напрямую, что делало её быстрее. Она также заявляла о лучшей читаемости: её выражения использовали грамматику и набор операторов, в основном скопированных из C, ни одно из её ключевых слов не было перевернуто, а общий стиль также был больше похож на C. Вот второй пример, сравнивающий скрипты, вычисляющие первые 10 степеней числа 2. Опять же, из-за отсутствия грамматики выражений, в скрипте sh используется подстановка команд и команда `expr`. (Современная оболочка POSIX имеет такую грамматику: оператор может быть записан как или .) Наконец, вот третий пример, демонстрирующий различные стили для оператора `switch`. В скрипте sh ";;" обозначает конец каждого случая, поскольку sh не допускает пустые операторы.
By today's standards, C shell may not seem particularly more C like than many other popular scripting languages. But through the 80s and 90s, the difference was seen as striking, particularly when compared to Bourne shell (also known as sh), the then dominant shell written by Stephen Bourne at Bell Labs. This example illustrates the C shell's more conventional expression operators and syntax. The Bourne sh lacked an expression grammar. The square bracketed condition had to be evaluated by the slower means of running the external test program. sh's if command took its argument words as a new command to be run as a child process. If the child exited with a zero return code, sh would look for a then clause (a separate statement, but often written joined on the same line with a semicolon) and run that nested block. Otherwise, it would run the else. Hard linking the test program as both "test" and "[" gave the notational advantage of the square brackets and the appearance that the functionality of test was part of the sh language. sh's use of a reversed keyword to mark the end of a control block was a style borrowed from ALGOL 68. By contrast, csh could evaluate the expression directly, which made it faster. It also claimed better readability: Its expressions used a grammar and a set of operators mostly copied from C, none of its keywords were reversed and the overall style was also more like C.
Here is a second example, comparing scripts that calculate the first 10 powers of 2. Again because of the lack of an expression grammar, the sh script uses command substitution and the expr command. (Modern POSIX shell does have such a grammar: the statement could be written or .) Finally, here is a third example, showing the differing styles for a switch statement. In the sh script, ";;" marks the end of each case because sh disallows null statements otherwise.
Улучшения для интерактивного использования
Вторая цель заключалась в том, чтобы C-shell была более удобна для интерактивной работы. Она представила множество новых функций, которые упростили, ускорили и сделали более комфортным использование путём ввода команд в терминале. Пользователи могли выполнять задачи, затрачивая значительно меньше нажатий клавиш, и она работала быстрее. Наиболее важными из этих новых функций стали история команд и механизмы редактирования, псевдонимы, стеки каталогов, обозначение тильдой, cdpath, управление заданиями и хеширование путей. Эти новые функции оказались очень популярными, и многие из них впоследствии были переняты другими Unix-оболочками.
История
История позволяет пользователям вспоминать предыдущие команды и повторно выполнять их, вводя всего несколько быстрых сочетаний клавиш. Например, ввод двух восклицательных знаков ("!!") в качестве команды приводит к повторному выполнению непосредственно предыдущей команды. Другие короткие сочетания клавиш, например, "!$" (обозначающее "последний аргумент предыдущей команды"), позволяют объединять фрагменты предыдущих команд и редактировать их для создания новой команды.
Операторы редактирования
Редактирование может выполняться не только над текстом предыдущей команды, но и над подстановками переменных. Операторы варьируются от простого поиска и замены строк до разбора имени файла для извлечения конкретного сегмента.
Псевдонимы
Псевдонимы позволяют пользователю вводить имя псевдонима, который оболочка C затем внутренне преобразует в заданный пользователем набор слов. Во многих простых случаях псевдонимы работают быстрее и удобнее, чем скрипты.
Стеллаж директорий
Стек каталогов позволяет пользователю добавлять в стек или извлекать из стека текущий рабочий каталог, что упрощает переключение между различными местами в файловой системе.
Тильдовая нотация
Тильдовая нотация предоставляет краткий способ указания путей относительно домашнего каталога, используя символ "~".
Заполнение имени файла
Клавиша Escape может использоваться для интерактивного отображения возможных вариантов завершения имени файла в конце текущей командной строки.
Cdpath (Диапазон)
Cdpath расширяет понятие пути поиска для команды `cd` (перейти в каталог): если указанный каталог не находится в текущем каталоге, csh попытается найти его в каталогах, указанных в переменной `cdpath`.
Контроль работы
Вплоть до 1980-х годов большинство пользователей использовали простые символьные терминалы, которые не поддерживали работу с несколькими окнами, поэтому они могли выполнять только одну задачу одновременно. Управление заданиями в оболочке C позволяло пользователю приостановить текущую операцию и создать новый экземпляр оболочки C, называемый заданием, нажатием комбинации клавиш ^Z. Пользователь мог затем переключаться между заданиями с помощью команды fg. Активное задание называлось выполняемым на переднем плане. Другие задания могли быть либо приостановлены (остановлены), либо выполняться в фоновом режиме.
Хэширование пути
Хаширование пути ускоряет поиск исполняемых файлов в оболочке C. Вместо последовательного обращения к файловой системе в каждом каталоге из переменной PATH до тех пор, пока файл не будет найден или все возможности не будут исчерпаны, оболочка C обращается к внутренней хэш-таблице, построенной путем сканирования этих каталогов. Эта таблица обычно позволяет оболочке C определить местонахождение файла (если он существует) без необходимости его поиска, и её можно обновить командой `rehash`.
Обзор языка
В оболочке C обрабатывается каждая строка по отдельности. Каждая строка разбивается на набор слов, разделенных пробелами или другими символами, имеющими специальное значение, включая скобки, каналы и операторы перенаправления ввода/вывода, точки с запятой и амперсанды.