Справочник (памятка) команд WSL

Основные команды

Установка и управление WSL

# Установка WSL
wsl --install

# Просмотр списка доступных дистрибутивов Linux
wsl --list --online
# или
wsl -l -o

# Установка конкретного дистрибутива
wsl --install -d <DistroName>

# Просмотр установленных дистрибутивов
wsl --list
# или
wsl -l

# Просмотр всех дистрибутивов (включая WSL версию)
wsl --list --verbose
# или
wsl -l -v

Управление дистрибутивами

# Запуск конкретного дистрибутива
wsl -d <DistroName>

# Установка дистрибутива по умолчанию
wsl --set-default <DistroName>

# Удаление дистрибутива
wsl --unregister <DistroName>

# Остановка конкретного дистрибутива
wsl --terminate <DistroName>

# Остановка всех запущенных дистрибутивов
wsl --shutdown

Версии WSL

# Установка версии WSL для конкретного дистрибутива
wsl --set-version <DistroName> <Version>

# Установка версии WSL по умолчанию
wsl --set-default-version <Version>

Импорт/Экспорт

# Экспорт дистрибутива в tar-файл
wsl --export <DistroName> <FileName.tar>

# Импорт дистрибутива из tar-файла
wsl --import <DistroName> <InstallLocation> <FileName.tar>

Сетевые команды

# Просмотр IP-адреса WSL
wsl hostname -I

# Запуск сетевой диагностики
wsl --status

Полезные команды внутри WSL

# Доступ к Windows-директориям
cd /mnt/c/

# Запуск Windows-программ
cmd.exe /c "команда"
explorer.exe .

# Проверка версии дистрибутива
cat /etc/os-release

# Обновление пакетов (Ubuntu/Debian)
sudo apt update && sudo apt upgrade

Настройка и конфигурация

# Настройка параметров памяти (.wslconfig в Windows %UserProfile%)
[wsl2]
memory=4GB
processors=4

# Монтирование дисков
wsl --mount <DiskPath>

Советы

  • Используйте wsl --help для просмотра всех доступных команд
  • В Windows 11 можно запускать Linux GUI приложения напрямую
  • WSL интегрируется с Visual Studio Code через расширение «Remote — WSL»
  • Файловая система Windows доступна через /mnt/c/ (где c — буква диска)

Устранение неполадок

# Перезапуск службы WSL
wsl --shutdown
# затем
wsl

# Проверка статуса WSL
wsl --status

# Обновление WSL
wsl --update

Чтобы установить новый дистрибутив с другим именем, убедитесь что:

  • Выбранное имя еще не используется
  • Имя не содержит специальных символов
  • Используйте простые английские буквы и цифры

Например, если вы пытаетесь установить Ubuntu, и имя «Ubuntu» уже занято, вы можете использовать:

wsl --install -d Ubuntu --name Ubuntu2
# или
wsl --install -d Ubuntu --name MyUbuntu

WordPress разработка: локал-стейдж-прод

Подход с тремя окружениями (локал-стейдж-прод) является фундаментальным в профессиональной WordPress-разработке и помогает обеспечить качество, стабильность и безопасность веб-сайтов.

Разработчики WordPress обычно используют несколько окружений для обеспечения качества, тестирования и бесперебойной работы. Вот как это обычно организуется:

Стандартная модель с тремя окружениями

Стандартная модель включает три основных окружения:

1. Локальное окружение (Local)

  • Назначение: Разработка и первичное тестирование
  • Где располагается: На компьютере разработчика
  • Особенности:
    • Используется для быстрой разработки новых функций
    • Можно экспериментировать без рисков
    • Не требует доступа к интернету
    • Обычно использует инструменты типа LocalWP, XAMPP, MAMP, Docker

2. Тестовое окружение (Staging)

  • Назначение: Проверка функционала в условиях, близких к боевым
  • Где располагается: На хостинге, часто на отдельном поддомене (например, stage.site.com)
  • Особенности:
    • Должно максимально соответствовать производственному окружению
    • Используется для тестирования обновлений и новых функций
    • Часто защищено паролем от публичного доступа
    • Может иметь копию реальных данных (с анонимизацией персональных данных)

3. Производственное окружение (Production)

  • Назначение: Обслуживание реальных пользователей
  • Где располагается: На боевом хостинге
  • Особенности:
    • Оптимизировано для производительности и безопасности
    • Все изменения тщательно проверяются перед внедрением
    • Регулярное резервное копирование данных
    • Мониторинг работоспособности и безопасности

Рабочий процесс и инструменты

Системы контроля версий

  • Git: Почти все профессиональные разработчики используют Git для отслеживания изменений
  • Репозитории: GitHub, GitLab, Bitbucket для хранения кода
  • Ветвление: Обычно используют модель с ветками для функций (feature branches), которые затем объединяются в основную ветку

Автоматизация развертывания

  • CI/CD: Непрерывная интеграция и развертывание с использованием GitHub Actions, GitLab CI, Bitbucket Pipelines
  • Инструменты развертывания: Capistrano, DeployBot, Buddy
  • WordPress-специфичные: WP-CLI для управления сайтом через командную строку

Управление базами данных

  • Миграция данных: Инструменты типа WP Migrate DB Pro для синхронизации баз данных между окружениями
  • Версионирование базы данных: Некоторые разработчики используют инструменты типа WP-CFM для версионирования конфигурации

Дополнительные практики

  • Документация: Ведение документации по проекту, включая требования, архитектуру, API
  • Проверка кода: Использование линтеров и других инструментов для обеспечения качества кода
  • Мониторинг: Установка систем мониторинга для отслеживания производительности и проблем

Продвинутые подходы

Docker-контейнеризация

Многие команды переходят на использование Docker для создания идентичных окружений:

  • Гарантирует одинаковое окружение для всех разработчиков
  • Упрощает настройку локальных сред
  • Делает развертывание более предсказуемым

Подход Infrastructure as Code (IaC)

  • Использование инструментов типа Terraform или Ansible для определения инфраструктуры как кода
  • Автоматизация создания и настройки серверов

Многосайтовое окружение

В больших компаниях иногда добавляют дополнительные окружения:

  • Development (разработка): Для интеграции работы разных разработчиков
  • QA: Для тестирования качества
  • UAT (User Acceptance Testing): Для тестирования клиентом

Инструменты для локальной разработки WordPress

Самые популярные инструменты для создания локальной среды:

  • LocalWP (бывший Local by Flywheel): Простой интерфейс, популярен среди новичков
  • DevKinsta: От компании Kinsta, специально для их хостинга
  • XAMPP/MAMP/WAMP: Классические стеки для разных ОС
  • Docker + docker-compose: Более гибкое решение, часто с конфигурацией типа WordPress + MySQL + phpMyAdmin
  • Varying Vagrant Vagrants (VVV): Среда на основе Vagrant, популярная среди контрибьюторов WordPress

PostgreSQL: Шпаргалка для работы с базой данных

Эта шпаргалка охватывает основные операции для работы с PostgreSQL.

Если у вас возникают ошибки типа «permission denied», возможно, вам нужно подключиться с правами суперпользователя или получить необходимые разрешения от администратора базы данных.

Подключение к PostgreSQL

Через терминал (psql)

-- Подключение к конкретной базе данных
psql -h hostname -p port -U username -d database_name
-- Пример: 
psql -h localhost -p 5432 -U postgres -d mydb

-- Подключение без указания базы (к пользовательской базе)
psql -U username

Строка подключения для приложений

postgresql://username:password@hostname:port/database_name

Основные команды в psql

Как посмотреть список всех баз данных?

\l или \list

Как подключиться к базе данных?

\c database_name или \connect database_name

Как посмотреть список всех таблиц в текущей базе?

\dt

Список всех таблиц с подробностями

\dt+

Список всех схем

\dn

Описание структуры таблицы

\d table_name

Полное описание структуры таблицы (с типами и ограничениями)

\d+ table_name

Как посмотреть список пользователей?

\du

Получить помощь по командам

-- Помощь по командам psql
\?

-- Помощь по SQL командам
\h

Как выйти из psql?

\q

Основные SQL-запросы

Создание новой базы данных

CREATE DATABASE database_name;

Удаление базы данных

DROP DATABASE database_name;

Работа с таблицами

-- Создание таблицы
CREATE TABLE table_name (
    column1 data_type CONSTRAINTS,
    column2 data_type CONSTRAINTS,
    ...
);

-- Пример создания таблицы
CREATE TABLE users (
    id SERIAL PRIMARY KEY,        -- Автоинкрементное поле с первичным ключом
    username VARCHAR(50) UNIQUE NOT NULL,  -- Строка фиксированной длины с ограничениями
    email VARCHAR(100) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP  -- Текущая дата/время по умолчанию
);

-- Удаление таблицы
DROP TABLE table_name;

-- Изменение структуры таблицы (добавление столбца)
ALTER TABLE table_name ADD COLUMN column_name data_type;

-- Изменение структуры таблицы (удаление столбца)
ALTER TABLE table_name DROP COLUMN column_name;

-- Переименование таблицы
ALTER TABLE table_name RENAME TO new_table_name;

Работа с данными

-- Выборка всех данных из таблицы
SELECT * FROM table_name;

-- Выборка конкретных столбцов
SELECT column1, column2 FROM table_name;

-- Выборка с условием
SELECT * FROM table_name WHERE condition;

-- Сортировка результатов
SELECT * FROM table_name ORDER BY column_name [ASC|DESC];

-- Ограничение количества результатов
SELECT * FROM table_name LIMIT number [OFFSET number];

-- Вставка данных
INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);

-- Обновление данных
UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;

-- Удаление данных
DELETE FROM table_name WHERE condition;

-- Усечение таблицы (удаление всех строк, но сохранение структуры)
TRUNCATE TABLE table_name;

Работа с индексами

-- Создание индекса
CREATE INDEX index_name ON table_name (column_name);

-- Создание составного индекса
CREATE INDEX index_name ON table_name (column1, column2);

-- Удаление индекса
DROP INDEX index_name;

Резервное копирование и восстановление

# Создание резервной копии базы данных
pg_dump -h hostname -p port -U username -d database_name > backup_file.sql

# Создание сжатой резервной копии
pg_dump -h hostname -p port -U username -d database_name | gzip > backup_file.sql.gz

# Восстановление из резервной копии
psql -h hostname -p port -U username -d database_name < backup_file.sql

# Восстановление из сжатой резервной копии
gunzip -c backup_file.sql.gz | psql -h hostname -p port -U username -d database_name

Что такое Local WP?

LocalWP — это бесплатная программа для быстрой и удобной локальной разработки сайтов на WordPress. Она позволяет запустить сайт прямо на своём компьютере без необходимости настраивать сервер вручную.

Официальный сайт

Что делает LocalWP?

Создаёт локальный сервер – ваш сайт работает на компьютере, как на реальном хостинге.
Устанавливает WordPress в один клик – не нужно вручную скачивать файлы и настраивать базы данных.
Позволяет работать офлайн – сайт доступен даже без интернета.
Поддерживает несколько сайтов – можно создать несколько тестовых проектов.
Синхронизация с хостингами – можно легко перенести сайт с локального компьютера на реальный сервер.

Кому подойдёт?

  • Новичкам – не нужно разбираться в сложных настройках.
  • Разработчикам – можно тестировать сайты перед публикацией.
  • Фрилансерам – удобно показывать клиентам демо-версии сайтов.

Как пользоваться?

  1. Скачиваете и устанавливаете LocalWP.
  2. Создаёте новый сайт, вводите название и нажимаете «Создать».
  3. Программа сама развернёт сервер и установит WordPress.
  4. Всё, можно разрабатывать сайт прямо на компьютере!

Итог: LocalWP — это быстрый и удобный способ запустить WordPress на своём ПК без сложных настроек. 🚀

Основные преимущества Local WP:

  1. Простота использования — позволяет легко создавать локальные WordPress-сайты даже начинающим разработчикам
  2. Встроенный сервер — не нужно отдельно настраивать LAMP/MAMP/WAMP стеки
  3. Изоляция проектов — каждый сайт работает в своей среде, что предотвращает конфликты
  4. Гибкие настройки — позволяет выбирать разные версии PHP, MySQL и веб-сервера
  5. Live Links — возможность временно опубликовать локальный сайт для демонстрации клиентам
  6. Интеграция с сервисами — хорошая связь с хостингами (особенно WP Engine и Flywheel)

Запуск приложения Nextjs через менеджера процессов PM2

PM2 — это популярный процессный менеджер для Node.js приложений, который облегчает управление процессами в продакшн-среде. Он используется для мониторинга, управления и автоматического перезапуска Node.js приложений. PM2 предоставляет ряд удобных функций, которые делают развертывание и обслуживание серверных приложений более удобными и эффективными.

Зачем использовать PM2 для запуска приложений?

  1. Автоматический перезапуск: PM2 автоматически перезапускает ваше приложение в случае его сбоя или после внесения изменений в код. Это особенно полезно для продакшн-серверов, где важно минимизировать время простоя.
  2. Мониторинг процессов: PM2 предоставляет удобные инструменты для мониторинга приложений, такие как просмотр логов, статистики и состояния процессов. С помощью команды pm2 status вы можете быстро узнать, какие приложения запущены, их текущий статус, использование ресурсов и другую информацию.
  3. Управление несколькими процессами: PM2 позволяет запускать несколько экземпляров одного приложения, что идеально подходит для многозадачности и увеличения производительности, особенно на многоядерных серверах. Это важно для приложений, таких как Next.js, которые могут обрабатывать большое количество одновременных запросов.
  4. Простота конфигурации и использования: Запуск приложений через PM2 очень прост: всего несколько команд для запуска, мониторинга и перезапуска. PM2 также позволяет создавать конфигурационные файлы, которые помогают управлять приложениями в разных средах.
  5. Логирование: PM2 автоматически собирает логи ошибок и стандартного вывода, которые можно просматривать в реальном времени. Это помогает быстро диагностировать и устранять ошибки, а также отслеживать работу приложения.
  6. Поддержка автозапуска: PM2 может быть настроен для автоматического старта приложений при перезагрузке системы. Это гарантирует, что ваше приложение всегда будет запущено, даже если сервер был перезагружен.

Когда стоит использовать PM2?

PM2 полезен для тех случаев, когда ваше Node.js приложение:

  • Запускается в продакшн-среде, и требуется высокая доступность и стабильность.
  • Нужно обеспечить многозадачность или балансировку нагрузки между несколькими процессами.
  • Важна автоматизация процессов, таких как перезапуск приложения при сбоях.
  • Требуется легкий способ мониторинга и логирования приложения.

Преимущества использования PM2 для Next.js

Next.js — это фреймворк, который часто используется для создания серверных приложений и сайтов с серверным рендерингом (SSR). Использование PM2 для запуска приложения Next.js в продакшн-среде помогает решить следующие задачи:

  • Обеспечивает устойчивость приложения (автоматический перезапуск в случае сбоев).
  • Поддерживает многопроцессность для лучшего использования серверных ресурсов.
  • Упрощает процесс развертывания, так как PM2 автоматически обрабатывает перезапуск после изменений в коде.
  • Предоставляет удобные средства мониторинга и логирования, что важно для эффективного обслуживания приложения.

Таким образом, PM2 — это мощный инструмент для продвинутых пользователей и разработчиков, который помогает надежно запускать, управлять и мониторить Next.js приложения в продакшн-среде.

Как развернуть Next.js приложение с использованием PM2 для продакшн-среды?

Сначала нужно собрать оптимизированную версию вашего приложения:

Шаг 1: Сборка приложения Next.js для продакшна

Это создаст оптимизированную версию вашего приложения в папке .next

cd /var/www/my-site
npm run build

Шаг 2: Установите PM2

npm install -g pm2

Шаг 3: Создайте файл конфигурации для PM2

Создайте файл ecosystem.config.js в корне вашего проекта:

module.exports = {
  apps: [
    {
      name: "my-app",
      script: "npm",
      args: "start",
      cwd: "/var/www/my-site",  // Путь к вашему проекту
      env: {
        NODE_ENV: "production",
        PORT: 3000
      },
      instances: 1,
      autorestart: true,
      watch: false,
      max_memory_restart: "1G",
      log_date_format: "YYYY-MM-DD HH:mm:ss Z"
    }
  ]
};

Шаг 4: Запустите приложение с помощью PM2

pm2 start ecosystem.config.js

Шаг 5: Настройте автозапуск PM2 при старте системы

pm2 startup systemd

Шаг 6: Сохраните текущую конфигурацию PM2

pm2 save

Мониторинг работы

Вы можете проверять состояние приложения с помощью pm2 status и просматривать логи с помощью pm2 logs.

Проверка памяти: Используйте pm2 monit для мониторинга использования памяти и CPU.

Обновление приложения

Для обновления приложения на проде:

cd /var/www/my-site
git pull # или другой способ обновления кода
npm install
npm run build
pm2 restart lic-app

Как удалить все коммиты локально и затем запушить только один новый коммит?

Шаг 1: Удаление всей истории коммитов локально

Перейди в свой репозиторий:

cd /путь/к/вашему/репозиторию

Затем сбросьте всю историю, но с сохранением файлов:

git checkout --orphan new-branch

Теперь мы находимся в новой ветке без истории коммитов, но файлы остались.

Шаг 2: Удаление всех файлов из индекса

git reset --hard

Это уберёт все файлы из индекса, но не удалит их с диска.

git add .
git commit -m "Первый (и единственный) коммит"

Шаг 3: Перезапись истории в удалённом репозитории

git branch -M main  # если ветка должна быть main
git push --force origin main

Внимание! --force полностью перезапишет историю в GitHub-репозитории. Убедись, что вам не нужна старая история.

SQL. Как посчитать количество строк с нулевым значением (NULL)?

В SQL для подсчёта количества NULL значений в колонке можно использовать функцию COUNT вместе с CASE WHEN или SUM.

Вот несколько способов:

1. Использование COUNT с CASE WHEN

SELECT COUNT(*) - COUNT(column_name) AS null_count
FROM table_name;
  • COUNT(*) считает все строки.
  • COUNT(column_name) считает только не-NULL значения.
  • Разница между ними даёт количество NULL значений.

2. Использование SUM

SELECT SUM(CASE WHEN column_name IS NULL THEN 1 ELSE 0 END) AS null_count
FROM table_name;
  • CASE WHEN column_name IS NULL THEN 1 ELSE 0 END даёт 1 для NULL и 0 для остальных.
  • SUM суммирует единицы, что даёт общее количество NULL значений.

3. Альтернативный вариант с COUNT(CASE WHEN)

SELECT COUNT(CASE WHEN column_name IS NULL THEN 1 END) AS null_count
FROM table_name;
  • COUNT считает только строки, где CASE WHEN возвращает 1, то есть только NULL значения.

Скрипт для выключения Mac по завершению фильма в QuickTime Player и VLC

Как это работает с QuickTime Player?

Работа с QuickTime Player реализована через AppleScript, аналогично VLC, но есть некоторые особенности:

  1. Статус воспроизведения: Проверка осуществляется через свойство playing первого документа.
  2. Текущий файл: Получается имя документа, который сейчас открыт в плеере.
  3. Оставшееся время: Вычисляется как разница между общей продолжительностью документа и текущей позицией воспроизведения.

Главное отличие в работе с QuickTime — необходимость проверять наличие открытого документа, поскольку QuickTime может быть запущен без открытых файлов.

#!/bin/bash

# Скрипт для выключения Mac по завершению воспроизведения в VLC или QuickTime Player
# Принцип работы: скрипт периодически проверяет, активно ли воспроизведение в выбранном плеере
# Когда воспроизведение останавливается, компьютер выключается после настраиваемой задержки

# Настраиваемые параметры
SHUTDOWN_DELAY=5  # Задержка выключения в минутах после завершения воспроизведения
CHECK_INTERVAL=5  # Интервал проверки состояния плеера в секундах
PLAYER=""         # Будет определено автоматически или выбрано пользователем

