Во-первых, позвольте мне сказать, что это звучит как непростая задача для человека, который только изучает 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
.