Оболочка в C - как читать и выполнять пользовательский ввод? - PullRequest
0 голосов
/ 05 января 2019

Мое задание - написать очень простую оболочку на C. У меня не так много источников, и я только начал изучать C, я использовал только scanf() и printf() и кодировал простые функции. Я знаю только, что он должен быть написан с fork() и другим exec(). Я потратил много времени на анализ других оболочек, но я не понимаю структуру программ и некоторые функции, такие как:

  1. парсинг, зачем нам парсинг? Если я знаю, что не буду использовать аргументы в командах, я хотел бы только сравнить ввод с моими собственными функциями, такими как help() или date(), и выполнить их.
  2. чтение ввода пользователя. Используя fgets(), а затем strcmp()?
  3. выполняется, как это работает? Как execvp() знает, что пользовательский ввод - это команда (функция) в моем main или программа в моей папке с программой?

1 Ответ

0 голосов
/ 05 января 2019

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

Чтобы ответить на ваши вопросы, хотя:

зачем нам разбор?

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

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

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

чтение ввода пользователя. Используя fgets() и затем strcmp()?

Помните, что fgets() может не пройти всю строку - если строка длиннее, чем длина вашего буфера минус 1. Но, возможно, вам гарантирован предел длины строки? Или допускается сбой на слишком длинных линиях?

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

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

Посмотрите справочную страницу для execvp() (и друзей). В основном, когда вы вызываете execvp(), происходит запуск двоичного файла в указанном месте, а его командная строка - это то, что вы передаете в качестве второго аргумента execvp(). Предположим, вы запускаете

execvp("/path/to/foo", "/path/to/foo", "bar");

Итак, программа на /path/to/foo запущена. Как и любая программа, ее argv[0] - это путь к ней. Его argc будет 2, а argv[1] будет "bar". Его рабочий каталог (и идентификатор пользователя и группы) будет текущим каталогом, а также идентификатором пользователя и группы процесса, который запустил execvp(), поэтому - не обязательно /path/to/foo.

Продолжая предыдущий пример, вы можете сделать:

chdir("/path/to");
execvp("foo", "foo", "bar");

, когда foo будет работать с argv[0], равным foo.

...