Прогулка по интерпретатору командной строки

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

Что такое интерпретатор командной строки оболочки?

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

Как работает интерпретатор командной строки?

Есть несколько важных шагов, чтобы убедиться, что введенная вами команда будет выполнена. Там всегда одно и то же, в том же порядке.
Чтобы прояснить этот вопрос, давайте возьмем пример: ls -l *.c
Вы должны знать результат, но это не самое главное.

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

Ожидание ввода пользователя

После запроса тестового сообщения (обычно это значение $PWD, за которым следует $) командная строка будет ждать вас, подождите, пока вы не нажмете кнопку ввода. Вы можете написать что угодно, например, только пробел, какую-то странную последовательность букв, настоящую команду, даже описание парка Диснейленд, он только ждет, когда вы нажмете ввод.
На самом деле есть другая кнопка, CTRL-D, которые остановят текущее ожидание и перейдут к другому ожиданию.
Затем, когда это будет сделано, при нажатии специальной кнопки командная строка сохранит это в переменной, и это будет все для первый шаг.

Если вы являетесь поклонником C, чтобы воссоздать такие вещи, вы можете легко использовать команду getline, а если вы фанатичный поклонник C, вы также можете перекодировать его, используя только sys-вызов. Ключ к этому, полезный системный вызов для использования чтения, который будет читать пользовательский ввод

Для возобновления, с вашей точки зрения, вы только открываете терминал, затем пишете «ls -l *.c» и нажимаете ввод

Проверьте введенное

Процесс проверит пользовательский ввод, проверит, не заполнены ли команды пробелами, нет ли комментариев, нет ли специальных символов типа '\t' или '\r'… Будет много проверок уверен, что он получит только то, что мы хотим выполнить.
Он также будет разделен на символьное слово, разделенное пробелом, или специальным символом, чтобы иметь только команду, флаги или оператор.

Давайте посмотрим на наш пример. Итак, мы вводим «ls -l *.c», вывод после этого процесса будет: «ls» «-l» «*.c».

Найдите команду и выполните ее

Получив только то, что нужно, программа возьмет первый токен, тот, который представляет команду, и проверит, существует ли команда. Команда может существовать в 4 типах: Исходная команда bash, часто в каталоге /bin/…, может быть встроенной командой, также может быть псевдонимом или может быть исполняемым файлом в текущем каталоге.
Но вы догадываетесь, есть особый порядок проверки.

Первый: Псевдонимы

Псевдоним – это короткое имя, которое оболочка преобразует в другое более длинное имя или команду. Псевдонимы позволяют вам определять новые команды, заменяя строку на первый токен простой команды.
Таким образом, он будет проверять этот список «укороченных» исполняемых файлов, если введенная команда не является одной.

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

Второй: встроенный

Встроены некоторые надстройки, которые создатель интерпретатора командной строки может добавить по своему желанию. Это также список команд, и компьютер проверит, нет ли здесь введенной команды.

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

Третий: взгляните на ПУТЬ

После всех этих проверок компьютер проверит, не существует ли команда в PATH. Он примет значение $PATH и поместит команду в конце всех разных PATH. Если команда подходит, интерпретатор создаст дочерний процесс, который будет выглядеть так же, как текущий процесс (например, тот же env …), выполнит в нем команду и дождется завершения выполнения команды, прежде чем двигаться дальше.
Создание дочернего процесса будет производиться sys-вызовом fork, а ожидание - sys-вызовом wait.
Выполнение, самое главное, производится sys-вызовом execve.

Очевидно, что команда ls находится в PATH, как /bin/ls или /usr/bin/ls, интерпретатор командной строки запустит команду ls со всеми флагами и т. д.

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

Последний: проверьте, не является ли он исполняемым файлом в текущем каталоге.

Например, если вы скомпилируете программу на языке C и захотите ее выполнить, в командной строке введите: ./a.out (у меня не хватает воображения, чтобы найти имя). Система будет искать, существует ли файл ./a.out на всем последнем шаге, но, очевидно, он найдет его в текущем каталоге и выполнит.

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

Распечатайте команду и подождите (снова)

В конце, если команда была найдена на одном из этих 4 шагов, она будет выполнена и распечатает результат. Кроме того, если не найти, будет вывод, но вывод ошибки в stderr.
Вывод команды, будь то в stdout или stderr, будет напечатан системным вызовом записи.

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

Для нашего примера результат поиска должен быть примерно таким:

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

Спасибо за ваше время, и надеюсь, что вы узнали что-то :)

Автор :
Аксель Валентин
Джейсон Лешар
Микаэль Буайо