Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Madi-13/bash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 

Repository files navigation

MiniShell (C)

Небольшая учебная командная оболочка (shell) на C: читает команду из stdin, парсит её на слова и пайпы, поддерживает конвейеры (|), перенаправления (< и >), фоновый запуск (&) и встроенную команду cd.

Проект подходит как компактный пример: парсинг ввода + fork/exec + pipe + dup2 + wait.


Возможности

  • Запуск внешних программ через execvp()
  • Конвейеры (pipes):
    cmd1 | cmd2 | cmd3
  • Перенаправление ввода/вывода:
    • cmd > file — stdout в файл (создаётся/перезаписывается)
    • cmd < file — stdin из файла
  • Фоновый режим: cmd & (shell не ждёт завершения)
  • Поддержка кавычек " для слов с пробелами:
    echo "hello world"
  • Встроенная команда:
    • cd [path] (если без аргумента или ~ — переход в $HOME)
  • Выход:
    • exit / quit

Быстрый старт

Сборка

gcc -Wall -Wextra -O2 -o minishell main.c

Запуск

./minishell

Shell работает в бесконечном цикле: читает одну строку → выполняет → ждёт следующую.


Синтаксис

Обычная команда

ls -la

Конвейер

ls -la | grep ".c" | wc -l

Перенаправление вывода

echo hello > out.txt

Перенаправление ввода

wc -l < out.txt

Фоновый запуск

sleep 10 &

Встроенная команда cd

cd /tmp
cd ~
cd

Примеры

1) Конвейер + grep

ps aux | grep ssh

2) Запись в файл

echo "some text" > file.txt
cat < file.txt

3) Фоновый режим

sleep 5 &
echo "я не жду завершения sleep"

Как это устроено (внутренности)

Парсинг

Ввод разбирается на структуру вида:

  • char ***cmds — список команд в конвейере

    • cmds[i]char **argv для execvp
    • cmds[i][j] — отдельное слово/аргумент

Ключевые функции:

  • get_word() — читает одно слово из stdin (учитывает "; отдельные токены <, >, |, &)
  • get_list() — собирает список слов (argv) до \n или |
  • get_cmds() — собирает массив команд до конца строки; возвращает n — сколько команд в pipeline

Выполнение команд

  • do_cmds(cmds, n):

    • если команда cd — выполняется без fork (в текущем процессе), т.к. chdir() должен менять директорию shell’а

    • если n == 1 — один fork() и execvp()

    • если n > 1 — создаются пайпы pipefd, для каждой команды делается fork(), затем:

      • dup2() подменяет stdin/stdout нужными концами pipe
      • вызывается execvp()

Перенаправления

Функция redir(cmd) ищет токены < или >:

  • >open(..., O_WRONLY|O_CREAT|O_TRUNC, 0644) и dup2(fd, 1)
  • <open(..., O_RDONLY) и dup2(fd, 0)

После этого токены перенаправления удаляются из argv (через del_w()), чтобы execvp() получил чистые аргументы.


Ограничения и заметки

  • В одной команде корректно обрабатывается по одному перенаправлению за вызов redir(). В коде оно вызывается дважды, чтобы попытаться обработать и <, и >.

  • Нет поддержки:

    • >> (append)
    • 2> (stderr redirection)
    • ;, &&, ||, скобок, переменных окружения, подстановок и т.п.
  • Промпта ($ ) нет — ввод просто читается из stdin.

  • Парсер довольно “низкоуровневый”: использует read() посимвольно.


Структура памяти

Динамически выделенные структуры освобождаются через:

  • free_3_arr(cmds) — освобождает char*** (команды + аргументы + строки)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages