{"id":22572161,"url":"https://github.com/eabykov/devops-linux","last_synced_at":"2025-04-10T14:20:42.280Z","repository":{"id":157126664,"uuid":"594183295","full_name":"eabykov/devops-linux","owner":"eabykov","description":"Все уроки переехали в: https://eabykov.github.io/devops/","archived":false,"fork":false,"pushed_at":"2025-02-07T09:20:05.000Z","size":9,"stargazers_count":18,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T13:01:44.665Z","etag":null,"topics":["aider","bash","daniil","devops","linux","polina","shell","terminal"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eabykov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-27T19:49:24.000Z","updated_at":"2025-03-17T07:14:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"f40e2361-ead9-47d8-bb77-682850ce6dc9","html_url":"https://github.com/eabykov/devops-linux","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eabykov%2Fdevops-linux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eabykov%2Fdevops-linux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eabykov%2Fdevops-linux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eabykov%2Fdevops-linux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eabykov","download_url":"https://codeload.github.com/eabykov/devops-linux/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248233935,"owners_count":21069493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aider","bash","daniil","devops","linux","polina","shell","terminal"],"created_at":"2024-12-08T02:08:21.810Z","updated_at":"2025-04-10T14:20:42.267Z","avatar_url":"https://github.com/eabykov.png","language":null,"readme":"# **Все уроки переехали в: [Курс обучения DevOps](https://eabykov.github.io/devops/)**\n\n## Задания по Linux (все файлы для выполнения заданий находятся в данном репозитории) \n\n### Перед началом выполнить комманды по очереди:\n\nДля того чтобы при выполении команды `sudo ...` не писать каждый раз пароль\n```bash\nsudo grep -q \"ALL ALL = (ALL) NOPASSWD: ALL\" /etc/sudoers \u003e/dev/null || sudo sh -c \"echo 'ALL ALL = (ALL) NOPASSWD: ALL' \u003e\u003e /etc/sudoers\"\n```\n\nОбновим список версий установленных пакетов и установим для них обновления\n```bash\nsudo apt update -qq \u0026\u0026 sudo apt upgrade -y -qq\n```\n\nУстановим несколько полезных программ\n- ncdu - более удобный аналог du\n- ripgrep - более быстрый и удобный аналог grep\n- lnav - более удобный аналог less\n- jq - для работы с json файлами (например поиска в файле имен)\n- nano - текстовый редактор, вместо vi или vim\n- wget - поможет скачать что-либо из интернета\n- curl - с его помощью можно делать HTTP запросы прямо из консоли, например `curl google.com`\n```bash\nsudo apt install -y -qq ncdu ripgrep lnav jq nano wget curl\n```\nЗаменим стандарные утилиты на более удобные (погугли `alias bash`)\n```bash\ngrep -q 'rg' ${HOME}/.bash_aliases || echo -e \"alias grep='rg'\" \u003e\u003e ${HOME}/.bash_aliases\ngrep -q 'ncdu' ${HOME}/.bash_aliases || echo -e \"alias du='ncdu'\" \u003e\u003e ${HOME}/.bash_aliases\ngrep -q 'lnav' ${HOME}/.bash_aliases || echo -e \"alias less='lnav'\" \u003e\u003e ${HOME}/.bash_aliases\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eВсе действия выше одним скриптом\u003c/summary\u003e\n\n```bash\n#!/bin/bash\n\nsudo grep -q \"ALL ALL = (ALL) NOPASSWD: ALL\" /etc/sudoers \u003e/dev/null || sudo sh -c \"echo 'ALL ALL = (ALL) NOPASSWD: ALL' \u003e\u003e /etc/sudoers\"\n\nsudo apt update -qq \u0026\u0026 sudo apt upgrade -y -qq\n\nsudo apt install -y -qq ncdu ripgrep lnav jq nano wget curl\n\ngrep -q 'rg' ${HOME}/.bash_aliases || echo -e \"alias grep='rg'\" \u003e\u003e ${HOME}/.bash_aliases\ngrep -q 'ncdu' ${HOME}/.bash_aliases || echo -e \"alias du='ncdu'\" \u003e\u003e ${HOME}/.bash_aliases\ngrep -q 'lnav' ${HOME}/.bash_aliases || echo -e \"alias less='lnav'\" \u003e\u003e ${HOME}/.bash_aliases\n```\n\n\u003c/details\u003e\n\n### Первое задание\n\n1. Перейди в `/tmp` директорию\n2. Вернитесь обратно в директорию в которой были первоначально\n3. Перейди в домашнюю директорию пользователя\n4. Перейди в вышестоящую директорию\n5. Перейди в корень (что такое корень?)\n6. Выполни команду `cd ~`, куда вы попали?\n7. Выведи на экран полный путь к директории где ты сейчас находишься\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение первого задания\u003c/summary\u003e\n\n```sh\n#!/bin/sh\n\necho -n \"Мы сейчас находимся в директории: \"\n# выводим текст на экран и не переносим строку с помощь параметра -n\n# чтобы вывод следующей команды pwd был после нашей фразы, например: 'Мы сейчас находимся в директории: /home/user'\npwd\n\necho -n \"1. Перешли в директорию: \"\ncd /tmp \u0026\u0026 pwd # используем \u0026\u0026 что значит 'И' то есть если успешно выполнилась `cd /tmp` то делать `pwd`\n\necho -n \"2. Вернулись в директорию: \"\ncd -\n\necho -n \"3. Перешли в директорию: \"\ncd \u0026\u0026 pwd\n\necho -n \"4. Перешли в директорию: \"\ncd .. \u0026\u0026 pwd\n\necho -n \"5. Перешли в кореневую директорию (директория которая является вышестоящей для всех существующих файлов и директорий): \"\ncd / \u0026\u0026 pwd\n\necho -n \"6-7. Перешли в домашнюю директорию: \"\ncd ~ \u0026\u0026 pwd\n```\n\n\u003c/details\u003e\n\n### Второе задание\n\n1. Создай два файла с именами `config` и `binary`\n2. Создай директорию `app`\n3. Перемести файлы `config` и `binary` в директорию `app`\n4. Создай в директории `app` подпапки `temp/info/users` одной командой\n5. Вернись на директорию выше и удали директорию `app`\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение второго задания\u003c/summary\u003e\n\n1. `touch config binary`, `touch ./config ./binary`, `touch config` вместе с `touch binary`\n2. `mkdir app` или `mkdir ./app`\n3. `mv config app/` вместе с `mv binary app/` и проверить что это так с помощью `ls -lah`\n4. `cd app` и `touch config.overwrite`\n5. `mkdir -p temp/info/users`\n6. `cd ..` и `rm -rfv app`\n\n\u003c/details\u003e\n\n### Третье задание\n\n1. Создай пустой файл `file.txt` в директории `/tmp`\n2. Скопируй `file.txt` файл в свою домашнюю директорию\n3. Создай копию файла `file.txt` которая будет называться `txt.file`\n4. Создай директорию `directory` и перемести в нее файлы `file.txt` и `txt.file`\n5. Создай копию директории `directory` которая будет называться `next_directory`\n6. Переименуй `next_directory` в `next`\n7. Удали обе директории которые создал и все файлы одной командой\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение третьего задания\u003c/summary\u003e\n\n1. `cd /tmp` и `touch file.txt`\n2. `cp -a file.txt ~/` или `cp -a file.txt $HOME/`\n3. `cp -a file.txt txt.file`\n4. `mkdir directory` и потом `mv *.* directory` (осторожно, если есть еще файлы с точкой то скопирует и их)\n5. `cp -a ./directory ./next_directory`\n6. `mv next_directory next`\n7. `rm -rfv next directory`\n\n\u003c/details\u003e\n\n### Четвертое задание\n\nВ директори есть файл в котором написан список IP адресов, вычисли какой из них чаще всего повторяется (использовать файл `ip_list`\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение четвертого задания\u003c/summary\u003e\n\n1. `cut -d' ' -f1` выведем только IP адреса, без всего лишнего\n2. `sort -n` отсортируем их тем самым сгрупировав одинаковые\n3. `uniq -c` выведем количество одинаковых повторений IP\n4. `cut -d' ' -f1 ip_list | sort -n | uniq -c` совместим все три команды передавая вывод одной в другую через `|`\n\n\u003c/details\u003e\n\n### Пятое задание\n\nВывести только время когда была установлена последняя программа (не запись в `man-db`). История установки программ хранится в файле `/var/log/dpkg.log`\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение пятого задания\u003c/summary\u003e\n\n1. Перейдем в директорию с файлом `cd /var/log/`\n2. Посмотрим содержимое файла `less /var/log/dpkg.log` в котором можно делать поиск нажав `/` и введя слово, например `installed`\n3. `grep 'installed' dpkg.log | grep -v 'man-db' | tail -1 | cut -d ' ' -f2`\n   - `grep 'installed' dpkg.log` - поиск строк с словом installed в файле лога\n   - `grep -v 'man-db'` - убрать строки с обновлением man-db во всех страках с installed\n   - `tail -1` - вывести 1 последнюю строку\n   - `cut -d ' ' -f2` - вывести только время (можно еще и дату для удобства `cut -d ' ' -f1-2`)\n\n\u003c/details\u003e\n\n### Шестое задание\n\n1. Отсортировать `names.txt` в алфавитном порядке и убрать повторения\n2. Записать отсортированный список имен в файл `names_sorted.txt`\n3. Дописать в конец файла `names_sorted.txt` имена с файла `names_new.txt`\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение шестого задания\u003c/summary\u003e\n\n1. `sort | uniq`\n   - `sort` сортируем в алфавитном порядке\n   - `uniq` склеивает повторяющиеся строки в одну\n2. `sort | uniq \u003e names_sorted.txt`\n   - `\u003e` перезаписывает содержимое файла `names_sorted.txt` выводом команды `uniq`\n3. `cat names_new.txt \u003e\u003e names_sorted.txt`\n   - `\u003e\u003e` дописывает в конец файла `names_sorted.txt` вывод команды cat (содержимое файла `names_new.txt`)\n\n\u003c/details\u003e\n\n### Восьмое задание\n\n1. Вывести все файлы из папки `/etc` в которых есть имя вашего пользователя\n2. Не выводить ошибки при поиске\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение восьмого задания\u003c/summary\u003e\n\n1. `grep -i 'Aider' /etc/*`\n   - `/etc/*` поиск по всем файлам в папке `/etc`\n   - `-i` означает не учитывать регистр (найдет: aider, Aider, AIDER, aIDEr, и тд)\n2. `grep -i 'Aider' /etc/* 2\u003e/dev/null`\n   - `2\u003e/dev/null` не выводить ошибки\n\n\u003c/details\u003e\n\n### Девятое задание\n\n1. Упаковать (сжать) в архив все файлы с именами из седьмого задания\n   1. С помощью `tar`\n   2. С помощью `zip`\n2. Создать папку `unpack` и распаковать в нее содержимое архивов по очереди\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение девятого задания\u003c/summary\u003e\n\nОтветы на все вопросы тут https://losst.pro/arhivatsiya-v-linux советую пользоваться `zip` как самым простым или `tar` как уже установленым в большинстве unix систем (linux)\n\n\u003c/details\u003e\n\n### Десятое задание\n\n1. Обьяснить какие данные будут выведены на экран в команде `top`\n2. Какой командой можно посмотреть использование оперативной памяти?\n   1. В чем разница между `available` и `free` памятью?\n3. Что такое память `buff/cache`?\n4. Посмотреть сколько места занято на диске `/` и насколько он нагружен\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение десятого задания\u003c/summary\u003e\n\n1. top и htop выводят:\n   - load average - мера потребности в ресурсах CPU и на дисковые ресурсы. Например если 1.5 то это значит что нужна была мощность равная 1 vCPU (ядру) и 0.5 ожидание записи на диск, в сумме получилось 1.5 вот тебе и нагрузка на систему. Выводится как три числа за 1, 5 и 15 минут\n   - использование оперативной памяти (сколько свободно, сколько всего, сколько занято и тд в mem)\n   - список процессов отсортированых по использованию CPU (процессора)\n2. free (-m в мегабайтах или -h для людей)\n   1. `available` доступная память часть которой может уже использоваться, но ничего страшного если ее \"забрать\" и использовать при надобности (например кэш или буфер), а `free` это которая вообще сейчас не используется ни для чего\n3. Временные данные, кэш, которые могут быть очищены если оперативная память (RAM) будет нужна какому-то приложению. Например кэш нужен чтобы приложения быстрее запускались\n4. `ps aux | grep python`\n5. `sudo kill -9 PID` где PID это числовой индификатор процесса который мы узнали из прошлой команды (ps aux...)\n6. `df -m` (или можно -h) узнать нагрузку на диск можно несколькими способами:\n   - `iostat -dx DISK_NAME` где DISK_NAME взято из столбца `Filesystem` первой команды\n   - `sudo iotop` - как top, только для дисков\n\n\u003c/details\u003e\n\n### Одиннадцатое задание\n\n1. Создать скрипт который:\n   1. Может запускать только текущий пользователь\n   2. Устанавит через `apt` (только если еще не установлены)\n      - `curl` - выполнять http запросы\n      - `git` - система для контроля за версиями, может заливать их в публичный репозиторий\n      - `jq` - для работы с файлами json чтобы удобно искать в них или отображать\n\n\u003cdetails\u003e\n  \u003csummary\u003eРешение одиннадцатого задания\u003c/summary\u003e\n\n1. Создаем скрипт `touch install_apps.sh` и даем права на запуск только текущему пользователю `chmod u+x install_apps.sh`\n   1. Сам скрипт:\n   ```sh\n   #!/bin/bash\n   \n   sudo apt install -y wget curl git jq\n   ```\n   2. Установка docker будет сложнее так как apt по умолчанию не знает откуда его ставить (нет репозитория с docker в базовом списке репозиториев)\n   \u003e Репозиторий - место откуда скачивать программы (там храняться все версии и туда разработчики загружают новые версии)\n   \n   ```sh\n   #!/bin/bash\n   \n   sudo apt install -y wget curl git jq\n   \n   # обновлем список версий из известных репозиториев\n   sudo apt update\n   # устанавливаем последнии версии необходимых программ (тут ставится даже curl)\n   sudo apt install -y ca-certificates curl gnupg lsb-release\n   \n   # создаем папку где будут храниться ключи для доступа к репозиторию из которого можно установить docker\n   sudo mkdir -p /etc/apt/keyrings\n   # через curl делаем запрос ключа (выведет нам его в консоль)\n   # перенаправляем вывод (по сути сам ключ) в команду добавления ключа /etc/apt/keyrings/docker.gpg\n   curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg\n   \n   # записываем данные о репозитории которые будет исопльзовать apt в файл /etc/apt/sources.list.d/docker.list\n   echo \\\n   \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \\\n   $(lsb_release -cs) stable\" | sudo tee /etc/apt/sources.list.d/docker.list \u003e /dev/null\n   \n   # обновляем список программ из репозиториев (обновит список програм которые можно ставить и из нового репозитория docker)\n   sudo apt update\n   # устанавливаем последнюю версию docker вместе с утилитами которые он использует\n   sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n   \n   # добавляем нашего пользователя в группу docker для того чтобы команды docker работали без sudo\n   sudo usermod -aG docker $USER\n   \n   # включаем автозапуск докера при старте компа\n   sudo systemctl enable docker.service\n   sudo systemctl enable containerd.service\n   \n   echo \"Нужно перезапустить компьютер для начала работы с docker\"\n   sudo docker --version\n   ```\n\n\u003c/details\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feabykov%2Fdevops-linux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feabykov%2Fdevops-linux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feabykov%2Fdevops-linux/lists"}