├── .github └── FUNDING.yml ├── LICENSE ├── README.md ├── README_RUS.md └── files ├── building-architecture ├── horizontal-vertical-scaling_eng.png ├── horizontal-vertical-scaling_rus.png ├── monolith-microservices_eng.png └── monolith-microservices_rus.png ├── common ├── BigO.png ├── BigO_eng.png ├── array.png ├── array_eng.png ├── binary.png ├── graph.png ├── graph_eng.png ├── hash-table.png ├── hash-table_eng.png ├── heap.png ├── heap_eng.png ├── hex.png ├── linked-list.png ├── logic.png ├── logic_eng.png ├── octal.png ├── queue.gif ├── stack.png ├── stack_eng.png └── tree.png ├── databases ├── mongodb-cheatsheet.md └── sql-cheatsheet.md ├── linux ├── bash-scripts-cheatsheet.md ├── chmod.png ├── chmod_eng.png ├── cron.png └── cron_eng.png ├── logo.png ├── network-internet ├── Browser.png ├── Domain.png ├── Hosting.png ├── IPv4-IPv6.png ├── Internet.png ├── Problems.gif ├── Traceroute.png ├── browser_eng.png ├── dns.png ├── domain_eng.png ├── http.png ├── http_eng.png ├── osi.png ├── problems_eng.gif ├── proxy-vpn.png ├── proxy-vpn_eng.png ├── tcp-ip.png ├── tcp-ip_eng.png ├── tcp.png ├── topologies.png ├── topologies_rus.png └── udp.png ├── optimization ├── cdn.png ├── cdn_eng.png ├── load-balancer.png └── load-balancer_eng.png ├── os ├── concurrency-parallel.png ├── os-layer.png ├── os-layer_eng.png ├── process.png └── process_eng.png ├── programming-language └── regex-cheatsheet.md ├── security ├── hashing.png └── hashing_eng.png ├── software ├── message-queue.png ├── message-queue_eng.png ├── web-server_eng.png └── web-server_rus.png └── testing ├── testing-pyramid_eng.png └── testing-pyramid_rus.png /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [cheatsnake] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: yurace 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2023 Yury (cheatsnake) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /files/building-architecture/horizontal-vertical-scaling_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/building-architecture/horizontal-vertical-scaling_eng.png -------------------------------------------------------------------------------- /files/building-architecture/horizontal-vertical-scaling_rus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/building-architecture/horizontal-vertical-scaling_rus.png -------------------------------------------------------------------------------- /files/building-architecture/monolith-microservices_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/building-architecture/monolith-microservices_eng.png -------------------------------------------------------------------------------- /files/building-architecture/monolith-microservices_rus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/building-architecture/monolith-microservices_rus.png -------------------------------------------------------------------------------- /files/common/BigO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/BigO.png -------------------------------------------------------------------------------- /files/common/BigO_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/BigO_eng.png -------------------------------------------------------------------------------- /files/common/array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/array.png -------------------------------------------------------------------------------- /files/common/array_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/array_eng.png -------------------------------------------------------------------------------- /files/common/binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/binary.png -------------------------------------------------------------------------------- /files/common/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/graph.png -------------------------------------------------------------------------------- /files/common/graph_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/graph_eng.png -------------------------------------------------------------------------------- /files/common/hash-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/hash-table.png -------------------------------------------------------------------------------- /files/common/hash-table_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/hash-table_eng.png -------------------------------------------------------------------------------- /files/common/heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/heap.png -------------------------------------------------------------------------------- /files/common/heap_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/heap_eng.png -------------------------------------------------------------------------------- /files/common/hex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/hex.png -------------------------------------------------------------------------------- /files/common/linked-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/linked-list.png -------------------------------------------------------------------------------- /files/common/logic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/logic.png -------------------------------------------------------------------------------- /files/common/logic_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/logic_eng.png -------------------------------------------------------------------------------- /files/common/octal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/octal.png -------------------------------------------------------------------------------- /files/common/queue.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/queue.gif -------------------------------------------------------------------------------- /files/common/stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/stack.png -------------------------------------------------------------------------------- /files/common/stack_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/stack_eng.png -------------------------------------------------------------------------------- /files/common/tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/common/tree.png -------------------------------------------------------------------------------- /files/databases/mongodb-cheatsheet.md: -------------------------------------------------------------------------------- 1 | # Шпаргалка по MongoDB 2 | 3 |
Вернуться на главную страницу ⬆️
4 | 5 | - Подготовка БД 6 | 7 | ```js 8 | show dbs // показать список всех БД 9 | use db_name // подключиться/создать БД с именем db_name 10 | db // вывести имя текущей базы данных 11 | db.createCollection("users") // создать коллекцию "notes" 12 | show collections // показать список коллекций в текущей БД 13 | db.dropDatabase() // удалить текущую БД 14 | ``` 15 | 16 | - Добавление элементов 17 | 18 | ```js 19 | // Добавить один элемент 20 | db.users.insertOne({ 21 | name: "Alex", 22 | age: 27, 23 | isMarried: false, 24 | city: "NewYork" 25 | }) 26 | 27 | // Добавить несколько элементов 28 | db.users.insertMany([{...}, {...}]) 29 | ``` 30 | 31 | - Получение элементов 32 | 33 | ```js 34 | // Получить все элементы из коллекции 35 | db.users.find(); 36 | // Получить элементы по указанному критерию 37 | db.user.find({ age: 27 }); 38 | // Получить один элемент 39 | db.users.findOne({ name: "Alex" }); 40 | // Получить отсортированный список элементов 41 | // 1 - по возрастанию; -1 - по убыванию 42 | db.users.find().sort({ age: 1 }); 43 | // Получить количество элементов 44 | db.users.find().count(); 45 | // Лимит количества получаемых элементов 46 | db.users.find().limit(10); 47 | // Выборка с помощью операторов сравнения 48 | db.users.find({ age: { $gt: 20 } }); // > 20 49 | db.users.find({ age: { $gte: 20 } }); // >= 20 50 | db.users.find({ age: { $lt: 50 } }); // < 50 51 | db.users.find({ age: { $lte: 50 } }); // <= 50 52 | db.users.find({ age: { $ne: 35 } }); // != 35 53 | ``` 54 | 55 | - Изменение элементов 56 | 57 | ```js 58 | // Полное изменение элемента (первый аргумент - критерий поиска) 59 | db.users.updateOne({name: "Alex"}, {новые_данные}) 60 | // Изменение определенных полей элемента 61 | db.users.updateOne({name: "Alex"}, {$set: {age: 28, isMarried: true}}) 62 | // Переименовать поле у нескольких элементов 63 | db.users.updateMany({name: "Alex"}, {&rename: {city: "town"}}) 64 | // Удаление элемента/элементов 65 | db.users.deleteOne({name: "Alex"}) 66 | db.users.deleteMany({name: "Alex"}) 67 | ``` 68 | -------------------------------------------------------------------------------- /files/databases/sql-cheatsheet.md: -------------------------------------------------------------------------------- 1 | # Шпаргалка по SQL 2 | 3 |
Вернуться на главную страницу ⬆️
4 | 5 | - Создание новой БД 6 | ```sql 7 | CREATE DATABASE db_name; 8 | ``` 9 | - Создание новой таблицы 10 | ```sql 11 | CREATE TABLE users ( 12 | id SERIAL PRIMARY KEY, # Уникальный id 13 | firstName VARCHAR(100), # Строка 14 | lastName VARCHAR(100), # Строка 15 | age INT, # Число 16 | gender VARCHAR(10), # Строка 17 | isMarried BOOLEAN # true/false 18 | ); 19 | ``` 20 | - Основные типы данных 21 | > - INT (целые числа от -2^32 до +2^32) 22 | > - FLOAT / DOUBLE / DECIMAL (дробные числа) 23 | > - CHAR / VARCHAR / TEXT (строки) 24 | > - DATA / DATETIME / TIME (дата и время) 25 | > - ENUM (перечисления - списки допустимых значений) 26 | > - [И другие](https://sql-language.ru/osnova-sql/tipy-dannykh-sql.html) 27 | - Добавление данных в таблицу 28 | ```sql 29 | INSERT INTO users( 30 | firstName, lastName, age, gender, isMarried 31 | ) VALUES ( 32 | 'Alex', 'Manson' 25, 'male', false 33 | ); 34 | ``` 35 | - Выборка данных из таблицы 36 | ```sql 37 | # SELECT 38 | ## Получить всю таблицу users 39 | SELECT * FROM users; 40 | ## Получить только столбцы firstName и age из таблицы users 41 | SELECT firstName, age FROM users; 42 | 43 | # LIMIT 44 | ## Получить первых 20 записей таблицы users 45 | SELECT * FROM users LIMIT 20; 46 | 47 | # DISTINCT 48 | ## Получить только уникальные значения из столбца firstName 49 | SELECT DISTINCT(firstName) FROM users; 50 | 51 | # WHERE 52 | ## Записи, где столбец gender = 'male' 53 | SELECT * FROM users WHERE gender = 'male'; 54 | ## AND, OR 55 | SELECT * FROM users WHERE age = 25 AND isMarried = falsel 56 | SELECT * FROM users WHERE age = 20 OR age = 50; 57 | 58 | # BETWEEN 59 | ## Записи, где значения столбца age находятся в промежутке от 20 до 30 60 | SELECT * FROM users WHERE age BETWEEN 20 AND 30; 61 | 62 | #NULL 63 | ## Записи, где столбец lastName не пуст 64 | SELECT * FROM users WHERE lastName IS NOT NULL; 65 | ``` 66 | - Поиск данных по шаблону 67 | ```sql 68 | # IN, LIKE, NOT LIKE 69 | ## % - подстановочный знак, который указывает на любое кол-во символов 70 | ## _ - подстановочный знак, который указывает на один символ 71 | 72 | ## Записи, где firstname равен 'John', 'Mike' или 'Kane' 73 | SELECT * FROM users WHERE firstName IN ('John', 'Mike', 'Kane'); 74 | ## Записи, где firstname начинается c буквы 'A' 75 | SELECT * FROM users WHERE firstName LIKE 'A%'; 76 | ## Записи, где первая буква в firstName равна 'A', 'B' или 'C' 77 | SELECT * FROM users WHERE firstName LIKE '[ABC]%'; 78 | ## Записи, где вторая буква в firstname не равна 'o' 79 | SELECT * FROM users WHERE firstName NOT LIKE '_o%'; 80 | ``` 81 | - Сортировка и фильтрация данных таблиц 82 | ```sql 83 | # ORDER BY 84 | ## ASC - по возрастанию (по умолчанию) 85 | ## DESC - по убыванию 86 | SELECT * FROM users ORDER BY firstName ASC; 87 | SELECT * FROM users ORDER BY age DESC; 88 | SELECT * FROM users ORDER BY lastName DESC, isMarried ASC; 89 | 90 | # HAVING 91 | ## Фильтрация результатов группировки 92 | ``` 93 | - Использование псевдонимов 94 | ```sql 95 | # AS 96 | SELECT firstName AS name FROM users WHERE name = "Alex"; 97 | ``` 98 | - Изменение таблиц 99 | ```sql 100 | # ALTER TABLE 101 | ## Добавить новую колонку city к таблицe users 102 | ALTER TABLE users ADD COLUMN city VARCHAR(50); 103 | ## Удалить колонку isMarried из таблицы users 104 | ALTER TABLE users DROP COLUMN isMarried; 105 | ## Переименовать колонку firstName в fName в таблицe users 106 | ALTER TABLE users RENAME COLUMN firstName TO fName; 107 | ## Переименовать таблицу users в consumers 108 | ALTER TABLE users RENAME TO consumers; 109 | ``` 110 | - Изменение данных в таблице 111 | ```sql 112 | # UPDATE 113 | ## Изменить в таблицe users записать с id = 1 114 | UPDATE users SET firstName = 'Kale', age = 33 WHERE id = 1; 115 | ## Изменить записи, где gender = 'female' 116 | UPDATE users SET city = 'Paris' WHERE gender = 'famale'; 117 | ``` 118 | - Удаление данных из таблицы 119 | ```sql 120 | # DELETE 121 | # Удалить запись в таблице users, где id = 2 122 | DELETE FROM users WHERE id = 2; 123 | # Удалить все записи в таблице users, где gender = 'male' 124 | DELETE FROM users WHERE gender = 'male'; 125 | ``` 126 | - [Агрегатные функции](https://codetown.ru/sql/agregatnye-funkcii/) 127 | > Используются для обобщения/подсчёта данных. 128 | ```sql 129 | # COUNT 130 | ## Возвращает количество элементов в таблице users 131 | SELECT COUNT(*) FROM users; 132 | ## Возвращает количество не повторяющихся значений столбца firstName 133 | SELECT COUNT(DISTINCT(firstName)) FROM users; 134 | 135 | # MAX, MIN 136 | SELECT MAX(age) FROM users; 137 | SELECT MIN(age) FROM users; 138 | 139 | # SUM 140 | # Сумма всех значений столбца age 141 | SELECT SUM(age) FROM users; 142 | 143 | # AVG 144 | ## Среднее значение столбца age 145 | SELECT AVG(age) FROM users; 146 | ``` -------------------------------------------------------------------------------- /files/linux/bash-scripts-cheatsheet.md: -------------------------------------------------------------------------------- 1 | # Шпаргалка по Bash скриптам 2 | 3 |
Вернуться на главную страницу ⬆️
4 | 5 | **Содержание:** 6 | 7 | - [Hello world](#hello-world) 8 | - [Комментарии](#комментарии) 9 | - [Переменные](#переменные) 10 | - [Пользовательский ввод](#пользовательский-ввод) 11 | - [Передача аргументов](#передача-аргументов) 12 | - [Условия if else](#условия-if-else) 13 | - [Операторы условий](#операторы-условий) 14 | - [Логические операторы](#логические-операторы) 15 | - [Арифметические операторы](#арифметические-операторы) 16 | - [Конструкция switch case](#конструкция-switch-case) 17 | - [Массивы](#массивы) 18 | - [Цикл while](#цикл-while) 19 | - [Цикл until](#цикл-until) 20 | - [Цикл for](#цикл-for) 21 | - [Цикл select](#цикл-select) 22 | - [Break и continue в циклах](#break-и-continue-в-циклах) 23 | - [Функции](#функции) 24 | - [Локальные переменные](#локальные-переменные) 25 | - [Ключевое слово readonly](#ключевое-слово-readonly) 26 | - [Обработка сигналов](#обработка-сигналов) 27 | 28 | Скрипты Bash имеют расширение `.sh`: 29 | ``` 30 | $ touch script.sh 31 | ``` 32 | 33 | Хорошей практикой считается указывать путь до вашего терминала вначале каждого скрипта: 34 | ```sh 35 | #! /bin/bash 36 | ``` 37 | > Этот прием называется **shebang**, подробнее можно почитать [тут](https://ru.wikipedia.org/wiki/%D0%A8%D0%B5%D0%B1%D0%B0%D0%BD%D0%B3_(Unix)) 38 | 39 | Список доступных терминалов в вашей системе можно посмотреть с помощью этой команды: 40 | ``` 41 | $ cat /etc/shells 42 | ``` 43 | 44 | ## Hello world 45 | 46 | ```sh 47 | #! /bin/bash 48 | echo "Hello world" 49 | ``` 50 | 51 | Запуск скрипта: 52 | ``` 53 | $ bash script.sh 54 | ``` 55 | 56 | Скрипт можно сделать исполняемым файлом и запускать без команды `bash`: 57 | ``` 58 | $ chmod +x script.sh 59 | ``` 60 | ``` 61 | $ ./script.sh 62 | ``` 63 | 64 | ## Комментарии 65 | 66 | Однострочные комментарии: 67 | ```sh 68 | # Это просто коммент 69 | # И это тоже 70 | echo "Hello from bash" # эта команда выводит строку в консоль 71 | ``` 72 | 73 | Мультистрочные комментарии: 74 | ```sh 75 | : 'Мультистрочные комментарии очень удобны 76 | для подробного описания ваших скриптов. 77 | Успользуйте их с умом!' 78 | ``` 79 | 80 | ## Переменные 81 | 82 | ```sh 83 | MY_STRING="bash is cool" 84 | echo $MY_STRING # Вывод значения переменной 85 | ``` 86 | > Имя переменной не должно начинаться с цифры 87 | 88 | ## Пользовательский ввод 89 | 90 | Команда `read` читает пользовательский ввод и записывает его в указанную переменную: 91 | ```sh 92 | echo "Введите ваше имя:" 93 | read NAME 94 | echo "Привет $NAME!" 95 | ``` 96 | > Если переменная не указана, то команда `read` по умолчанию сохранит все данные в переменную `REPLY` 97 | 98 | 99 | Можно записывать несколько переменных. Для этого, при вводе из терминала, значения необходимо разделять пробелом: 100 | ```sh 101 | read V1 V2 V3 102 | echo "1 переменная: $V1" 103 | echo "2 переменная: $V2" 104 | echo "3 переменная: $V3" 105 | ``` 106 | ``` 107 | $ bash script.sh 108 | $ hello world some other text 109 | 1 переменная: hello 110 | 2 переменная: world 111 | 3 переменная: some other text 112 | ``` 113 | 114 | Флаг `-a` позволяет создать массив в который будут записываться строки пользовательского ввода разделенные пробелом: 115 | ```sh 116 | read -a NAMES 117 | echo "Массив имён: ${NAMES[0]}, ${NAMES[1]}, ${NAMES[2]}" 118 | ``` 119 | ``` 120 | $ bash script.sh 121 | Alex Mike John 122 | Массив имён: Alex, Mike, John 123 | ``` 124 | 125 | Флаг `-p` позволяет не переносить пользовательский ввод на следующую строку. 126 | 127 | Флаг `-s` позволяет скрыть вводимые символы (как это происходит при вводе пароля). 128 | ```sh 129 | read -p "Введите ваш логин: " LOGIN 130 | read -sp "Введите ваш пароль: " PASSWD 131 | ``` 132 | ``` 133 | $ bash script.sh 134 | Введите ваш логин: bash_hacker 135 | Введите ваш пароль: 136 | ``` 137 | 138 | ## Передача аргументов 139 | 140 | Аргументы это просто значения, которые могут быть указаны при запуске скрипта. 141 | 142 | Всем переданным аргументам присваивается уникальное имя равное их порядковому номеру: 143 | ```sh 144 | echo "Аргумент 1 - $1; aргумент 1 - $2; aргумент 1 - $3." 145 | ``` 146 | ``` 147 | $ bash script.sh hello test 1337 148 | Аргумент 1 - hello; aргумент 1 - test; aргумент 1 - 1337. 149 | ``` 150 | 151 | Нулевой аргумент всегда равен названию файла со скриптом: 152 | ```sh 153 | echo "Вы запустили файл $0" 154 | ``` 155 | ``` 156 | $ bash script.sh 157 | Вы запустили файл script.sh 158 | ``` 159 | 160 | Все аргументы можно положить в именованный массив: 161 | ```sh 162 | args=("$@") 163 | echo "Полученные аргументы: ${args[0]}, ${args[1]}, ${args[2]}." 164 | ``` 165 | ``` 166 | $ bash script.sh some values 123 167 | Полученные аргументы: some, values, 123 168 | ``` 169 | > `@` - это название массива по умолчанию, который хранит все аргументы (за исключением нулевого) 170 | 171 | Количество переданных аргументов (за исключением нулевого) хранится в переменной `#`: 172 | ```sh 173 | echo "Всего получено аргументов: $#" 174 | ``` 175 | 176 | ## Условия if else 177 | 178 | Условия всегда начинаются с ключевого слова `if` и заканчиваются на `fi`: 179 | ```sh 180 | echo "Введите ваш возраст:" 181 | read AGE 182 | 183 | if (($AGE >= 18)) 184 | then 185 | echo "Доступ разрешен" 186 | else 187 | echo "Доступ запрещен" 188 | fi 189 | ``` 190 | ``` 191 | $ bash script.sh 192 | Введите ваш возраст: 193 | 19 194 | Доступ разрешен 195 | 196 | $ bash script.sh 197 | Введите ваш возраст: 198 | 16 199 | Доступ запрещен 200 | ``` 201 | 202 | Условий может быть сколько угодно много, для этого используется конструкция `elif`, которая также как `if` может проверять условия: 203 | ```sh 204 | read COMMAND 205 | 206 | if [ $COMMAND = "help" ] 207 | then 208 | echo "Доступные команды:" 209 | echo "ping - вернет строку PONG" 210 | echo "version - вернет номер версии программы" 211 | elif [ $COMMAND = "ping" ] 212 | then 213 | echo "PONG" 214 | elif [ $COMMAND = "version" ] 215 | then 216 | echo "v1.0.0" 217 | else 218 | echo "Команда не определена. Воспользуйтесь командой 'help' для справки" 219 | fi 220 | ``` 221 | > Обратите внимание, что после конструкций `if` и `elif` всегда следует строчка с ключевым словом `then`
222 | > Так же не забывайте отделять условия пробелами внутри фигурных скобок -> `[ condition ]` 223 | 224 | ## Операторы условий 225 | 226 | Для цифр и строк могут использоваться разные операторы сравнения. Полные их списки с примерами приведены в таблицах ниже. 227 | > Обратите внимания, что разные операторы используются с определенными скобками 228 | 229 | ### Операторы сравнения для чисел 230 | 231 | | Оператор | Описание | Пример | 232 | | -------- | -------------------- | ------------------ | 233 | | -eq | равняется ли | if [ $age -eq 18 ] | 234 | | -ne | не равняется | if [ $age -ne 18 ] | 235 | | -gt | больше чем | if [ $age -gt 18 ] | 236 | | -ge | больше чем или равно | if [ $age -ge 18 ] | 237 | | -lt | меньше чем | if [ $age -lt 18 ] | 238 | | -le | меньше чем или равно | if [ $age -le 18 ] | 239 | | > | больше чем | if (($age > 18)) | 240 | | < | меньше чем | if (($age < 18)) | 241 | | => | больше чем или равно | if (($age => 18)) | 242 | | <= | меньше чем или равно | if (($age <= 18)) | 243 | 244 | ### Операторы сравнения для строк 245 | 246 | | Оператор | Описание | Пример | 247 | | -------- | ------------------------------------------- | ------------------------ | 248 | | = | проверка на равенство | if [ $str = "hello" ] | 249 | | == | проверка на равенство | if [ $str == "hello" ] | 250 | | != | проверка на НЕ равенство | if [ $str != "hello" ] | 251 | | < | сравнение меньше чем по ASCII коду символов | if [[ $str < "hello" ]] | 252 | | > | сравнение больше чем по ASCII коду символов | if [[ $str > "hello" ]] | 253 | | -z | проверка пустая ли строка | if [ -z $str ] | 254 | | -n | проверка есть ли в строке хоть один символ | if [ -n $str ] | 255 | 256 | Так же существуют операторы для проверки различных условий над файлами. 257 | 258 | ### Операторы для проверки файлов 259 | 260 | | Оператор | Описание | Пример | 261 | | -------- | --------------------------------------------------------------------------------- | --------------- | 262 | | -e | проверяет, существует ли файл | if [ -e $file ] | 263 | | -s | проверяет, пустой ли файл | if [ -s $file ] | 264 | | -f | проверяет, является ли файл обычным файлом, а не каталогом или специальным файлом | if [ -f $file ] | 265 | | -d | проверяет, является ли файл каталогом | if [ -d $file ] | 266 | | -r | проверяет, доступен ли файл для чтения | if [ -r $file ] | 267 | | -w | проверяет, доступен ли файл для записи | if [ -w $file ] | 268 | | -x | проверяет, является ли файл исполяемым | if [ -x $file ] | 269 | 270 | ## Логические операторы 271 | 272 | Условия с оператором "И" возвращают истину только в том случае, когда все условия истины. 273 | > Существует несколько вариантов написания условий с логическими операторами 274 | 275 | ```sh 276 | if [ $age -ge 18 ] && [ $age -le ] 277 | ``` 278 | ```sh 279 | if [ $age -ge 18 -a $age -le ] 280 | ``` 281 | ```sh 282 | if [[ $age -ge 18 && $age -le ]] 283 | ``` 284 | 285 | Условия с оператором "ИЛИ" возвращают истину в том случае, когда хотя бы одно условие истинно. 286 | 287 | ```sh 288 | if [ -r $file ] || [ -w $file ] 289 | ``` 290 | ```sh 291 | if [ -r $file -o -w $file ] 292 | ``` 293 | ```sh 294 | if [[ -r $file || -w $file ]] 295 | ``` 296 | 297 | ## Арифметические операторы 298 | 299 | ```bash 300 | num1=10 301 | num2=5 302 | 303 | # Сложение 304 | echo $((num1 + num2)) # 15 305 | echo $(expr $num1 + $num2) # 15 306 | 307 | # Вычитание 308 | echo $((num1 - num2)) # 5 309 | echo $(expr $num1 - $num2) # 5 310 | 311 | # Умножение 312 | echo $((num1 * num2)) # 50 313 | echo $(expr $num1 \* $num2) # 50 314 | 315 | # Деление 316 | echo $((num1 / num2)) # 2 317 | echo $(expr $num1 / $num2) # 2 318 | 319 | # Остаток от деления 320 | echo $((num1 % num2)) # 0 321 | echo $(expr $num1 % $num2) # 0 322 | ``` 323 | > Обратите внимание, что при использовании умножения с ключевым словом `expr` необходимо использовать косую черту. 324 | 325 | ## Конструкция switch case 326 | 327 | Не всегда удобно использовать конструкции if/elif для большого количества условий. Для этого лучше подойдет конструкция case: 328 | 329 | ```sh 330 | read COMMAND 331 | 332 | case $COMMAND in 333 | "/help" ) 334 | echo "Вы открыли справочное меню" ;; 335 | "/ping" ) 336 | echo "PONG" ;; 337 | "/version" ) 338 | echo "Текущая версия: 1.0.0" ;; 339 | * ) 340 | echo "Такой команды нет :(" ;; 341 | esac 342 | ``` 343 | 344 | > Случай со звездочкой * отработает лишь в том случае, если не подойдет ни одно из условий выше. 345 | 346 | ## Массивы 347 | 348 | Массивы позволяют хранить целую коллекцию данных в одной переменной. С этой переменной можно удобно и легко взаимодействовать: 349 | 350 | ```sh 351 | array=('aaa' 'bbb' 'ccc' 'ddd') 352 | 353 | echo "Элементы массива: ${array[@]}" 354 | echo "Первый элемент массива: ${array[0]}" 355 | echo "Индексы элементов массива: ${!array[@]}" 356 | 357 | array_length=${#array[@]} 358 | echo "Длинна массива: ${array_length}" 359 | echo "Последний элемент массива: ${array[$((array_length - 1))]}" 360 | ``` 361 | ``` 362 | $ bash script.sh 363 | Элементы массива: aaa bbb ccc ddd 364 | Первый элемент массива: aaa 365 | Индексы элементов массива: 0 1 2 3 366 | Длинна массива: 4 367 | Последний элемент массива: ddd 368 | ``` 369 | > Обратите внимание, что элементы массива разделются пробелом без запятой. 370 | 371 | Элементы массива можно добавлять/перезаписывать/удалять по ходу выполнения скрипта: 372 | 373 | ```sh 374 | array=('a' 'b' 'c') 375 | 376 | array[3]='d' 377 | echo ${array[@]} # a b c d 378 | 379 | array[0]='x' 380 | echo ${array[@]} # x b c d 381 | 382 | array[0]='x' 383 | echo ${array[@]} # x b c d 384 | 385 | unset array[2] 386 | echo ${array[@]} # x b d 387 | ``` 388 | 389 | ## Цикл while 390 | 391 | Цикл while повторяет выполение блока кода описанного между ключевыми словами `do` - `done` пока истино заданное условие. 392 | 393 | ```sh 394 | i=0 395 | 396 | while (( $i < 5 )) 397 | do 398 | i=$((i + 1)) 399 | echo "Итерация номер $i" 400 | done 401 | ``` 402 | ``` 403 | $ bash script.sh 404 | Итерация номер 1 405 | Итерация номер 2 406 | Итерация номер 3 407 | Итерация номер 4 408 | Итерация номер 5 409 | ``` 410 | 411 | Операция увеличения числа на 1 единицу называется инкриментом и для неё существует специальная запись: 412 | 413 | ```sh 414 | (( i++ )) # post increment 415 | ``` 416 | ```sh 417 | (( ++i )) # pre increment 418 | ``` 419 | 420 | Противоположная операция - декремент: 421 | 422 | ```sh 423 | (( i-- )) # post decrement 424 | ``` 425 | ```sh 426 | (( --i )) # pre decrement 427 | ``` 428 | 429 | С помощью while циклов можно построчно читать различные файлы. Существует несколько способов сделать это: 430 | 431 | ```sh 432 | echo "Чтение файла по строкам:" 433 | while read line 434 | do 435 | echo $line 436 | done < text.txt 437 | ``` 438 | 439 | ```sh 440 | echo "Чтение файла по строкам:" 441 | cat text.txt | while read line 442 | do 443 | echo $line 444 | done 445 | ``` 446 | 447 | ```sh 448 | echo "Чтение файла по строкам:" 449 | while IFS='' read -r line 450 | do 451 | echo $line 452 | done < text.txt 453 | ``` 454 | 455 | ## Цикл until 456 | 457 | Цикл until противоположен циклу while тем, что он выполняет блок кода описанный между ключевыми словами `do` - `done` тогда, когда заданное условие возвращает false: 458 | 459 | ```sh 460 | i=5 461 | until (( $i == 0 )) # будет выполняться пока i не станет равным 0 462 | do 463 | echo "Значение переменной i = $i" 464 | (( i-- )) 465 | done 466 | ``` 467 | ``` 468 | $ bash script.sh 469 | Значение переменной i = 5 470 | Значение переменной i = 4 471 | Значение переменной i = 3 472 | Значение переменной i = 2 473 | Значение переменной i = 1 474 | ``` 475 | 476 | ## Цикл for 477 | 478 | Самый классический цикл: 479 | ```sh 480 | for (( i=1; i<=10; i++ )) 481 | do 482 | echo $i 483 | done 484 | ``` 485 | 486 | В новых версиях Bash существует более удобный способ записи с помощью оператора `in`: 487 | 488 | ```sh 489 | for i in {1..10} 490 | do 491 | echo $i 492 | done 493 | ``` 494 | 495 | Условие после ключевого слова `in` в общем случае выгядит так: 496 | 497 | ``` 498 | {START..END..INCREMENT} 499 | ``` 500 | > _START_ - с какого элемента начинать цикл;
501 | > _END_ - до какого элемента продолжать цикл;
502 | > _INCREMENT_ - на сколько увеличивать элемент после каждой итерации (по умолчанию на 1). 503 | 504 | 505 | Цикл for можно использовать для последовательного запуска набора команд: 506 | 507 | ```sh 508 | for command in ls pwd date # Список команд для запуска 509 | do 510 | echo "---Запуск команды $command---" 511 | $command 512 | echo "------------------------" 513 | done 514 | ``` 515 | ``` 516 | $ bash script.sh 517 | ---Запуск команды ls--- 518 | script.sh text.txt 519 | ------------------------ 520 | ---Запуск команды pwd--- 521 | /home/user/bash 522 | ------------------------ 523 | ---Запуск команды date--- 524 | Сб 03 сен 2022 10:35:57 +03 525 | ------------------------ 526 | ``` 527 | 528 | Ключевое слово `break` останавливает выполнение цикла. 529 | 530 | Ключевое слово `continue` завершает текущую итерацию цикла и переходит к следующей.
531 | 532 | ## Цикл select 533 | 534 | Крайне удобный цикл для создания меню выбора опций: 535 | 536 | ```sh 537 | select color in "Красный" "Зеленый" "Синий" "Белый" 538 | do 539 | echo "Вы выбрали $color цвет..." 540 | done 541 | ``` 542 | ``` 543 | $ bash script.sh 544 | 1) Красный 545 | 2) Зеленый 546 | 3) Синий 547 | 4) Белый 548 | #? 1 549 | Вы выбрали Красный цвет... 550 | #? 2 551 | Вы выбрали Зеленый цвет... 552 | #? 3 553 | Вы выбрали Синий цвет... 554 | #? 4 555 | Вы выбрали Белый цвет... 556 | ``` 557 | 558 | Цикл `select` очень хорошо сочетается с оператором выбора `case`. Таким образом можно очень просто создавать интерактивные консольные приложения с большим количеством разветвлений: 559 | 560 | ```sh 561 | echo "---Добро пожаловать в меню---" 562 | 563 | select cmd in "Запуск" "Настройки" "О программе" "Выход" 564 | do 565 | case $cmd in 566 | "Запуск") 567 | echo "Программа запущена" 568 | echo "Введите число:" 569 | read input 570 | echo "$input в квадрате = $(( input * input ))" ;; 571 | "Настройки") 572 | echo "Настройки программы" ;; 573 | "О программе") 574 | echo "Версия 1.0.0" ;; 575 | "Выход") 576 | echo "Выход из программы..." 577 | break ;; 578 | esac 579 | done 580 | ``` 581 | 582 | ## Break и continue в циклах 583 | 584 | Для принудительного выхода из цикла используется ключевое слово `break`: 585 | 586 | ```sh 587 | count=1 588 | 589 | while (($count)) # всегда возвращает истину 590 | do 591 | if (($count > 10)) 592 | then 593 | break # принудительный выход несмотря на условие после while 594 | else 595 | echo $count 596 | ((count++)) 597 | fi 598 | done 599 | ``` 600 | 601 | Для того, чтобы пропустить выполнение текущей итерации в цикле и перейти к следующей - используется ключевое слово `continue`: 602 | 603 | ```sh 604 | for (( i=5; i>0; i-- )) 605 | do 606 | if ((i % 2 == 0)) 607 | then 608 | continue 609 | fi 610 | 611 | echo $i 612 | done 613 | ``` 614 | ``` 615 | $ bash script.sh 616 | 5 617 | 3 618 | 1 619 | ``` 620 | 621 | ## Функции 622 | 623 | Функции - это именованные участки кода, которые могут переиспользоваться неограниченное количество раз: 624 | 625 | ```sh 626 | hello() { 627 | echo "Hello World!" 628 | } 629 | 630 | # вызываем функцию 3 раза: 631 | hello 632 | hello 633 | hello 634 | ``` 635 | ``` 636 | $ bash script.sh 637 | Hello World! 638 | Hello World! 639 | Hello World! 640 | ``` 641 | 642 | Функции, так же, как и сами скрипты, могут принимать аргументы. Они имеют такие же названия, но аргументы функций видны только внутри функции, в которую они были переданы: 643 | 644 | ```sh 645 | echo "$1" # аргумент переданный при запуске скрипта 646 | 647 | calc () { 648 | echo "$1 + $2 = $(($1 + $2))" 649 | } 650 | 651 | # передача двух аргументов в функцию calc 652 | calc 42 17 653 | ``` 654 | ``` 655 | $ bash script.sh hello 656 | hello 657 | 42 + 17 = 59 658 | ``` 659 | 660 | ## Локальные переменные 661 | 662 | Если мы объявим какую-либо переменную, а затем объявим ещё одну с таким же именем, но уже внутри функции, то у нас произойдет перезапись: 663 | 664 | ```sh 665 | VALUE="hello" 666 | 667 | test() { 668 | VALUE="linux" 669 | } 670 | 671 | test 672 | echo $VALUE 673 | ``` 674 | ``` 675 | $ bash script.sh 676 | linux 677 | ``` 678 | 679 | Чтобы предотвратить такое поведение используются ключевое слово `local` перед именем переменной, которая объявляется внутри функции: 680 | 681 | ```sh 682 | VALUE="hello" 683 | 684 | test() { 685 | local VALUE="linux" 686 | echo "Переменная внутри функции: $VALUE" 687 | } 688 | 689 | test 690 | echo "Глобальная переменная: $VALUE" 691 | ``` 692 | ``` 693 | $ bash script.sh 694 | Переменная внутри функции: linux 695 | Глобальная переменная: hello 696 | ``` 697 | 698 | ## Ключевое слово readonly 699 | 700 | По умолчанию, каждая созданная переменная в Bash в последующем может перезаписываться. Чтобы защитить переменную от изменений можно использовать ключевое слово `readonly`: 701 | 702 | ```sh 703 | readonly PI=3.14 704 | PI=100 705 | 706 | echo "PI = $PI" 707 | ``` 708 | ``` 709 | $ bash script.sh 710 | script.sh: строка 2: PI: переменная только для чтения 711 | PI = 3.14 712 | ``` 713 | 714 | `readonly` можно использовать не только в момент объявления переменной, но и после: 715 | 716 | ```sh 717 | VALUE=123 718 | VALUE=$(($VALUE * 1000)) 719 | readonly VALUE 720 | VALUE=555 721 | 722 | echo $VALUE 723 | ``` 724 | ``` 725 | $ bash script.sh 726 | script.sh: строка 4: VALUE: переменная только для чтения 727 | 123000 728 | ``` 729 | 730 | Тоже самое касается функций. Они так же могут быть переопределены, поэтому их можно защитить с помощью `readonly` указав при этом флаг `-f`: 731 | 732 | ```sh 733 | test() { 734 | echo "This is test function" 735 | } 736 | 737 | readonly -f test 738 | 739 | test() { 740 | echo "Hello World!" 741 | } 742 | 743 | test 744 | ``` 745 | ``` 746 | $ bash script.sh 747 | script.sh: строка 9: test: значение функции можно только считать 748 | This is test function 749 | ``` 750 | 751 | ## Обработка сигналов 752 | 753 | Во время выполнения скриптов, могут происходить неожиданные действия. Например, пользователь может прервать выполнения скрипта с помощь комбинации `Ctrl + C`, либо может случайно закрыть терминал или в самом скрипте может случится какая-либо ошибка и так далее... 754 | 755 | В POSIX-системах существуют специальные сигналы - уведомления процесса о каком-либо событии. Их список определен в таблице ниже: 756 | 757 | | Сигнал | Код | Действие | Описание | 758 | | ------- | -------- | -------------------------- | -------------------------------------------------------- | 759 | | SIGHUP | 1 | Завершение | Закрытие терминала | 760 | | SIGINT | 2 | Завершение | Сигнал прерывания (Ctrl-C) с терминала | 761 | | SIGQUIT | 3 | Завершение с дампом памяти | Сигнал «Quit» с терминала (Ctrl-) | 762 | | SIGILL | 4 | Завершение с дампом памяти | Недопустимая инструкция процессора | 763 | | SIGABRT | 6 | Завершение с дампом памяти | Сигнал, посылаемый функцией abort() | 764 | | SIGFPE | 8 | Завершение с дампом памяти | Ошибочная арифметическая операция | 765 | | SIGKILL | 9 | Завершение | Процесс уничтожен (kill signal) | 766 | | SIGSEGV | 11 | Завершение с дампом памяти | Нарушение при обращении в память | 767 | | SIGPIPE | 13 | Завершение | Запись в разорванное соединение (пайп, сокет) | 768 | | SIGALRM | 14 | Завершение | Сигнал истечения времени, заданного alarm() | 769 | | SIGTERM | 15 | Завершение | Сигнал завершения (сигнал по умолчанию для утилиты kill) | 770 | | SIGUSR1 | 30/10/16 | Завершение | Пользовательский сигнал № 1 | 771 | | SIGUSR2 | 31/12/17 | Завершение | Пользовательский сигнал № 2 | 772 | | SIGCHLD | 20/17/18 | Игнорируется | Дочерний процесс завершен или остановлен | 773 | | SIGCONT | 19/18/25 | Продолжить выполнение | Продолжить выполнение ранее остановленного процесса | 774 | | SIGSTOP | 17/19/23 | Остановка процесса | Остановка выполнения процесса | 775 | | SIGTSTP | 18/20/24 | Остановка процесса | Сигнал остановки с терминала (Ctrl-Z) | 776 | | SIGTTIN | 21/21/26 | Остановка процесса | Попытка чтения с терминала фоновым процессом | 777 | | SIGTTOU | 22/22/27 | Остановка процесса | Попытка записи на терминал фоновым процессом | 778 | 779 | В Bash есть ключевое слово `trap` с помощью которого можно отлавливать различные сигналы и предусматривать выполнение определенных команд: 780 | 781 | ``` 782 | trap <КОМАНДА> <СИГНАЛ> 783 | ``` 784 | > Под сигналом можно использовать его название (колонка _Сигнал_ в таблице), либо его код (колонка _Код_ в таблице). Можно указывать несколько сигналов разделяя их названия или коды пробелом.
785 | > **Исключения:** сигналы SIGKILL (9) и SIGSTOP (17/19/23) отловить невозможно, поэтому нет смысла их указывать. 786 | 787 | ```sh 788 | trap "echo Выполнение программы прервано...; exit" SIGINT 789 | 790 | for i in {1..10} 791 | do 792 | sleep 1 793 | echo $i 794 | done 795 | ``` 796 | ``` 797 | $ bash script.sh 798 | 1 799 | 2 800 | 3 801 | 4 802 | ^CВыполнение программы прервано... 803 | ``` 804 | 805 | ## Отладка скриптов 806 | 807 | Запуск скрипта с параметром `-x` покажет его поэтапное выполнение, что будет полезно при отладке и поиске ошибок: 808 | 809 | ``` 810 | $ bash -x script.sh 811 | ``` 812 | 813 |
Вернуться в начало ⬆️
-------------------------------------------------------------------------------- /files/linux/chmod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/linux/chmod.png -------------------------------------------------------------------------------- /files/linux/chmod_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/linux/chmod_eng.png -------------------------------------------------------------------------------- /files/linux/cron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/linux/cron.png -------------------------------------------------------------------------------- /files/linux/cron_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/linux/cron_eng.png -------------------------------------------------------------------------------- /files/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/logo.png -------------------------------------------------------------------------------- /files/network-internet/Browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Browser.png -------------------------------------------------------------------------------- /files/network-internet/Domain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Domain.png -------------------------------------------------------------------------------- /files/network-internet/Hosting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Hosting.png -------------------------------------------------------------------------------- /files/network-internet/IPv4-IPv6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/IPv4-IPv6.png -------------------------------------------------------------------------------- /files/network-internet/Internet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Internet.png -------------------------------------------------------------------------------- /files/network-internet/Problems.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Problems.gif -------------------------------------------------------------------------------- /files/network-internet/Traceroute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/Traceroute.png -------------------------------------------------------------------------------- /files/network-internet/browser_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/browser_eng.png -------------------------------------------------------------------------------- /files/network-internet/dns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/dns.png -------------------------------------------------------------------------------- /files/network-internet/domain_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/domain_eng.png -------------------------------------------------------------------------------- /files/network-internet/http.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/http.png -------------------------------------------------------------------------------- /files/network-internet/http_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/http_eng.png -------------------------------------------------------------------------------- /files/network-internet/osi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/osi.png -------------------------------------------------------------------------------- /files/network-internet/problems_eng.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/problems_eng.gif -------------------------------------------------------------------------------- /files/network-internet/proxy-vpn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/proxy-vpn.png -------------------------------------------------------------------------------- /files/network-internet/proxy-vpn_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/proxy-vpn_eng.png -------------------------------------------------------------------------------- /files/network-internet/tcp-ip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/tcp-ip.png -------------------------------------------------------------------------------- /files/network-internet/tcp-ip_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/tcp-ip_eng.png -------------------------------------------------------------------------------- /files/network-internet/tcp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/tcp.png -------------------------------------------------------------------------------- /files/network-internet/topologies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/topologies.png -------------------------------------------------------------------------------- /files/network-internet/topologies_rus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/topologies_rus.png -------------------------------------------------------------------------------- /files/network-internet/udp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/network-internet/udp.png -------------------------------------------------------------------------------- /files/optimization/cdn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/optimization/cdn.png -------------------------------------------------------------------------------- /files/optimization/cdn_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/optimization/cdn_eng.png -------------------------------------------------------------------------------- /files/optimization/load-balancer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/optimization/load-balancer.png -------------------------------------------------------------------------------- /files/optimization/load-balancer_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/optimization/load-balancer_eng.png -------------------------------------------------------------------------------- /files/os/concurrency-parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/concurrency-parallel.png -------------------------------------------------------------------------------- /files/os/os-layer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/os-layer.png -------------------------------------------------------------------------------- /files/os/os-layer_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/os-layer_eng.png -------------------------------------------------------------------------------- /files/os/process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/process.png -------------------------------------------------------------------------------- /files/os/process_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/os/process_eng.png -------------------------------------------------------------------------------- /files/programming-language/regex-cheatsheet.md: -------------------------------------------------------------------------------- 1 | # Шпаргалка по регулярным выражениям 2 | 3 |
Вернуться на главную страницу ⬆️
4 | 5 | **Содержание:** 6 | 7 | - [Базовое применение](#базовое-применение) 8 | - [Флаги](#флаги) 9 | - [Основной синтаксис](#основной-синтаксис) 10 | - [Любой символ .](#любой-символ-) 11 | - [Перечень []](#перечень-) 12 | - [Исключающий перечень [^]](#исключающий-перечень-) 13 | - [Диапазон [-]](#диапазон--) 14 | - [Повторения *](#повторения-) 15 | - [Повторения +](#повторения--1) 16 | - [Необязательный символ ?](#необязательный-символ-) 17 | - [Количество повторений {}](#количество-повторений-) 18 | - [Диапазон повторений {,}](#диапазон-повторений-) 19 | - [Группировка ()](#группировка-) 20 | - [Логическое ИЛИ |](#логическое-или-) 21 | - [Экранирование](#экранирование-) 22 | - [Поиск в начале строки ^](#поиск-в-начале-строки-) 23 | - [Поиск в конце строки $](#поиск-в-конце-строки-) 24 | - [Классы символов](#классы-символов) 25 | - [Позиционные проверки](#позиционные-проверки) 26 | 27 | 28 | [Регулярные выражения](https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F) – это мощный инструмент для поиска и замены слов в тексте. Само регулярное выражение представляет из себя обычную строку составленную по определенным правилами. В общем виде она представляет из себя две косые черты `/ /`, где после первой черты идёт специальный паттерн для поиска, а после второй – набор флагов. 29 | 30 | Для тренировки использования регулярных выражений можно воспользоваться сайтом [Regex101.com](https://regex101.com/). 31 | 32 | Также можно воспользоваться возможностями для работы с регулярными выражениями в одном из языков программирования. Вот примеры для [Python](https://pythonru.com/primery/primery-primeneniya-regulyarnyh-vyrazheniy-v-python), [JavaScript](https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Regular_Expressions), [Go](https://tproger.ru/articles/puteshestvie-v-golang-regexp/), [Kotlin](https://java-blog.ru/kotlin/vvedenie-v-regulyarnye-vyrazheniya-kotlin), [C#](https://metanit.com/sharp/tutorial/7.4.php) и [так далее](https://www.google.com/search?q=%D0%BA%D0%B0%D0%BA+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C+%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5+%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F+%D0%B2+%5B%D0%B2%D0%B0%D1%88+%D1%8F%D0%B7%D1%8B%D0%BA+%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%5D%5D) 33 | 34 | ## Базовое применение 35 | 36 | Возьмем для примера любой текст. Представим, что в этом тексте нам нужно найти все слова `London`. Это самый простой случай использования регулярных выражения, нам всего лишь необходимо вписать нужное слово между косыми чертами: 37 | 38 |

Regex example

39 | 40 | ## Флаги 41 | 42 | Флаги влияют на результат поиска. Их всего 5 штук: 43 | 44 | - `i` – позволяет игнорировать регистры букв (нет разницы между *A* и *a*). 45 | - `g` – позволяет искать все совпадения в тексте, без него – только первое. 46 | - `m` – включение многострочного режима (влияет только на поведение `^` и `$`). 47 | - `s` – текст трактуется как одна строка, в этом случае метасимволу `.` (точка) соответствует любой одиночный символ, включая символ новой строки. 48 | - `u` – unicode-трактовка. Выражение может содержать специальные паттерны, характерные для юникода. 49 | 50 | ## Основной синтаксис 51 | 52 | ### Любой символ `.` 53 | 54 | На месте точки может быть любой символ. Количеством точек можно определять длину слов. 55 | 56 | ```js 57 | /t..k/g 58 | ``` 59 | 60 | > take look team took hike track teak time 61 | 62 | ### Перечень `[]` 63 | 64 | Позволяют указать определенный перечень символов. 65 | 66 | ```js 67 | /t[aoi]k/g 68 | ``` 69 | 70 | > tek tok tdk tak tik tuk tyk took taoik 71 | 72 | ### Исключающий перечень `[^]` 73 | 74 | Позволяет исключить определенный набор символ из поиска, используется вместе с квадратными скобками. 75 | 76 | ```js 77 | /ba[^td]/g 78 | ``` 79 | 80 | > ban bag bat bas bad 81 | 82 | ### Диапазон `[-]` 83 | 84 | Указывает диапазон с первого по последний символ (включительно) в алфавитном порядке. 85 | 86 | ```js 87 | /[a-d]../g 88 | ``` 89 | 90 | > ost hst ast fst cst bst 91 | 92 | Аналогично работает с цифрами: 93 | 94 | ```js 95 | /201[5-9]/g 96 | ``` 97 | 98 | > 2010 2012 2015 2017 2019 2022 99 | 100 | ### Повторения `*` 101 | 102 | Звездочка после символа указывает, что данный символ может отсутствовать, либо совпадать один или более раз. 103 | 104 | ```js 105 | /wo*w/g 106 | ``` 107 | 108 | > wow waw wiw woooow wawe ww woow 109 | 110 | ### Повторения `+` 111 | 112 | Плюс после символа указывает, что данный символ должен присутствовать один или более раз. 113 | 114 | ```js 115 | /go+gle/g 116 | ``` 117 | 118 | > google ggle gogle gugle g00gle goooogle 119 | 120 | ### Необязательный символ `?` 121 | 122 | Вопросительный знак после символа указывает, что данный символ является не обязательным (может либо отсутствовать, либо встрачаться только один раз). 123 | 124 | ```js 125 | /bou?nd/g 126 | ``` 127 | 128 | > bond bound bouuund boynd 129 | 130 | ### Количество повторений `{}` 131 | 132 | Чтобы указать точное количеcтво повторений, необходимо после символа записать фигурные скобки с нужным числом. 133 | 134 | ```js 135 | /bo{3}m/g 136 | ``` 137 | 138 | > boom bom booom bm boooom 139 | 140 | ### Диапазон повторений `{,}` 141 | 142 | Чтобы указать диапазон повторений, необходимо после символа записать фигурный скобки с нужным диапазоном, разделенным запятой. 143 | 144 | ```js 145 | /lo{2,4}k/g 146 | ``` 147 | 148 | > lok look lk loook looook loooooook 149 | 150 | Верхнюю границу можно опускать. Например, запись `a{3,}` говорит о том, что символ _a_ должен встречаться не менее трёх раз. 151 | 152 | ### Группировка `()` 153 | 154 | Скобки позволяют сгруппировать любую последовательность символов, чтобы в дальнейшем обращается к ним используя выражение `\число`, где число - порядковый номер сгруппированной последовательности. 155 | 156 | ```js 157 | /(la)-\1{2}-\1{3}/g // Группируем выражение "la" и затем, обращаемся к нему через "\1" 158 | ``` 159 | 160 | > la-laaa-la-lala-lalala-lalala-la-la-la 161 | 162 | ```js 163 | /(la)-\1-(laa)-\2/g 164 | ``` 165 | 166 | > laa-la-laa-la-la-laa-laa-lalal 167 | 168 | Чтобы игнорировать сохранение группы используется конструкция `(?:)`. 169 | 170 | ```js 171 | /(?:abc)-(test),\1,\1/g // В данном случае группа "abc" не будет сохранена, поэтому первый индекс указывает на "test". 172 | ``` 173 | 174 | > abc,test-abc-test,test,test-abc-test 175 | 176 | Группам можно задавать любые имена. Для этого используется конструкция - `(?P...)`, где Name - название, ... - любая последовательность символов. Для обращения к именованным группам используется конструкция - `(?P=Name)`. 177 | 178 | ```js 179 | /(?P7{3})-(?P=seven){2}-(?P=seven)/g 180 | ``` 181 | 182 | > 7777-77-7777777-777-777777-777-777-7-7-7-7777-7 183 | 184 | Если у Вас возникли трудности с пониманием группировки, советую [посмотреть данное видео](https://youtu.be/W9CffcsYpAU). 185 | 186 | ### Логическое ИЛИ `|` 187 | 188 | Вертикальная черта позволяет указывать альтернативные варианты для поиска. Это чем-то похоже на использование квадратных скобок `[abc]`, но только вертикальная черта может работать с целыми словами и выражениями, а не только с отдельными символами. 189 | 190 | ```js 191 | /yes|no/g 192 | ``` 193 | 194 | > yes,maybe,no,idk,ok 195 | 196 | ### Экранирование `\` 197 | 198 | Для того, чтобы использовать в поиске специальные символы `{} [] / \ + *. $ ^ |?`, необходимо поставить впереди знак косой черты `\`. 199 | 200 | ```js 201 | /\.|\?/g // Поиск точек "." или знаков вопроса "?" 202 | ``` 203 | 204 | > What now? What next? Times up. Wake up. 205 | 206 | ### Поиск в начале строки `^` 207 | 208 | Символ каретки в регулярном выражении говорит о том, что поиск производится только по началу строк. 209 | 210 | ```js 211 | /^[0-9]*/gm // Поиск чисел которые находятся в начале строки 212 | ``` 213 | 214 | > 1. Apples x10
215 | > 2. Cookies x5
216 | > 3. Eggs x7 217 | 218 | ### Поиск в конце строки `$` 219 | 220 | Символ доллара в регулярном выражении говорит о том, что поиск производится только по концу строк. 221 | 222 | ```js 223 | /com|net/gm 224 | ``` 225 | 226 | > google.com
227 | > nodejs.org
228 | > sourceforge.net 229 | 230 | ### Классы символов 231 | 232 | Для более удобного поиска целого класса символов существуют встроенные обозначения. 233 | 234 | #### Любой словесный символ `\w` 235 | 236 | Обе записи ниже эквивалентны. 237 | 238 | ```js 239 | /[a-zA-Z0-9_]/g 240 | ``` 241 | 242 | ```js 243 | /\w/g 244 | ``` 245 | 246 | > some random words for example 247 | 248 | #### Любой не словесный символ `\W` 249 | 250 | ```js 251 | /[^a-zA-Z0-9_]/g 252 | ``` 253 | 254 | ```js 255 | /\W/g 256 | ``` 257 | 258 | > developer_2022@gmail.com 259 | 260 | #### Любая цифра `\d` 261 | 262 | ```js 263 | /[0-9]/g 264 | ``` 265 | 266 | ```js 267 | /\d/g 268 | ``` 269 | 270 | > developer_2022@gmail.com 271 | 272 | #### Любой символ кроме цифр `\D` 273 | 274 | ```js 275 | /[^0-9]/g 276 | ``` 277 | 278 | ```js 279 | /\D/g 280 | ``` 281 | 282 | > developer_2022@gmail.com 283 | 284 | #### Пробел `\s` 285 | 286 | К пробелам также относятся различные символы переноса строк. 287 | 288 | ```js 289 | /[\r\n\t\f\v ]/g 290 | ``` 291 | 292 | ```js 293 | /\s/g 294 | ``` 295 | 296 | #### Любой символ кроме пробела `\S` 297 | 298 | ```js 299 | /[^\r\n\t\f\v ]/g 300 | ``` 301 | 302 | ```js 303 | /\S/g 304 | ``` 305 | 306 | ### Позиционные проверки 307 | 308 | Для того, чтобы найти фразу, которая должна находится до или после другой фразы используются позиционные проверки (lookarounds). 309 | 310 | #### Опережающие проверки `(?=)` `(?!)` 311 | 312 | Чтобы найти выражение Х после которого стоит выражение Y, используется конструкция `X(?=Y)`. 313 | 314 | ```js 315 | /\d+(?=€)/g 316 | ``` 317 | 318 | > 200$ 750€ 100$ 330€ 550$ 319 | 320 | Чтобы найти выражение Х после которого НЕ стоит выражение Y, используется конструкция `X(?!Y)`. 321 | 322 | ```js 323 | /\d{4,}(?!€)/g 324 | ``` 325 | 326 | > This car was costed about 7000€ in 2015 327 | 328 | #### Ретроспективные проверки `(?<=)` `(? {"id":4,"value":123,name:"test"} 337 | 338 | Чтобы найти выражение X перед которым НЕ стоит выражение Y, используется конструкция `(? $5 $6 $7 2019 2009 1999 345 | 346 | 347 | ## Практика 348 | 349 | Потратьте немного времени на закрепление изученного материала. Напишите простую библиотеку на Вашем любимом языке программирования, которая будет выполнять валидации (проверки) заданных строк. Например, на соответствие электронной почты или номера телефона. Напишите валидатор для паролей, чтобы он соответствовал заданным требованиям по длине, наличию специальных символов, заглавных букв или цифр. Это будет вдвойне полезным занятием, поскольку в будущем вы сможете использовать эту библиотеку в Ваших приложениях. 350 | 351 | Дополнительно по запросу в Google – _regex practice_, можно найти много интересных заданий на тему регулянрых выражений. 352 | 353 | ## Дополнительные материалы 354 | 355 | 1. 📄 [**Awesome Regex** – GitHub](https://github.com/aloisdg/awesome-regex) 356 | 1. 📺 [**Регулярные выражения в SEO: где и как применяются** – YouTube](https://youtu.be/ZxWfQW32dIE) 357 | 1. 📘 [**Регулярные выражения. Сборник рецептов** – Ян Гойвертс, Стивен Левитан, 2010](https://www.litmir.me/data/Book/0/156000/156298/Goiverts_Yan_Regulyarnye_vyracheniya._Sbornik_receptov_%5BPodrobnye_resheniya_na_vosmi_yazykah_programmirova_Litmir.net_bid156298_original.pdf) 358 | -------------------------------------------------------------------------------- /files/security/hashing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/security/hashing.png -------------------------------------------------------------------------------- /files/security/hashing_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/security/hashing_eng.png -------------------------------------------------------------------------------- /files/software/message-queue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/software/message-queue.png -------------------------------------------------------------------------------- /files/software/message-queue_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/software/message-queue_eng.png -------------------------------------------------------------------------------- /files/software/web-server_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/software/web-server_eng.png -------------------------------------------------------------------------------- /files/software/web-server_rus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/software/web-server_rus.png -------------------------------------------------------------------------------- /files/testing/testing-pyramid_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/testing/testing-pyramid_eng.png -------------------------------------------------------------------------------- /files/testing/testing-pyramid_rus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheatsnake/backend-cheats/493ead9f33501a3f1da2d33abfaa878d1bf98e43/files/testing/testing-pyramid_rus.png --------------------------------------------------------------------------------