Astra Linux: установить обои из консоли

Задача: необходимо установить свои обои на рабочем столе Astra Linux при помощи скрипта на bash

Решение: проблема решается буквально одной строчкой:

#!/bin/bash
fly-wmfunc FLYWM_UPDATE_VAL WallPaper "~/scripts/wallpapersden.com_atomic-heart-gaming_1920x1200.jpg"

Для автоматической установки достаточно положить этот скрипт в ~/.config/autostart

Продвинутая отправка почты из консоли

Есть множество статей как отправить почту из консоли терминала Linux. Но в основной своей массе, это всё касается уже настроенного почтового сервера. А если нужно отправить почту используя настройки SMTP с авторизацией, указанием кодировки и вложением в виде файла? Их есть у меня (с). Ниже пример:

echo "Test text" | mail -e 'set content_type=text/html' -v -S sendcharsets=utf-8,iso-8859-1 -s "Результат тестирование" -S smtp="асываo.ru:587" -S ssl-verify=ignore -S smtp-use-starttls -S smtp-auth=login -S smtp-auth-user="vlg1-Noreply@interrao.ru" -S smtp-auth-password='ываывываы' -S from=noreply@ывывсывс.ru ывсывсыв@сывасывсыв.ru </var/tmp/res.html

Этот пример вышлет письмо в кодировке UTF-8, со вложенным файлом res.html. Авторизация по логину-паролю, с шифрованием start SSL.

как отправить почту из консоли терминала Linux

Другие статьи на эту тему тут

Как скачать из консоли файл с яндекс.диска

Редко, но бывают ситуации, что под рукой только консоль терминала, а нужно скачать файл размещенный на яндек.диске (скачать с яндекс диска из консоли). Для решения такой ситуации есть утилита wldhx.yadisk-direct. Установим её:

pip3 install wldhx.yadisk-direct

После установки, закачка (скачать с яндекс диска из консоли) сводится к одной команде:

curl -L $(yadisk-direct https://disk.yandex.ru/d/JswxXZvффvJpPA) -o kop.rar
скачать с яндекс диска из консоли

Другие интересные решения для работы в консоли здесь. Ссылка на оригинальный репозитарий здесь

Update 26/08/2025: иногда установленный скрипт не находится без пути. Полезно посмотреть где оно при помощи:

whereis yadisk-direct

Квест в консоли на Python. Часть 2

Итак, продолжаем продолжаем писать квест в консоли на языке Python. Первая часть описана здесь. В ней мы реализовали автоматическую загрузку и сохранение состояния прохождения квеста. Сейчас же займемся (начнем по крайне мере) отрисовкой локации, и реакцией на нажатые кнопки. В локации предусмотрим возможность отображения картинки из ASCII. Например json стартовой локации может выглядеть примерно так:

{
  "title": "Стартовая локация",
  "description": "Стартовая локация описание",
  "ascii_art": "                    __            ================================\n         ALCATRAZ  /__\\            ||     ||<(.)>||<(.)>||     || \n       ____________|  |            ||    _||     ||     ||_    || \n       |_|_|_|_|_|_|  |            ||   (__D     ||     C__)   || \n       |_|_|_|_|_|_|__|            ||   (__D     ||     C__)   ||\n      A@\\|_|_|_|_|_|/@@Aa          ||   (__D     ||     C__)   ||\n   aaA@@@@@@@@@@@@@@@@@@@aaaA      ||   (__D     ||     C__)   ||\n  A@@@@@@@@@@@DWB@@@@@@@@@@@@A     ||     ||     ||     ||  dwb||\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  ================================",
  "available_locations": {
    "left": 1,
    "right": 2,
    "forward": 3,
    "back": 4
  }
}

Создадим класс TLocation, при инициалиизации будем передавать в него инициализированный класс player. В переменной класса data — будем хранить загруженную локацию.

class TLocation:
    data = {}
    player={}
    stdscr=curses.initscr()
    scr_size=stdscr.getmaxyx()
    def __init__(self,player):
        self.player=player;
    def load_location(self, location):
        f = open("locations/" + str(location) + ".json", mode='r', encoding='utf-8')
        self.data = json.load(f)
        f.close()

Далее нарисуем верхнее меню, где сообщаем игроку, на какие локации он может перемещаться, и что он держит в руках:

    def top_menu(self):
        loc="Идти: "
        if "left" in self.data["available_locations"]:
            loc=loc+"влево(4) "
        if "right" in self.data["available_locations"]:
            loc=loc+"вправо(6) "
        if "forward" in self.data["available_locations"]:
            loc=loc+"вперед(8) "
        if "back" in self.data["available_locations"]:
            loc=loc+"назад(2) "
        curses.start_color()
        curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
        self.stdscr.addstr(1, 1, loc,curses.color_pair(1))
        curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
        self.stdscr.addstr(1, 1, loc,curses.color_pair(1))
        # что в руках
        hands = "В руках: "
        self.stdscr.addstr(2, 1, "")
        for object in self.player.data["in_hands"]:
            hands=hands+"["+object+"]"
        if len(self.player.data["in_hands"])==0:
            hands = hands+"ничего нет"
        self.stdscr.addstr(2, 1, hands, curses.color_pair(1))

Ну и собственно основной код отрисовки локации, включающий бесконечный цикл ожидания нажатий клавиатуры. Предусматриваем переход на другую локацию, выход из игры и сохранение игры.

    def location_view(self, location):
        self.load_location(location)
        self.stdscr.clear()
        self.stdscr.border()
        self.top_menu()  # рисуем верхнее меню
        # название локации
        curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK)
        x = int((self.scr_size[1] - len(self.data["title"])) / 2)
        self.stdscr.addstr(2, x, self.data["title"],curses.color_pair(2))
        # рисуем рисунок ежели он есть
        y=3
        if "ascii_art" in self.data:
            mass_art=self.data["ascii_art"].split("\n")
            i=0
            while i<len(mass_art):
                x=int((self.scr_size[1]-len(mass_art[i]))/2)
                self.stdscr.addstr(y+i, x, mass_art[i])
                i+=1
            y = y + len(mass_art);
         # Выводим описательную часть
        curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK)
        self.stdscr.addstr(y, 1, self.data["description"],curses.color_pair(3))
        # Выводим нижнее меню
        curses.init_pair(4, curses.COLOR_RED, curses.COLOR_BLACK)
        self.stdscr.addstr(y + 1, 1, "Осмотреться вокруг [v] Применить что в руках [h]", curses.color_pair(4))
        self.stdscr.addstr(y + 2, 1, "Выйти из квеста [q] Сохранить состояние [r]", curses.color_pair(4))
        self.stdscr.refresh()
        while True:
            key=self.stdscr.getch()
            print(key)
            # реализация перехода с локации на локацию
            if key==52 and "left" in self.data["available_locations"]:
                self.player.data["location"]=self.data["available_locations"]["left"]
                self.location_view(self.player.data["location"])
            if key==54 and "right" in self.data["available_locations"]:
                self.player.data["location"]=self.data["available_locations"]["right"]
                self.location_view(self.player.data["location"])
            if key==56 and "forward" in self.data["available_locations"]:
                self.player.data["location"]=self.data["available_locations"]["forward"]
                self.location_view(self.player.data["location"])
            if key==50 and "back" in self.data["available_locations"]:
                self.player.data["location"]=self.data["available_locations"]["back"]
                self.location_view(self.player.data["location"])
            if key == 114:
                self.player.save()
                #self.message("Внимание!","Состояние прохождения завершено. \nФайл находится в папке /saves")
            if key==113:
                curses.reset_shell_mode()
                curses.endwin()
                exit(0)
        print(self.data)