# Функция для проверки, запущен ли плеер
is_player_running() {
    local player=$1
    pgrep -x "$player" >/dev/null
    return $?
}

# Функция для определения, какой медиаплеер используется
detect_player() {
    if is_player_running "VLC"; then
        echo "VLC"
        return 0
    elif is_player_running "QuickTime Player"; then
        echo "QuickTime Player"
        return 0
    else
        return 1
    fi
}

# Функция для проверки, воспроизводится ли что-то в VLC
is_vlc_playing() {
    local playing=$(osascript -e 'tell application "VLC" to get playing')
    if [ "$playing" = "true" ]; then
        return 0  # Воспроизведение активно
    else
        return 1  # Воспроизведение не активно
    fi
}

# Функция для получения оставшегося времени фильма в VLC
get_vlc_remaining_time() {
    # Получаем оставшееся время в секундах
    local remaining=$(osascript -e 'tell application "VLC" to get ((duration - time) as integer)')
    echo $remaining
}

# Функция для получения текущего файла в VLC
get_vlc_current_file() {
    local current_file=$(osascript -e 'tell application "VLC" to get name of current item')
    echo "$current_file"
}

# Функция для проверки, воспроизводится ли что-то в QuickTime
is_quicktime_playing() {
    local playing=$(osascript -e '
    tell application "QuickTime Player"
        if not (exists document 1) then
            return "false"
        end if
        return (playing of document 1)
    end tell
    ')
    if [ "$playing" = "true" ]; then
        return 0  # Воспроизведение активно
    else
        return 1  # Воспроизведение не активно
    fi
}

# Функция для получения текущего файла в QuickTime
get_quicktime_current_file() {
    local current_file=$(osascript -e '
    tell application "QuickTime Player"
        if not (exists document 1) then
            return "Неизвестный файл"
        end if
        return name of document 1
    end tell
    ')
    echo "$current_file"
}

# Функция для получения оставшегося времени в QuickTime (приблизительно)
get_quicktime_remaining_time() {
    local duration=$(osascript -e '
    tell application "QuickTime Player"
        if not (exists document 1) then
            return 0
        end if
        return duration of document 1
    end tell
    ')
    
    local current_time=$(osascript -e '
    tell application "QuickTime Player"
        if not (exists document 1) then
            return 0
        end if
        return current time of document 1
    end tell
    ')
    
    local remaining=$((duration - current_time))
    echo $remaining
}

# Функция для форматирования времени
format_time() {
    local seconds=$1
    local minutes=$((seconds / 60))
    local remaining_seconds=$((seconds % 60))
    echo "$minutes минут и $remaining_seconds секунд"
}

# Функция для отображения справки
show_help() {
    echo "Использование: $0 [опции]"
    echo "Опции:"
    echo "  -p, --player PLAYER    Указать плеер (vlc или quicktime)"
    echo "  -d, --delay MINUTES    Задать задержку выключения в минутах (по умолчанию: 5)"
    echo "  -h, --help             Показать эту справку"
    echo ""
    echo "Пример: $0 --player vlc --delay 10"
    exit 0
}

# Обработка аргументов командной строки
while [[ $# -gt 0 ]]; do
    key="$1"
    case $key in
        -p|--player)
            case "$2" in
                vlc|VLC)
                    PLAYER="VLC"
                    ;;
                quicktime|QuickTime|"QuickTime Player")
                    PLAYER="QuickTime Player"
                    ;;
                *)
                    echo "Ошибка: неизвестный плеер: $2"
                    echo "Поддерживаемые плееры: vlc, quicktime"
                    exit 1
                    ;;
            esac
            shift 2
            ;;
        -d|--delay)
            SHUTDOWN_DELAY="$2"
            shift 2
            ;;
        -h|--help)
            show_help
            ;;
        *)
            echo "Неизвестный параметр: $1"
            show_help
            ;;
    esac
done

# Если плеер не указан, пытаемся определить его автоматически
if [ -z "$PLAYER" ]; then
    PLAYER=$(detect_player)
    if [ $? -ne 0 ]; then
        echo "Ошибка: не найден запущенный медиаплеер (VLC или QuickTime Player)."
        echo "Запустите медиаплеер и начните воспроизведение, затем выполните скрипт снова."
        echo "Или укажите плеер вручную с помощью параметра --player."
        exit 1
    fi
fi

echo "Выбран плеер: $PLAYER"

# Проверяем, запущен ли выбранный плеер
if ! is_player_running "$PLAYER"; then
    echo "$PLAYER не запущен. Запустите $PLAYER и начните воспроизведение, затем выполните скрипт снова."
    exit 1
fi

# Проверяем, воспроизводится ли что-то в выбранном плеере
if [ "$PLAYER" = "VLC" ]; then
    if ! is_vlc_playing; then
        echo "В VLC ничего не воспроизводится. Начните воспроизведение фильма, затем выполните скрипт снова."
        exit 1
    fi
    
    # Получаем информацию о воспроизведении
    current_file=$(get_vlc_current_file)
    remaining_seconds=$(get_vlc_remaining_time)
