diff --git a/internal/shell/commands.go b/internal/shell/commands.go
deleted file mode 100644
index 80b8651..0000000
--- a/internal/shell/commands.go
+++ /dev/null
@@ -1,357 +0,0 @@
-// commands.go - встроенные команды fush shell (стиль busybox)
-// Реализует базовые команды: exit, ls, cd, mkdir, rm, touch, pwd, cat, echo
-// Все команды работают независимо от ОС, используя только стандартную библиотеку Go
-
-package shell
-
-import (
- "bufio"
- "fmt"
- "io"
- "os"
- "path/filepath"
- "strings"
- "time"
-
- "fush/pkg/ansi"
-)
-
-// cmdExit обрабатывает команду exit
-func (s *Shell) cmdExit(args []string) error {
- s.running.Store(false)
- s.logger.Info("Выполнена команда exit")
- return nil
-}
-
-// cmdHelp обрабатывает команду help
-func (s *Shell) cmdHelp(args []string) error {
- fmt.Println()
- ansi.Println(ansi.Cyan, "╔══════════════════════════════════════════════════════════════╗")
- ansi.Println(ansi.Cyan, "║ fush shell - Доступные команды ║")
- ansi.Println(ansi.Cyan, "╚══════════════════════════════════════════════════════════════╝")
- fmt.Println()
-
- ansi.Println(ansi.Yellow, "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
- ansi.Println(ansi.BrightGreen, "ВСТРОЕННЫЕ КОМАНДЫ (BUSYBOX-STYLE):")
- ansi.Println(ansi.Yellow, "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
-
- commands := []struct {
- name string
- desc string
- }{
- {"exit", "Выход из оболочки"},
- {"help", "Показать эту справку"},
- {"ls [path]", "Вывести список файлов в директории"},
- {"cd [dir]", "Сменить текущую директорию"},
- {"pwd", "Показать текущую директорию"},
- {"mkdir [-p]
", "Создать новую директорию"},
- {"rm [-rf] ", "Удалить файл или директорию"},
- {"touch ", "Создать файл или обновить время доступа"},
- {"cat ", "Вывести содержимое файла"},
- {"echo [text...]", "Вывести текст на экран"},
- {"exec [args...]", "Выполнить внешнюю команду"},
- }
-
- for _, cmd := range commands {
- fmt.Printf(" %-20s %s\n", ansi.Colorize(cmd.name, ansi.BrightWhite), cmd.desc)
- }
-
- fmt.Println()
- ansi.Println(ansi.Yellow, "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
- ansi.Println(ansi.BrightGreen, "ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:")
- ansi.Println(ansi.Yellow, "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
-
- fmt.Printf(" %-30s %s\n", ansi.Colorize("ls -la", ansi.BrightWhite), "Показать все файлы")
- fmt.Printf(" %-30s %s\n", ansi.Colorize("cd /tmp", ansi.BrightWhite), "Перейти в /tmp")
- fmt.Printf(" %-30s %s\n", ansi.Colorize("pwd", ansi.BrightWhite), "Показать текущий путь")
- fmt.Printf(" %-30s %s\n", ansi.Colorize("mkdir -p a/b/c", ansi.BrightWhite), "Создать вложенные директории")
- fmt.Printf(" %-30s %s\n", ansi.Colorize("rm -rf olddir", ansi.BrightWhite), "Удалить директорию рекурсивно")
- fmt.Printf(" %-30s %s\n", ansi.Colorize("cat file.txt", ansi.BrightWhite), "Показать содержимое файла")
- fmt.Printf(" %-30s %s\n", ansi.Colorize("echo Hello World", ansi.BrightWhite), "Вывести текст")
- fmt.Printf(" %-30s %s\n", ansi.Colorize("exec go version", ansi.BrightWhite), "Выполнить внешнюю команду")
- fmt.Printf(" %-30s %s\n", ansi.Colorize("ls | grep .go", ansi.BrightWhite), "Пайплайн")
- fmt.Printf(" %-30s %s\n", ansi.Colorize("ls > files.txt", ansi.BrightWhite), "Перенаправление вывода")
-
- fmt.Println()
- ansi.Println(ansi.Yellow, "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
-
- return nil
-}
-
-// cmdLs обрабатывает команду ls (стиль busybox)
-func (s *Shell) cmdLs(args []string) ([]byte, error) {
- path := "."
- showAll := false
- longFormat := false
-
- // Парсим аргументы
- for _, arg := range args {
- if arg == "-a" || arg == "--all" {
- showAll = true
- } else if arg == "-l" {
- longFormat = true
- } else if !strings.HasPrefix(arg, "-") {
- path = arg
- }
- }
-
- dir, err := os.Open(path)
- if err != nil {
- return nil, err
- }
- defer dir.Close()
-
- entries, err := dir.Readdir(-1)
- if err != nil {
- return nil, err
- }
-
- var output strings.Builder
-
- for _, entry := range entries {
- name := entry.Name()
-
- // Пропускаем скрытые файлы если не указан -a
- if !showAll && strings.HasPrefix(name, ".") {
- continue
- }
-
- if longFormat {
- // Формат: права ссылки владелец группа размер дата имя
- perms := entry.Mode().String()
- nlink := 1 // В Go сложно получить количество жестких ссылок
- uid := fmt.Sprintf("%d", entry.Sys() != nil) // Упрощённо
- gid := "users"
- size := entry.Size()
- modTime := entry.ModTime().Format("Jan _2 15:04")
-
- if entry.IsDir() {
- name = name + "/"
- } else if entry.Mode()&os.ModeSymlink != 0 {
- // Для симлинков пытаемся прочитать цель
- if target, err := os.Readlink(filepath.Join(path, entry.Name())); err == nil {
- name = name + " -> " + target
- }
- }
-
- fmt.Fprintf(&output, "%s %3d %-8s %-8s %8d %s %s\n",
- perms, nlink, uid, gid, size, modTime, name)
- } else {
- if entry.IsDir() {
- name = name + "/"
- }
- fmt.Fprint(&output, name, "\n")
- }
- }
-
- return []byte(output.String()), nil
-}
-
-// cmdCd обрабатывает команду cd
-func (s *Shell) cmdCd(args []string) error {
- path := s.GetEnv("HOME")
- if len(args) > 0 {
- path = args[0]
- }
-
- if path == "~" {
- path = s.GetEnv("HOME")
- }
-
- if err := os.Chdir(path); err != nil {
- return err
- }
-
- pwd, err := os.Getwd()
- if err == nil {
- s.SetEnv("PWD", pwd)
- }
-
- return nil
-}
-
-// cmdPwd обрабатывает команду pwd
-func (s *Shell) cmdPwd(args []string) ([]byte, error) {
- dir, err := os.Getwd()
- if err != nil {
- return nil, err
- }
- return []byte(dir + "\n"), nil
-}
-
-// cmdMkdir обрабатывает команду mkdir (с поддержкой -p)
-func (s *Shell) cmdMkdir(args []string) error {
- if len(args) == 0 {
- return fmt.Errorf("требуется имя директории")
- }
-
- createParents := false
- var dirs []string
-
- for _, arg := range args {
- if arg == "-p" || arg == "--parents" {
- createParents = true
- } else if !strings.HasPrefix(arg, "-") {
- dirs = append(dirs, arg)
- }
- }
-
- for _, dir := range dirs {
- var err error
- if createParents {
- err = os.MkdirAll(dir, 0755)
- } else {
- err = os.Mkdir(dir, 0755)
- }
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// cmdRm обрабатывает команду rm (с поддержкой -r и -f)
-func (s *Shell) cmdRm(args []string) error {
- if len(args) == 0 {
- return fmt.Errorf("требуется имя файла")
- }
-
- recursive := false
- force := false
- var targets []string
-
- for _, arg := range args {
- switch arg {
- case "-r", "-R", "--recursive":
- recursive = true
- case "-f", "--force":
- force = true
- default:
- if !strings.HasPrefix(arg, "-") {
- targets = append(targets, arg)
- }
- }
- }
-
- for _, target := range targets {
- info, err := os.Stat(target)
- if err != nil {
- if !force {
- return err
- }
- continue
- }
-
- if info.IsDir() && !recursive {
- return fmt.Errorf("'%s' является директорией, используйте -r для удаления", target)
- }
-
- if err := os.RemoveAll(target); err != nil && !force {
- return err
- }
- }
-
- return nil
-}
-
-// cmdTouch обрабатывает команду touch
-func (s *Shell) cmdTouch(args []string) error {
- if len(args) == 0 {
- return fmt.Errorf("требуется имя файла")
- }
-
- now := time.Now()
-
- for _, filename := range args {
- if strings.HasPrefix(filename, "-") {
- continue
- }
-
- file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0644)
- if err != nil {
- return err
- }
- file.Close()
-
- if err := os.Chtimes(filename, now, now); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// cmdCat обрабатывает команду cat (конкатенация файлов)
-func (s *Shell) cmdCat(args []string) ([]byte, error) {
- if len(args) == 0 {
- // Читаем из stdin
- info, err := os.Stdin.Stat()
- if err != nil {
- return nil, err
- }
-
- if info.Mode()&os.ModeCharDevice != 0 {
- return nil, fmt.Errorf("ожидается файл или stdin")
- }
-
- reader := bufio.NewReader(os.Stdin)
- var output strings.Builder
- for {
- line, err := reader.ReadString('\n')
- if err == io.EOF {
- break
- }
- if err != nil {
- return nil, err
- }
- output.WriteString(line)
- }
- return []byte(output.String()), nil
- }
-
- var output strings.Builder
-
- for _, filename := range args {
- if strings.HasPrefix(filename, "-") {
- continue
- }
-
- data, err := os.ReadFile(filename)
- if err != nil {
- return nil, fmt.Errorf("ошибка чтения '%s': %v", filename, err)
- }
-
- output.Write(data)
- if len(data) > 0 && data[len(data)-1] != '\n' {
- output.WriteByte('\n')
- }
- }
-
- return []byte(output.String()), nil
-}
-
-// cmdEcho обрабатывает команду echo
-func (s *Shell) cmdEcho(args []string) ([]byte, error) {
- newline := true
- startIdx := 0
-
- if len(args) > 0 && args[0] == "-n" {
- newline = false
- startIdx = 1
- }
-
- var output strings.Builder
- for i := startIdx; i < len(args); i++ {
- if i > startIdx {
- output.WriteByte(' ')
- }
- output.WriteString(args[i])
- }
-
- if newline {
- output.WriteByte('\n')
- }
-
- return []byte(output.String()), nil
-}