Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 5
×

Хочу написать простую командную строку на С

Здравствуйте, хочу написать простую командную строку на С.
Но не знаю с чего начать.
Может кто знает литературу или статьи.

Команды или функционал который бы хотел реализовать:
-cd
-exit
-help
-path
-pwd
-cp
-mkdir
-cat
-echo
-ls
-флаги(-v и т.д)
-изменения цвета
-история команд
-логин пользователя
-ошибки ввода

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn

Найкращі коментарі пропустити

Маєш на увазі шелл по типу баша?
Я сподіваюсь hello world ти вже можеш написати.
Парсити аргументи на C по православному — це getopt: man7.org/...​-pages/man3/getopt.3.html (на stack overflow пошукай приклади використання)

Парсити user input треба через readline: tiswww.case.edu/...​/chet/readline/rltop.html (заодно там тобі і tab-completion)

cd — linux.die.net/man/2/chdir
exit — повертаєш EXIT_CODE з main() або exit(EXIT_CODE) (linux.die.net/man/2/exit)
help — пишеш вручну
path — я хз що це
pwd — man 2 pwd
cp — можна вручну — відкрити обидва файли, читати з одного писати в інший, або швидший варіант для linux — це sendfile
і т.д.

колір — просто пишеш ansi-послідовність байт в stdout/stderr і все що після цієї послідовності буде кольоровим
про логін я не дуже зрозумів куди він має логінитись
історія ніби є в libreadline вже (разом з навігацією стрілками вгору-вниз)
обробка помилок теж в libreadline

Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Я джва года жду такую командную строку.

Коментар порушує правила спільноти і видалений модераторами.

int main(int args, char *argv[]) { /* do big switch */ return 0; }

Начни с гугла:) letmegooglethat.com/...​q=write my own shell in c
А по поводу примеров реализаций, вот: github.com/...​wn-x#build-your-own-shell

Є багато прикладів початкових скелетів.
Наприклад, ось такий: www.shsu.edu/...​2000/cs431/shell-lab.html

А там вже м’ясо напишете.

при чем здесь это? подумал юзер, но кама-сутру все таки купил

Ну берешь args[] из main и погнал свитчкейсами и ифами парсить)

Зачем тебе это надо? От этого надо плясать

Но не знаю с чего начать.

www.amazon.com/...​n-Kernighan/dp/0131103628

хочу написать простую командную строку на С.

Непогано було б розібратися з лексером та парсером.
В «Драконі» класно описано
www.amazon.com/...​s-Tools-2nd/dp/0321486811

...да-а-а, ребята, вы сделали мой день))

предложи свой вариант посмеяться

Маєш на увазі шелл по типу баша?
Я сподіваюсь hello world ти вже можеш написати.
Парсити аргументи на C по православному — це getopt: man7.org/...​-pages/man3/getopt.3.html (на stack overflow пошукай приклади використання)

Парсити user input треба через readline: tiswww.case.edu/...​/chet/readline/rltop.html (заодно там тобі і tab-completion)

cd — linux.die.net/man/2/chdir
exit — повертаєш EXIT_CODE з main() або exit(EXIT_CODE) (linux.die.net/man/2/exit)
help — пишеш вручну
path — я хз що це
pwd — man 2 pwd
cp — можна вручну — відкрити обидва файли, читати з одного писати в інший, або швидший варіант для linux — це sendfile
і т.д.

колір — просто пишеш ansi-послідовність байт в stdout/stderr і все що після цієї послідовності буде кольоровим
про логін я не дуже зрозумів куди він має логінитись
історія ніби є в libreadline вже (разом з навігацією стрілками вгору-вниз)
обробка помилок теж в libreadline

Щось мені здається, що readline занадто складний, щоб потренуватись код писати. Велосипед може буть цікавіше.

Зачем ты хочешь ее написать?

тебе надо парсить строковую команду.
1) разбиваешь на слова через strtok
2) делаешь таблицу (массив структур) {команда, указатель на обработчик}, где «команда» — одно из перечисленных тобою ключевых слов; обработчик — функция, принимающая массив строковых параметров (остальные слова из распаршенной команды)
3) собственно, пишешь обработчики, используя API операционной системы
4) отлаживаешь это все
5) сомнительный профит
Если что — пиши в личку или скайп denys.poltorak