elif [ "$PLAYER" = "QuickTime Player" ]; then
    if ! is_quicktime_playing; then
        echo "В QuickTime Player ничего не воспроизводится. Начните воспроизведение фильма, затем выполните скрипт снова."
        exit 1
    fi
    
    # Получаем информацию о воспроизведении
    current_file=$(get_quicktime_current_file)
    remaining_seconds=$(get_quicktime_remaining_time)
fi

# Выводим информацию
echo "Обнаружен воспроизводимый файл: $current_file"
echo "Оставшееся время: $(format_time $remaining_seconds)"
echo "Компьютер будет выключен после завершения воспроизведения."
echo "После завершения воспроизведения компьютер выключится через $SHUTDOWN_DELAY минут."
echo "Для отмены этого скрипта нажмите Ctrl+C."

# Цикл ожидания завершения воспроизведения
last_update_time=0
while true; do
    # Проверяем, запущен ли плеер
    if ! is_player_running "$PLAYER"; then
        echo "$PLAYER был закрыт. Начинаем процедуру выключения..."
        break
    fi
    
    # Проверяем состояние воспроизведения в зависимости от плеера
    if [ "$PLAYER" = "VLC" ]; then
        if ! is_vlc_playing; then
            echo "Воспроизведение в VLC завершено. Начинаем процедуру выключения..."
            break
        fi
        
        # Обновляем информацию каждые CHECK_INTERVAL секунд
        current_time=$(date +%s)
        if [ $((current_time - last_update_time)) -ge $CHECK_INTERVAL ]; then
            remaining_seconds=$(get_vlc_remaining_time)
            echo "Оставшееся время: $(format_time $remaining_seconds)"
            last_update_time=$current_time
        fi
    elif [ "$PLAYER" = "QuickTime Player" ]; then
        if ! is_quicktime_playing; then
            echo "Воспроизведение в QuickTime Player завершено. Начинаем процедуру выключения..."
            break
        fi
        
        # Обновляем информацию каждые CHECK_INTERVAL секунд
        current_time=$(date +%s)
        if [ $((current_time - last_update_time)) -ge $CHECK_INTERVAL ]; then
            remaining_seconds=$(get_quicktime_remaining_time)
            echo "Оставшееся время: $(format_time $remaining_seconds)"
            last_update_time=$current_time
        fi
    fi
    
    # Пауза между проверками для снижения нагрузки
    sleep 1
done

# Показываем уведомление о предстоящем выключении
osascript -e "display notification \"Компьютер будет выключен через $SHUTDOWN_DELAY минут\" with title \"Автоматическое выключение\""

# Запускаем таймер выключения
sudo shutdown -h +$SHUTDOWN_DELAY

echo "Компьютер будет выключен через $SHUTDOWN_DELAY минут."
echo "Чтобы отменить выключение, выполните команду: sudo shutdown -c"

Как использовать скрипт

  1. Базовое использование:
./media_shutdown.sh

Скрипт автоматически определит, какой плеер запущен.

  1. Указание плеера вручную:
./media_shutdown.sh --player vlc
./media_shutdown.sh --player quicktime
  1. Изменение задержки выключения:
./media_shutdown.sh --delay 10

Технические особенности

  1. Низкая нагрузка на систему: Скрипт проверяет состояние воспроизведения каждую секунду, но обновляет информацию о времени только каждые 5 секунд, что снижает нагрузку на систему.
  2. Универсальные функции: Код организован по принципу модульности — для каждого плеера есть отдельные функции, что упрощает добавление поддержки других плееров в будущем.
  3. Обработка ошибок: Скрипт корректно обрабатывает ситуации, когда плеер закрывается или фильм останавливается, и в любом случае запускает процедуру выключения.

Скрипт для выключения Mac по завершению фильма в VLC

Как работает скрипт

Скрипт использует несколько важных механизмов:

  1. AppleScript для связи с VLC: macOS позволяет использовать AppleScript для взаимодействия с приложениями. Через эти команды скрипт может узнать, играет ли сейчас фильм и сколько времени осталось до его окончания.
  2. Проверка состояния воспроизведения: Скрипт постоянно (каждую секунду) проверяет, продолжает ли VLC воспроизведение. Как только воспроизведение останавливается, запускается процедура выключения.
  3. Отложенное выключение: После завершения фильма скрипт не выключает компьютер немедленно, а устанавливает таймер на 5 минут. Это даёт вам возможность отменить выключение, если вы решите посмотреть ещё что-то.
  4. Информирование пользователя: Скрипт показывает системное уведомление о предстоящем выключении и выводит в терминал информацию о том, как отменить выключение.

Как использовать скрипт

  1. Сохраните код в файл, например vlc_shutdown.sh
  2. Сделайте файл исполняемым: chmod +x vlc_shutdown.sh
  3. Запустите VLC и начните воспроизведение фильма
  4. Запустите скрипт: ./vlc_shutdown.sh

Какие проблемы решает этот подход

