Это статья об основах программирования на Go. На канале я рассказываю об опыте перехода в IT с нуля, структурирую информацию и делюсь мнением.
Хой, джедаи и амазонки!
Рассказываю, как написал программу-аналог утилиты Cat для Linux на Go. Будет теория - в ней расскажу, что это за программа, зачем она нужна. Затем примеры кода и личные наблюдения.
А в конце статьи поделюсь информацией, что интересного происходило за два с половиной месяца с момента предыдущей публикации на Дзене.
1. Чем полезна утилита Cat
Программа "cat" (сокращение от "concatenate") - утилита командной строки, широко используемую в операционных системах Linux. Она предназначена для чтения, объединения и вывода содержимого текстовых файлов в терминал или в другой файл.
Ниже пример работы с терминалом в Linux, где я использую команду cat, чтобы посмотреть содержимое файла first.txt, который содержит текст "контент первого файла".
"Cat" может быть полезной во множестве сценариев и ситуаций. Некоторые из основных случаев использования включают:
- Просмотр содержимого файла: можем использовать "cat" для просмотра содержимого текстового файла в терминале. Это полезно, когда нам нужно быстро посмотреть на содержимое файла без редактирования.
- Создание или объединение файлов: с помощью "cat" можно создавать новые файлы или объединять содержимое нескольких файлов в один. Например, команда "cat file1.txt file2.txt > merged.txt" объединит содержимое файлов "file1.txt" и "file2.txt", и результат будет сохранен в файле "merged.txt".
- Перенаправление вывода: "cat" позволяет перенаправлять вывод в другие программы или файлы. Мы можем использовать утилиту для передачи содержимого одного файла в другую программу для дальнейшей обработки данных.
Программа "cat" является частью проекта GNU Core Utilities и была впервые включена в дистрибутивы Linux в 1987 году (дату подсказала нейросетка, достоверных подтверждений не нашёл в источниках). С тех пор она стала одной из стандартных утилит, которая широко используется в командной строке Linux.
Версия cat в GNU Coreutils, т.е. пакета с различным ПО, была написана Торбьорном Гранлундом и Ричардом Столлманом (Torbjorn Granlund and Richard M. Stallman). Фото Торбьорна найти не удалось, а фото Ричарда см. ниже.
Использование "cat" может быть полезно для системных администраторов, разработчиков и любых пользователей Linux, которым нужно работать с текстовыми файлами в командной строке.
Подробнее об этой программе можно почитать, например, в этой статье на личном сайте веб-разработчика, который копает в направлении открытого ПО. Кстати, у него нет технического образования, но это не мешает ему быть крутым в своём деле.
2. Пишем lite-версию Cat на Go
2.1. Техническое задание
Моя задача сделать минимальный функционал cat. Что там будет:
- В терминал следом за инициацией программы (условного go run main.go) вводим имя одного, двух или трёх файлов.
- Первый и (если он есть) второй файл - те, которые нужно прочитать и вывести содержимое в терминал.
- Если присутствует третий файл - в него нужно записать содержимое первых двух.
Фрагмент запуска кода может выглядеть так:
Здесь мы передаём три аргумента, т.е. три имени файла. Первые два мы прочитаем, а в третий запишем их содержимое.
Go разбираться как это делать.
2.2. Код
С кодом можно ознакомиться на моём GitHub'е. Я использовал для решения задачи os.Args, т.к. аргументы передаются в строгой последовательности, что делает os.Args наиболее уместным.
Далее немного теории об os.Args.
2.3. Об os.Args
Что такое os.Args - рассмотрим стандартную библиотеку:
Суть перевода примерно следующая:
Пакет os предоставляет независимый от платформы интерфейс для работы операционной системы.
Мало что понятно, если честно. Попробую посмотреть, какой тип данных у этой конструкции в IDE на-практике:
Ага, тип данных у переменной os.Args - это []string, т.е. срез строк, - как и указано в спецификации. Уже неплохо.
Библиотека os.Args в языке программирования Go предоставляет доступ к аргументам командной строки, переданным при запуске программы.
Переменная os.Args содержит все аргументы командной строки, включая имя самой программы (это важно). Первый элемент среза os.Args всегда является полным путем и именем запущенного исполняемого файла.
Мы можем использовать переменную os.Args для получения доступа к аргументам командной строки в программе. Например, если мы хотим получить доступ к первому аргументу после имени программы, вы можете обратиться к os.Args[1] - как с обычными массивами.
Итак, теорию по os.Args изучили, идём практиковаться.
2.4. Что интересного в коде
Расскажу о нескольких вещах, на которые стоит обратить внимание.
2.4.1. Функция подсчёта количества аргументов
Рассмотрим фрагмент кода:
1) В строке 19 я возвращаю ошибку (либо её отсутствие). Т.к. логично вернуть ошибку, чтобы вызываемая функция решила, что делать. Что именно делать - другой вопрос, в моей версии пока просто печатать информацию в терминал.
2) В строке 22 я проверяю, чтобы аргументов было минимум 2. Почему два, вы можете спросить. В ТЗ ведь было сказано, что можно принимать и один аргумент. А дело в том, что первым аргументом всегда будет полный путь исполняемого файла.
3) В строке 24 я использовал вложенные условия - это не очень хорошо. У меня был выбор сделать всё через switch, но в этом случае мне пришлось бы пилить одинаковые отдельные функции при наличии одного и двух аргументов, что не есть хорошо для чистого кода. По крайней мере со switch я видел такое развитие ситуации.
Можно было попробовать сначала определить, куда следует делать вывод в зависимости от числа аргументов:
output := os.Stdout
или
output, err = os.OpenFile(fileNameOutput, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
Затем вызывать функцию, передав туда срез из имен файлов которые нужно выводить и то куда выводить
err := printFiles(args, output)
Затем в цикле считать файлы и вывести.
Но как по мне - количество вложенных условий не страшное, поэтому пусть остаётся как есть.
2.4.2. Читаем файлы
Рассмотрим фрагмент кода:
1) В строке 39 я создаю переменную с типом срез байтов. Аналогично можно было бы сделать []uint8, т.к. при чтении файла в строке кода 41, сохранение происходит в такой тип переменной.
2) Далее я записываю в этот срез в строке 46 считанную информацию. Здесь была проблема сделать "энтер" между содержимым двух файлов. Пришлось городить такую конструкцию с двумя append'ами. Иначе было бы примерно такой вывод в терминал содержимого обоих файлов:
Контент первого файлаКонтент второго файла.
А с двумя append'ами получаем следующий вывод:
Контент первого файла
Контент второго файла.
3) Метод чтения из файла использовал самый простой. Способы работы с файлами я наглядно разбирал в этой публикации.
Ещё интересно в этом фрагменте кода то, что я читаю передаваемые аргументы (файлы) в цикле. Т.е. для меня неважно - один аргумент, два, или потенциально большее количество. Т.е. не читаю по-отдельности каждый файл, а перебираю. Это с одной стороны не усложняет код для понимания, и в то же время сокращает количество строк кода. Т.е. хорошее решение на мой взгляд для чистого кода.
2.4.3. Пишем в файл
Рассмотрим фрагмент кода:
В 52й строке я назначаю права доступа к файлу. Подробнее о правах доступа можно почитать в одной из моих предыдущих публикаций.
2.5. Итог разработки аналога Cat
Задача была простая, я её решил после огромного перерыва. Т.е. пришлось восстанавливать в памяти много информации.
Что хочу отметить: практически везде, где можно, использовал хотя бы минимальную обработку ошибок - это правила хорошего тона.
А далее расскажу о том, что происходило во время перерыва занятий.
3. Перерыв в обучении IT
Выпал из обучения IT-сфере на два с половиной месяца: прошлый пост был в конце мая, а сейчас осталось полторы недели до конца лета. И хотелось бы сказать, что была пора отпусков, лето, все дела...
Перерыв был вызван огромным объёмом работы на текущей работе. Из интересного - побывал на чемпионате профессионального мастерства в Сколково по компетенции "Аддитивное производство" Госкорпорации Ростех, см. несколько фото в ленте.
По итогам чемпионата мы с экспертным сообществом задумались об импортонезависимом ПО для чемпионата. Я предложил начать с операционной системы: перейти на Linux. А ещё нужны CAD-программы, слайсеры, ПО для реинжиниринга.
Также, хотя на море толком не удалось побывать этим летом - но в одном из предыдущих постов рассказывал о сотрудничестве с университетом по части НИОКТР. Там ребята помимо работы с "железом" активно пишут ПО на различных ЯП, и один из полезнейших инструментов - нейросетки.
С этим проектом мы должны участвовать на Восточном экономическом форуме ВЭФ-2023 в г.Владивосток, на о.Русский. На этой неделе ездил туда чтобы привезти и собрать макет оборудования, которое разрабатываем и изготавливаем по НИОКТР. А поскольку выставка пройдёт на набережной Японского моря, я немного разрушил мем выше, см. ленту из фото ниже.
На выставке только в павильоне Приморского края будет 85(!) научно-технических проекта, в т.ч. по IT-сфере. Будет интересно разузнать всё как есть, что интересного в IT происходит у нас в регионе. А ведь там будет множество павильонов из других краёв, а может и стран. Хз, впервые буду на ВЭФе.
Вот такие дела. Ещё этим летом познакомился с классной девушкой и успел в неё влюбиться - правда, она сказала, что я не айтишник. Все айтишники, говорит, замкнутые. Ну хз. Успел с ней расстаться уже. По другой причине. Как говориться, спасибо за всё хорошее.
Встретил одноклассника - он работает на машине литья под низким давлением в литейном цеху. Узнал, что он увлёкся IT - учился на тестера. Рассказал ему о Go, он загорелся и со следующей неделе начнёт изучать. Поглядим, к чему это приведёт.
А сейчас я тебе говорю "Успехов, бро!". Спасибо, что дочитал публикацию до конца. Будем на связи.
Бро, ты уже здесь? 👉 Подпишись на канал для новичков «Войти в IT» в Telegram, будем изучать IT вместе 👨💻👩💻👨💻