Так тут же не командную строку с аргументами парсить, а сидеть в цикле, ловить команду через stdin, и ее уже разбивать. Там если не через strtok, то надо что-то сложное подключать.

Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

Можно посмотреть исходники Busybox

Как пример упрощённой реализации того, что хочет топикстартер

Не «линуховых», а юниксовых, не на говне, а системах с ограниченными ресурсами, насчёт не торможения такого нигде не заявлялось, функциональность бузибокса сильно урезанная по сравнению с полновесными утилитами, а значит и объём кода меньше, соответственно его проще воспринимать.

Мне неинтересно дискутировать с копрофилами

Виктор, я отслеживаю твое состояние последние несколько лет. Происходит заметная регрессия, а сегодня у тебя какой-то срыв просто. Поспокойнее, оно того не стоит. Не порть нервы. Ты еще молодой. Поживи нормально с удовольствием.

а значит и объём кода меньше, соответственно его проще воспринимать.

Тут как повезет)
en.wikipedia.org/...​d_C_Code_Contest#Examples

Это Duff’s device en.wikipedia.org/wiki/Duff’s_device
* надо бы мне обновлять страницу прежде чем отвечать)

When numerous instances of Duff’s device were removed from the XFree86 Server in version 4.0, there was an improvement in performance and a noticeable reduction in size of the executable.[7] lkml.indiana.edu/...​x/kernel/0008.2/0171.html

но согласен, кого волнует практичность, ведь художник творит!

Всему свое время. Время оптимизировать руками и время доверить компилятору.

все выглядит очень просто

Эм... Это не из тех задач, которым посвящена литература. Просто садись и делай.

Ну тогда совет — не начинать с С)

ну С проще Питона, только писать не так удобно

Тогда другой совет — начать с Хелоу Ворлда. Потом Фузз-Бизз и т.д. и тп. Так и до командной строки дойдёт.

ну С проще Питона, только писать не так удобно

П****а проще х**, только писать не так удобно

Cи знаю на уровне первого семестра программирования, задания на Операционные системы.

Некоторая часть готова кода, но не всё, да и хочется написать нормальное что-то. А не говно которое у меня.

Проблема в том что нам даже не сказали что и как делать. Мы учили одно(как работает Линукс и Виндоус), как компилируются программы, гит, семафоры и мютекс в baci.
А тут сказали что нужно сделать свой микрошел.
Как и ТЗ, к сожалению не дали.

Какой микрошел? Какие мьютексы? Тут консольное приложение на 2 часа работы и строк на 200 максимум.

В Main метод строковый массив args заходит — это и есть твои параметры. Тебе просто нужно их распарсить и прикрутить к каждому соответствующий кусочек кода.

Какой массив args?
шелл висит в вечном цикле и интерактивно обрабатывает команды от пользователя

Так ему в каком виде командную строку надо, консольки или шела? Сомневаюсь, что вот так сходу задали второе.

А какая между ними разница?
Нужно что-то, во что можно ввести cd и поменять текущую директорию, потом ввести cp и скопировать файл.

Разница есть, но если достаточно консольки — то есму всего лишь нужно распарсить argv из int main(int argc, char **argv);

Нормальным было бы решение через паттерн «Команда». Но у тебя ничего не выйдет, потому что С)

Зачем оно здесь?
Undo не нужен
Несколько команд одновременно ввести нельзя

Можно сделать красивый котекстуальный биндинг по названию команды. Ну и всякие штуки типа истории команд, которую хотел автор.

историю можно сделать односвязным списком строк
KISS

Да можно вообще всё это одним свитчем написать. Но автор же учится.

С ТЗ сложно так как сказали написать микрошел и дали только список что должен делать. Всё.

Толком не сказали как это сделать. А сказали сделать много. Например сейчас я не знаю как сделать адрес каталога в которым я сейчас нахожусь и как принимать команды к программам которые есть в каталоге и запускать их(из помощи к заданию — " fork() + exec*()")

принимаешь все строкой из stdin (fread) и парсишь на слова (strtok)
адрес каталога хранишь в строке (const char*) или строчном буфере (char[257])
запускать, да, (fork + exec). По ним гугл знает 100500 обучалок.

Підписатись на коментарі