Этот скрипт имеет несколько преимуществ перед простым таймером выключения:

  • Адаптивность: Скрипт автоматически определяет, сколько времени осталось до конца фильма, вместо того чтобы полагаться на фиксированное время.
  • Интеллектуальное поведение: Если вы остановите фильм или закроете VLC, скрипт все равно сработает и выключит компьютер.
  • Безопасность: Задержка в 5 минут перед выключением даёт вам время отменить выключение, если вы передумали.
#!/bin/bash

# Скрипт для выключения Mac по завершению воспроизведения в VLC
# Принцип работы: скрипт периодически проверяет, активно ли воспроизведение в VLC
# Когда воспроизведение останавливается, компьютер выключается после небольшой задержки

# Функция для проверки, запущен ли VLC
is_vlc_running() {
    pgrep -x VLC >/dev/null
    return $?
}

# Функция для проверки, воспроизводится ли что-то в VLC
is_vlc_playing() {
    # Используем AppleScript для проверки статуса воспроизведения
    playing=$(osascript -e 'tell application "VLC" to get playing')
    if [ "$playing" = "true" ]; then
        return 0  # Воспроизведение активно
    else
        return 1  # Воспроизведение не активно
    fi
}

# Функция для получения оставшегося времени фильма
get_remaining_time() {
    # Получаем оставшееся время в секундах
    remaining=$(osascript -e 'tell application "VLC" to get ((duration - time) as integer)')
    echo $remaining
}

# Проверяем, запущен ли VLC
if ! is_vlc_running; then
    echo "VLC не запущен. Запустите VLC и начните воспроизведение фильма, затем выполните скрипт снова."
    exit 1
fi

# Проверяем, воспроизводится ли что-то
if ! is_vlc_playing; then
    echo "В VLC ничего не воспроизводится. Начните воспроизведение фильма, затем выполните скрипт снова."
    exit 1
fi

# Получаем оставшееся время фильма и название файла
remaining_seconds=$(get_remaining_time)
current_file=$(osascript -e 'tell application "VLC" to get name of current item')

# Выводим информацию
echo "Обнаружен воспроизводимый файл: $current_file"
echo "Оставшееся время: $(($remaining_seconds / 60)) минут и $(($remaining_seconds % 60)) секунд"
echo "Компьютер будет выключен после завершения воспроизведения."

# Добавляем небольшую задержку перед выключением (5 минут)
shutdown_delay=5

echo "После завершения воспроизведения компьютер выключится через $shutdown_delay минут."
echo "Для отмены этого скрипта нажмите Ctrl+C."

# Цикл ожидания завершения воспроизведения
while true; do
    if ! is_vlc_running; then
        echo "VLC был закрыт. Начинаем процедуру выключения..."
        break
    fi
    
    if ! is_vlc_playing; then
        echo "Воспроизведение завершено. Начинаем процедуру выключения..."
        break
    fi
    
    # Обновляем оставшееся время каждые 30 секунд
    if (( $(date +%s) % 30 == 0 )); then
        remaining_seconds=$(get_remaining_time)
        echo "Оставшееся время: $(($remaining_seconds / 60)) минут и $(($remaining_seconds % 60)) секунд"
    fi
    
    # Пауза в 1 секунду между проверками
    sleep 1
done

# Показываем уведомление о предстоящем выключении
osascript -e "display notification \"Компьютер будет выключен через $shutdown_delay минут\" with title \"Автоматическое выключение\""

# Запускаем таймер выключения
sudo shutdown -h +$shutdown_delay

echo "Компьютер будет выключен через $shutdown_delay минут."
echo "Чтобы отменить выключение, выполните команду: sudo shutdown -c"

Cкрипт для выключения Mac в заданное время

Этот скрипт позволяет указать время выключения компьютера в формате ЧЧ:MM. Вот как им пользоваться:

  1. Сохраните скрипт в файл, например shutdown_timer.sh
  2. Сделайте его исполняемым командой: chmod +x shutdown_timer.sh
  3. Запустите скрипт с указанием времени: ./shutdown_timer.sh 23:30

Как работает скрипт:

  • Принимает время в формате ЧЧ:MM
  • Проверяет, что формат времени корректный
  • Вычисляет, сколько минут осталось до указанного времени
  • Использует стандартную команду shutdown для планирования выключения
  • Если указанное время уже прошло сегодня, планирует выключение на завтра

Для отмены запланированного выключения используйте команду sudo shutdown -c.

#!/bin/bash

# Функция для проверки, что время введено в правильном формате (HH:MM)
validate_time() {
    if [[ ! $1 =~ ^([0-1][0-9]|2[0-3]):[0-5][0-9]$ ]]; then
        echo "Ошибка: введите время в формате ЧЧ:МM (например, 23:30)"
        exit 1
    fi
}