В результате картинка (квест в консоли) на мониторе выглядит уже чуть симпатичнее:

 квест в консоли

Шаблон консольного скрипта на PHP

Довольно часто по работе приходится писать различного вида скрипты которые выполняются как в консоли, так и при вызове из браузера. Со временем сложился устойчивый стартовый шаблон консольного скрипта на PHP, который собственно и таскаю с сервера на сервер, когда начинаю что-то писать.

Можно конечно использовать для этого различные фреймворки, типа yii, которые предоставляют более удобный для этого функционал, но чаще всего для простых скриптов такого монстра тащить не рационально. Посему имеем то что имеем.

Структура папок следующая:

Шаблон консольного скрипта

Начнем с файла index.php:

<?php
define('WUO_ROOT', dirname(__FILE__));
// загружаем классы
spl_autoload_register(function ($class_name) {
    require_once WUO_ROOT.'/class/'.$class_name.'.php';
});

include_once WUO_ROOT.'/config.php';
include_once WUO_ROOT.'/inc/functions.php';

PutLog("скрипт стартовал!");
PutLog("ищу остатки на складе",2);
PutLog("на складе Вологда",3);
PutLog("10",4);
PutLog("на складе Бобруйск",3);
PutLog("23",4);
PutLog("завершил бронирование остатка",2);

Что тут интересного? Сначала объявляем константу, куда ложим текущий физический путь до выполняемого скрипта. Далее загружаем все классы которые находятся в папке class (ака require_once vendor/autoload.php’ при использовании composer). Потом грузим файл config.php:

<?php

date_default_timezone_set('Europe/Moscow'); // Временная зона по умолчанию

if (isset($argv[0])){   // Тестовая
    ini_set('display_errors', 1);
    error_reporting(E_ALL);    
    define("log_file","dev.log");
} else {                // БОЕВАЯ
    define("log_file","work.log");
};

В котором прописываем логику определения разных констант в зависимости от переданного аргумента командной строки. Скрипт считает, что если аргумент есть — то значит версия скрипта «Для разработки».

В файле functions.php я добавил наиболее часто используемые мной функции:

  • PutLog — вывод лога в файл и дублирование в консоль, если скрипт запущен из командной строки
  • _GET — получение параметра $_GET, если отсутствует, возвращается пусто, или значение по умолчанию
  • _POST — получение параметра $_POST, если отсутствует, возвращается пусто, или значение по умолчанию
  • GetIpUser — попытаться получить IP пользователя вызвавшего выполнение скрипта
  • jsonExit — отдать на выход содержимое в формате json, установить заголовок json и выйти из программы
  • String2Boolean — преобразовать строку в тип boolean, Например на входе может быть строка «True» или число 1, на выходе будет именно Тип. Функция полезна при работе с JSON, где тип зачастую не определен однозначно.

Ну собственно и всё: этот шаблон консольного скрипта можно использовать на серверах как разместив его в cron, так и просто вызывая его через браузер.

1 2 3