Для моего класса я должен создать базовую оболочку, похожую на bash, которая позволит пользователю вызывать команды вроде ls, sleep и т.д. Я ищу ресурсы о том, как это сделать: учебники, текст справки, пример кода или даже некоторые общие сведения о том, как начать работу. У кого-нибудь есть ссылки или информация, чтобы помочь мне?
Написание базовой оболочки
Ответ 1
В руководстве glibc содержится некоторая полезная информация о реализации управления заданиями в оболочке: http://www.gnu.org/software/libc/manual/html_node/Implementing-a-Shell.html#Implementing-a-Shell
Ответ 2
Это действительно зависит от того, насколько проста ваша оболочка. Если вам не требуется управление заданиями (например, фоновая настройка) или трубы, это очень просто. Вот пример:
#include <stdio.h>
#include <stdlib.h>
#define MAX_LENGTH 1024
int main(int argc, char *argv[]) {
char line[MAX_LENGTH];
while (1) {
printf("$ ");
if (!fgets(line, MAX_LENGTH, stdin)) break;
system(line);
}
return 0;
}
Выйти из приведенного выше примера можно с помощью CTRL-D. Чтобы добавить встроенные команды, такие как exit или cd, вам нужно будет сделать токенизацию строки с помощью strtok() и посмотреть первый токен. Вот более сложный пример с добавленными командами:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef _WIN32
#include <windows.h>
#define chdir _chdir
#else
#include <unistd.h>
#endif
#define MAX_LENGTH 1024
#define DELIMS " \t\r\n"
int main(int argc, char *argv[]) {
char *cmd;
char line[MAX_LENGTH];
while (1) {
printf("$ ");
if (!fgets(line, MAX_LENGTH, stdin)) break;
// Parse and execute command
if ((cmd = strtok(line, DELIMS))) {
// Clear errors
errno = 0;
if (strcmp(cmd, "cd") == 0) {
char *arg = strtok(0, DELIMS);
if (!arg) fprintf(stderr, "cd missing argument.\n");
else chdir(arg);
} else if (strcmp(cmd, "exit") == 0) {
break;
} else system(line);
if (errno) perror("Command failed");
}
}
return 0;
}
Вы можете расширить это, добавив больше встроенных команд или поддерживая такие вещи, как cd, без аргументов, чтобы перейти в ваш домашний каталог. Вы также можете улучшить командную строку, добавив такую информацию, как текущий каталог.
В качестве примечания, простой способ добавить историю команд и функции редактирования строк - использовать библиотеку GNU readline.
Ответ 3
Я написал очень базовую оболочку для проекта HelenOS. Он имеет следующие функции:
- Редактирование строк/история
- Buit в командах/загружаемых командах
- Путь поиска для поиска внешних команд
- EXTREMELY основные сценарии
- Отброшенные реализации большинства основных утилит GNU (сделанные с нуля) как встроенные функции.
Большая часть его реализована на очень простой многоразовой базе, построенной вокруг указателей на функции. Как минимум, вам понадобится встроенный "выход" или "выход", чтобы кто-то мог выйти из оболочки, плюс "cd" и "pwd". Конструкция "export" /'declare' также имеет смысл.
Вы можете ознакомиться с лицензированным кодом (BSD) здесь. Или загрузите репо, это в uspace/app/bdsh. Я, вероятно, могу выкопать последнюю рабочую версию Linux до того, как я портировал ее, если вам это нужно. Самое большое различие - версия HelenOS использует домашний редактор строк, task_spawn() вместо execve()/posix_spawn() и т.д. Остальное переносимо. Он был первоначально разработан, чтобы сделать тестирование функций простым и интерактивным. Я не выполнял управление заданиями, поскольку это не было необходимо. Однако это может быть достигнуто тривиально.
Если вы хотите изучить "настоящую" оболочку, я настоятельно рекомендую посмотреть dash
, вам будет гораздо проще понять, чем погрузиться прямо в код bash.
Анекдотически "bdsh" означает "мертвую оболочку мозга".
Ответ 4
Вы можете посмотреть BusyBox для некоторых очень небольших реализаций оболочки.
Ответ 5
Если вы начинаете, попробуйте http://stephen-brennan.com/2015/01/16/write-a-shell-in-c/ и далее для подробных знаний http://www.gnu.org/software/libc/manual/html_node/Data-Structures.html#Data-Structures.
Кроме того, учась программировать оболочку с помощью C/С++, вы привыкли ссылаться на man-страницы команд.
Ответ 6
Bash предоставляет очень мало команд: cd
, pushd
, popd
, подпрограммы обработки переменных (set
и $x
) и все элементы потока управления, такие как циклы и условные. Почти все остальные команды находятся в $PATH
.
Если в задании не указано иначе, игнорируйте переменные и поток управления. Просто предоставьте REPL, который выглядит в $PATH
и выполняет все, что вводит пользователь (предположительно через posix_spawn()
), и передает по аргументам командной строки.
Ответ 7
Лоубол:
Если программа очень проста, тогда простые системные вызовы могут быть реализованы script -like с помощью команды "system("putdesiredcommandhere");
"
Когда вы устанавливаете "printf
" в программе, вы делаете простой системный вызов с помощью stdio.h.
Далее следует образец кода.
#include <stdio.h>
#include <stdlib.h>
main ()
{
system ("clear");
system ("echo this is an example of a basic system call");
printf ("just as you've always done.\n");
return 0;
}
Используя этот метод, вы можете расшифровать сценарии bash или csh в c-программу. Для этого потребуется системный вызов для каждой строки в script.