# Проверяем, указано ли время в аргументах
if [ $# -eq 0 ]; then
    echo "Пожалуйста, укажите время выключения в формате ЧЧ:MM"
    echo "Пример: $0 23:30"
    exit 1
fi

# Проверяем формат времени
validate_time "$1"

# Текущее время
current_time=$(date +%s)

# Преобразуем введенное время в секунды с начала дня
shutdown_hour=$(echo $1 | cut -d':' -f1)
shutdown_min=$(echo $1 | cut -d':' -f2)

# Вычисляем время выключения в секундах
target_time=$(date -j -f "%H:%M" "$shutdown_hour:$shutdown_min" +%s 2>/dev/null)

# Проверка на случай ошибки конвертации времени
if [ $? -ne 0 ]; then
    echo "Ошибка при обработке введенного времени."
    exit 1
fi

# Если целевое время уже прошло сегодня, переносим на завтра
if [ $target_time -le $current_time ]; then
    target_time=$((target_time + 86400)) # Добавляем 24 часа (в секундах)
fi

# Вычисляем разницу в секундах
seconds_diff=$((target_time - current_time))

# Выводим информацию
echo "Компьютер будет выключен в $1"
echo "До выключения осталось: $(($seconds_diff / 60)) минут"

# Устанавливаем команду выключения
sudo shutdown -h +$(($seconds_diff / 60))

# Выводим сообщение о том, как отменить выключение
echo "Чтобы отменить запланированное выключение, выполните команду:"
echo "sudo killall shutdown или sudo shutdown -c"

Как закрыть все страницы сайта и сделать их доступными только после авторизации?

Закрыть сайт вручную можно нехитрый через код.

  1. Откройте файл functions.php вашей темы.
  2. Добавьте следующий код:
function poet_restrict_access() {
    if ( ! is_user_logged_in() && ! is_page('login') ) {
        wp_redirect( wp_login_url() );
        exit;
    }
}
add_action( 'template_redirect', 'poet_restrict_access' );

Всё! Теперь сайт будет перенаправлять на страницу входа, если пользователь не авторизован.

Так как админка WordPress доступна только авторизованным пользователям, то «сюрпризов» не будет. Админка будет доступна 🙂

Разрешение доступа к определённым страницам (например, исключим страницу входа, регистрации и контактов)

function poet_restrict_access() {
    // Список страниц, которые остаются открытыми
    $allowed_pages = array( 'login', 'register', 'contact' ); 

    if ( ! is_user_logged_in() && ! is_page( $allowed_pages ) ) {
        wp_redirect( wp_login_url() ); // Перенаправление на страницу входа
        exit;
    }
}
add_action( 'template_redirect', 'poet_restrict_access' );

Если ваш сайт использует AJAX (например, в теме или плагинах), нужно разрешить доступ к AJAX-запросам, иначе они перестанут работать. Добавьте это в функцию:

function poet_restrict_access() {
    // Разрешить доступ к AJAX и cron-запросам
    if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
        return;
    }

    if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
        return;
    }

    // Список страниц, которые остаются открытыми
    $allowed_pages = array( 'login', 'register', 'contact' );

    if ( ! is_user_logged_in() && ! is_page( $allowed_pages ) ) {
        wp_redirect( wp_login_url() ); // Перенаправление на страницу входа
        exit;
    }
}
add_action( 'template_redirect', 'poet_restrict_access' );

Настройка редиректа после входа

function custom_login_redirect( $redirect_to, $request, $user ) {
    // Убедимся, что пользователь авторизован
    if ( isset( $user->roles ) && is_array( $user->roles ) ) {
        return home_url(); // Перенаправление на главную страницу
    }

    return $redirect_to;
}
add_filter( 'login_redirect', 'custom_login_redirect', 10, 3 );

Как закрыть и админку ?

Если вы хотите ограничить доступ к админке для определённых ролей или полностью исключить его, добавьте это:

function restrict_admin_access() {
    if ( ! current_user_can( 'manage_options' ) && ! wp_doing_ajax() ) {
        wp_redirect( home_url() );
        exit;
    }
}
add_action( 'admin_init', 'restrict_admin_access' );

Как добавить класс к корневому элементу html с помощью Javascript?

Добавление класса ‘js’ к корневому HTML-элементу обычно используется для того чтобы убедиться в поддержки JavaScript (чтобы можно было менять стили и поведение элементов в зависимости от поддержки JS)

Чистый JavaScript (ES6+):

document.documentElement.classList.add('js');

Vanilla JavaScript (более старый синтаксис):

document.documentElement.className += ' js';

С проверкой поддержки classList:

if (document.documentElement.classList) {
    document.documentElement.classList.add('js');
}

Универсальный вариант, который:

  • Проверяет поддержку classList
  • Если поддерживает — использует classList.add()
  • Если не поддерживает — использует старый метод конкатенации className
  • Добавляет пробел перед ‘js’, только если className уже не пустой
if ('classList' in document.documentElement) {
    document.documentElement.classList.add('js');
} else {
    document.documentElement.className += (document.documentElement.className ? ' ' : '') + 'js';
}

Эти варианты полностью заменяют jQuery-версию и добавляют класс ‘js’ к корневому HTML-элементу, что обычно используется для индикации поддержки JavaScript в браузере.

Альтернативный вариант, который дополнительно удаляет класс ‘no-js’, если он был установлен заранее.

document.documentElement.className = 
    document.documentElement.className.replace(/\bno-js\b/, '') + ' js';

Основные преимущества:

  • Не требуется подключение jQuery
  • Нативный JavaScript
  • Меньше кода
  • Лучшая производительность