rubric/modules/linuxmodules/linux_scripts.go
2026-04-06 11:02:36 +03:00

318 lines
9.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package linuxmodules
import (
"fmt"
"rubric/utils"
)
var ScriptsModule = Module{
Key: "scripts",
Aliases: []string{"sc", "scripting", "скрипты"},
Title: "Bash-скрипты",
Description: "Темы 2732: скрипты, условия, циклы, функции, массивы",
Run: showScripts,
}
func showScripts() {
utils.Header("Linux — Bash-скрипты")
// ─── 27. Bash скрипты №1 ──────────────────────────────────────
utils.Section("27. Основы скриптов. Условия")
utils.Println(utils.ColorBold + "Структура скрипта:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Shebang — первая строка указывает интерпретатор
# Комментарий
echo "Привет, мир!"
# Запуск скрипта:
chmod +x script.sh # сделать исполняемым
./script.sh # запустить
bash script.sh # запустить через bash (без chmod)`)
utils.Println(utils.ColorBold + "Переменные в скриптах:" + utils.ColorReset)
utils.Code(`#!/bin/bash
name="Alice"
count=5
echo "Имя: $name"
echo "Счёт: $count"
# Ввод от пользователя:
read -p "Введите имя: " username
echo "Привет, $username!"
# Ввод без отображения (пароль):
read -s -p "Пароль: " password`)
utils.Println(utils.ColorBold + "Условный оператор if:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Базовая форма:
if [ условие ]; then
команды
elif [ другое_условие ]; then
команды
else
команды
fi
# Примеры условий:
# Сравнение строк:
if [ "$name" = "Alice" ]; then echo "Привет, Alice"; fi
if [ "$name" != "Bob" ]; then echo "Не Боб"; fi
if [ -z "$name" ]; then echo "Пустая строка"; fi # -z = пусто
if [ -n "$name" ]; then echo "Не пустая"; fi # -n = не пусто
# Сравнение чисел:
if [ "$count" -eq 5 ]; then ... # equal
if [ "$count" -ne 5 ]; then ... # not equal
if [ "$count" -gt 3 ]; then ... # greater than
if [ "$count" -lt 10 ]; then ... # less than
if [ "$count" -ge 5 ]; then ... # greater or equal
if [ "$count" -le 5 ]; then ... # less or equal
# Файлы и директории:
if [ -f /etc/passwd ]; then echo "файл существует"; fi
if [ -d /tmp ]; then echo "директория существует"; fi
if [ -e /dev/sda ]; then echo "путь существует"; fi
if [ -r file ]; then echo "доступен для чтения"; fi
if [ -w file ]; then echo "доступен для записи"; fi
if [ -x script.sh ]; then echo "исполняемый"; fi
if [ -s file ]; then echo "файл не пустой"; fi
if [ file1 -nt file2 ]; then echo "file1 новее"; fi
# Логика:
if [ cond1 ] && [ cond2 ]; then ... # И
if [ cond1 ] || [ cond2 ]; then ... # ИЛИ
if ! [ cond ]; then ... # НЕ
# [[ ]] — расширенные условия bash:
if [[ "$str" == *"подстрока"* ]]; then ... # glob
if [[ "$str" =~ ^[0-9]+$ ]]; then ... # regex`)
// ─── 2829. Bash скрипты №23 ─────────────────────────────────
utils.Section("2829. Циклы")
utils.Println(utils.ColorBold + "Цикл for:" + utils.ColorReset)
utils.Code(`# По списку:
for item in один два три; do
echo "$item"
done
# По числовому диапазону:
for i in {1..5}; do
echo "Шаг $i"
done
# С шагом:
for i in {0..20..5}; do echo "$i"; done # 0 5 10 15 20
# C-стиль:
for ((i=0; i<5; i++)); do
echo "$i"
done
# По файлам:
for file in /etc/*.conf; do
echo "Обрабатываю: $file"
done
# По строкам вывода команды:
for user in $(cat /etc/passwd | cut -d: -f1); do
echo "Пользователь: $user"
done`)
utils.Println(utils.ColorBold + "Цикл while:" + utils.ColorReset)
utils.Code(`# Пока условие истинно:
count=0
while [ $count -lt 5 ]; do
echo "count = $count"
((count++))
done
# Чтение файла построчно:
while IFS= read -r line; do
echo "Строка: $line"
done < /etc/hosts
# Бесконечный цикл:
while true; do
echo "Работаю..."
sleep 1
done`)
utils.Println(utils.ColorBold + "Цикл until и управление циклами:" + utils.ColorReset)
utils.Code(`# Пока условие ложно:
until [ -f /tmp/ready ]; do
echo "Жду файл..."
sleep 1
done
# break — выйти из цикла:
for i in {1..10}; do
if [ $i -eq 5 ]; then break; fi
echo $i
done
# continue — перейти к следующей итерации:
for i in {1..10}; do
if [ $((i % 2)) -eq 0 ]; then continue; fi
echo "Нечётное: $i"
done`)
// ─── 3031. Bash скрипты №45 ─────────────────────────────────
utils.Section("3031. Функции и обработка ошибок")
utils.Println(utils.ColorBold + "Функции:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Объявление функции:
greet() {
local name=$1 # local — локальная переменная
echo "Привет, $name!"
}
# Или:
function greet {
echo "Привет, $1!"
}
# Вызов:
greet "Alice"
greet "Bob"
# Возвращаемое значение:
# Функции возвращают только числа (код возврата 0-255)
is_root() {
[ "$(id -u)" -eq 0 ]
}
if is_root; then
echo "Запущен как root"
fi
# Для передачи строк — echo + подстановка команд:
get_hostname() {
echo "$(hostname)"
}
host=$(get_hostname)`)
utils.Println(utils.ColorBold + "Обработка ошибок:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Остановить при ошибке:
set -e # выйти при любой ошибке (exit on error)
set -u # ошибка при неопределённой переменной
set -o pipefail # учитывать ошибки в pipe
set -euo pipefail # всё вместе (рекомендуется)
# Проверка кода возврата:
if ! mkdir /tmp/mydir 2>/dev/null; then
echo "Ошибка создания директории" >&2
exit 1
fi
# Функция для вывода ошибок:
error() {
echo "ОШИБКА: $*" >&2
exit 1
}
[ -f "$1" ] || error "Файл $1 не найден"
# Trap — обработка сигналов и выхода:
cleanup() {
rm -f /tmp/tempfile
echo "Очищено"
}
trap cleanup EXIT # при любом выходе
trap cleanup INT TERM # при Ctrl+C или kill`)
// ─── 32. Bash скрипты №6 ──────────────────────────────────────
utils.Section("32. Массивы, строки и аргументы скрипта")
utils.Println(utils.ColorBold + "Массивы:" + utils.ColorReset)
utils.Code(`# Объявление:
fruits=("яблоко" "банан" "апельсин")
declare -a numbers=(1 2 3 4 5)
# Доступ:
echo "${fruits[0]}" # яблоко (индекс с 0)
echo "${fruits[@]}" # все элементы
echo "${#fruits[@]}" # количество элементов
echo "${fruits[@]:1:2}" # срез: с индекса 1, 2 элемента
# Добавить элемент:
fruits+=("манго")
# Перебор:
for fruit in "${fruits[@]}"; do
echo "$fruit"
done
# Перебор с индексом:
for i in "${!fruits[@]}"; do
echo "$i: ${fruits[$i]}"
done
# Ассоциативный массив (словарь):
declare -A user
user[name]="Alice"
user[age]=30
echo "${user[name]}"
echo "${!user[@]}" # ключи
echo "${user[@]}" # значения`)
utils.Println(utils.ColorBold + "Аргументы скрипта:" + utils.ColorReset)
utils.Code(`#!/bin/bash
# Позиционные параметры:
echo "Скрипт: $0"
echo "Первый аргумент: $1"
echo "Второй аргумент: $2"
echo "Все аргументы: $@"
echo "Количество аргументов: $#"
# Проверка аргументов:
if [ $# -lt 2 ]; then
echo "Использование: $0 <имя> <возраст>" >&2
exit 1
fi
# Обработка опций (getopts):
while getopts "hv:n:" opt; do
case $opt in
h) echo "Справка"; exit 0 ;;
v) verbose=true ;;
n) name="$OPTARG" ;;
?) echo "Неизвестный ключ"; exit 1 ;;
esac
done
# shift — сдвинуть аргументы:
shift $((OPTIND - 1)) # убрать опции, остались обычные аргументы`)
utils.Println(utils.ColorBold + "Полезные приёмы:" + utils.ColorReset)
utils.Code(`# Цвета в терминале:
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
echo -e "${RED}Ошибка${NC}"
echo -e "${GREEN}Успех${NC}"
# Прогресс-бар простой:
for i in {1..10}; do
echo -ne "\rПрогресс: $((i*10))%"
sleep 0.1
done; echo
# Логирование:
LOG=/var/log/myscript.log
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; }
log "Скрипт запущен"
# Ожидание с таймаутом:
timeout 30 ./long_command.sh || echo "Таймаут!"`)
fmt.Println()
utils.Note("Проверяйте скрипты на ошибки: bash -n script.sh (синтаксис) и bash -x script.sh (трассировка).")
utils.Footer()
}