Страницы

Поиск по вопросам

Показаны сообщения с ярлыком linux. Показать все сообщения
Показаны сообщения с ярлыком linux. Показать все сообщения

среда, 15 апреля 2020 г.

Как узнать оперативную память занятую процессом

#linux

                    
Доброго времени суток!
Вопрос такой, надо узнать оперативую память занятую процессом по PID. Желательно
командой, и желательно, что бы результат выводился только в виде занятой памяти без
посторонней информации.    


Ответы

Ответ 1



В принципе у top есть пара полезных опций, например top -b -n 1 -p 1184 выведет один раз информацию о процессе 1184 и завершится. Но все равно он читает данные из /proc, поэтому лучше и удобнее смотреть там

Ответ 2



Один из вариантов частичного ответа #include #include using namespace std; int main() { ifstream ifs("/proc/self/maps", ifstream::in); while (ifs.good()) { string s; getline(ifs, s); cout << s << endl; } } man 5 proc

Ответ 3



Есть очень продвинутый htop, я бы использовал его. Еще полезные найденные команды: ps axo %mem,comm,pid,euser | sort -nr | head -n 10 ps auxf | sort -nr -k 4 | head -10

Дополнительное tty устройство

#qt #cpp #linux

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


Ответы

Ответ 1



Спасибо всем, более правильный ответ на мой вопрос. -pseudo-terminal Как создать и работать с ним вот

Ответ 2



mknod, но аргументы надо где-то в описаниях системы искать. ls -l /dev говорит, что их много и major у всех 4. Похоже (по времени), что они создаются при загрузке ОС. Я, откровенно говоря, не понимаю с чем они на моей виртуалке связаны. Почитайте man 2 mknod, man 4 ttyS, man 4 tty и SEE ALSO в них. Может что-то полезное найдете.

понедельник, 13 апреля 2020 г.

Cron запуск Ruby скрипта

#cron #ruby #linux

                    
Добавляю в crontab 
*/1 * * * * root ruby /home/www/admin/cron.rb

В syslog
Apr 30 13:01:01 cs10433 /USR/SBIN/CRON[5448]: (root) CMD (ruby /home/www/admin/cron.rb)
    Apr 30 13:01:01 cs10433 /USR/SBIN/CRON[5447]: (CRON) error (grandchild #5448
failed with exit status 127)

Как заставить cron выпаолнять скрипТ?    


Ответы

Ответ 1



Код выхода 127 - это ошибка "command not found". Либо шелл не видит ruby, либо в скрипте вы вызываете команду, которую не видит шелл.

Ответ 2



#!/usr/bin/env bash export PATH ; PATH="/usr/local/rvm/gems/ruby-1.9.3-p392/bin:/usr/local/rvm/gems/ruby-1.9.3-p392@global/bin:/usr/local/rvm/rubies/ruby-1.9.3-p392/bin:/usr/local/rvm/bin:$PATH" export rvm_env_string ; rvm_env_string='ruby-1.9.3-p392' export rvm_path ; rvm_path='/usr/local/rvm' export rvm_ruby_string ; rvm_ruby_string='ruby-1.9.3-p392' unset rvm_gemset_name export RUBY_VERSION ; RUBY_VERSION='ruby-1.9.3-p392' export GEM_HOME ; GEM_HOME='/usr/local/rvm/gems/ruby-1.9.3-p392' export GEM_PATH ; GEM_PATH='/usr/local/rvm/gems/ruby-1.9.3-p392:/usr/local/rvm/gems/ruby-1.9.3-p392@global' export MY_RUBY_HOME ; MY_RUBY_HOME='/usr/local/rvm/rubies/ruby-1.9.3-p392' export IRBRC ; IRBRC='/usr/local/rvm/rubies/ruby-1.9.3-p392/.irbrc' unset MAGLEV_HOME unset RBXOPT ruby /home/www/admin/cron.rb cron.sh

Java socket: зависает соединение

#java #сокет #cpp #linux

                    
Пишу код на Java, код прикреплю ниже, там же комментарии в местах, где зависает соединение.
По документации в c =in.read(buffer); должно лежать -1 при завершении передачи. Сервер
завершает передачу файла и запускает поток на чтение, но клиент упорно ждет данных.
Клиент на java.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class foto_url {
    public static void main(String args[]) throws IOException
    {int serverPort = 5000; // здесь обязательно нужно указать порт к которому привязывается
сервер.
            String address = "54.228.232.96";
            InetAddress ipAddress = InetAddress.getByName(address); // создаем объект
который отображает вышеописанный IP-адрес
            Socket socket = new Socket(ipAddress, serverPort); // создаем сокет используя
IP-адрес и порт сервера.
            // Берем входной и выходной потоки сокета,теперь можем получать и отсылать
данные клиентом. 
         OutputStream out = socket.getOutputStream(); 
        InputStream in = socket.getInputStream();
        System.out.println("download");
        downloadFiles(in,"new11", 1024);
        System.out.println("upload");
        uploadFiles(out,"new11", 1024);
        System.out.println("download");
        downloadFiles(in,"zzx", 1024); 
        socket.close();
    }
    public static void downloadFiles(InputStream in,String strPath, int buffSize) {
        try {

            // Конвертируем потоки в другой тип, чтоб легче обрабатывать текстовые
сообщения.
            OutputStream writer = new FileOutputStream(strPath);
            byte buffer[] = new byte[buffSize];
            int c = in.read(buffer);
            while (c > 0) {
                writer.write(buffer, 0, c);
              //c= in.available(); //При таком варианте тоже зависает
               //   in.read(buffer);
                c =in.read(buffer);//В этом месте зависает.
                System.out.println("c="+c);
            }

            writer.flush();
            writer.close();

        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public static void uploadFiles(OutputStream out,String strPath, int buffSize) {
        try {

            // Конвертируем потоки в другой тип, чтоб легче обрабатывать текстовые
сообщения.
            InputStream read = new FileInputStream(strPath);
            byte buffer[] = new byte[buffSize];
            int c = read.read(buffer);
            while (c>0) {
                out.write(buffer);
                c =read.read(buffer);
            }
            out.flush();
            read.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

сервер на с++ под линукс.
 #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    using namespace std;
    void send_pic(int sock, char *path);
    void get_pictures(int sock,char *name);
    int  new_server()//запускает основаной порт и экстренный порт
    {
        int listener;
        struct sockaddr_in addr;
        char buf[1024];
        int bytes_read; 
        int sock;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(5000);
        addr.sin_addr.s_addr = INADDR_ANY;

        listener = socket(AF_INET, SOCK_STREAM, 0);
        if(listener < 0)
        {
            perror("socket");
            exit(1);
        }

        if(bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0)
        {
            perror("bind");
            close( listener );
            exit(2);
        }

        listen(listener, 1);

        while(1)
        {   int sesID=-1;
            sock = accept(listener, NULL, NULL);
            if(sock < 0)
            {
                perror("accept");
                exit(3);
            }
            switch(fork())
            {
            case -1:
                perror("fork");
                break;

            case 0:
                close(listener);
                send_pic(sock,"/home/ec2-user/pic.gif");
                get_pictures(sock,"pic/ololo.gif");
                send_pic(sock,"pic/ololo.gif");
                close(sock);
                _exit(0);

            default:
                close(sock);
            }

        }
       close(listener);
    }

    void send_pic(int sock, char *path)
    {
        cout<<"\nsend_picture"<


Ответы

Ответ 1



Чтение из сокета и запись в сокет - всегда в разных потоках. Логика пакетов делается проще - отправляйте первыми 2 или 4 байтами размер (в байтах) контента. Дальше всё просто: читаем 2(или 4) байта в цикле (сохраняем в переменную, к примеру, _len), как только что-то прочитали - заполняем буфер кусками из сокета, пока не получили длину буфера равной _len. Всё, пакет передан. Начинаем с начала. Читать не обязательно кусками, но нужно проверять на доступность порции в буфере сокета (на случай лагов в сети).

суббота, 11 апреля 2020 г.

Как последовательно запустить несколько процессов, а код завершения последнего потомка передать первому процессу?

#c #linux

                    
Добрый вечер. Подскажите как правильно выполнить задачу?
Необходимо создать цепочку из 5 последовательно запущенных процессов, когда каждый
дочерний процесс становится родителем для следующего потомка. Код завершения последнего
потомка передать первому процессу. В первом процессе вывести данное число на экран.

Создал в цикле 5 процессов:

pid_t return_value;

  for(int i = 0; i < 5; i++)
  {
    return_value = fork();
    printf("%s %d %s %d\n", "Процесс: ", getpid(), "PID: ", return_value);  
  }

  return 0;


Данный код выдает мне в терминале огромную простыню, 


Я так понимаю что это из-за того, что после создания нового процесса они продолжают
выполняться параллельно. Как код завершения последнего потомка передать первому процессу
так и не выяснил. Подскажите как правильно сделать? 
    


Ответы

Ответ 1



Надеюсь, Вы уже сами успешно решили свою задачку, но на всякий случай вот простой код. #include #include #include #include int main (int ac, char *av[]) { int n = 5, s; srand(getpid()); while (n--) if (fork()) break; if (n < 0) { // last child s = rand() % 100; printf("child %d exit rc: %d\n", (int)getpid(), s); exit(s); } wait(&s); if (n != 4) // all except first exit(WEXITSTATUS(s)); printf("Grandfather %d: child exited: %d\n", (int)getpid(), WEXITSTATUS(s)); return puts("End") == EOF; } Т.е. делаем цикл по переменной (в коде -- n), которая наследуется новым процессом и в нем запускаем новый процесс. Родитель выходит из цикла, ждет завершения потомка (тот в свою очередь ждет завершения своего потомка и так 5 раз). Если это не прародитель (определяем по n), то выходим с кодом завершения потомка, который получили в wait(). (без pipe передать PID последнего процесса в первый не получится (конечно, кроме разделяемой памяти или файла), но это мы с Вами вроде уже обсуждали).

Многопоточный epoll

#cpp #linux #g++ #epoll

                    
Написал код с epoll_create1(0); epoll_ctl(); epoll_wait(); и при вызове epoll_wait();
из двух потоков с удивлением вижу, что они возвращают одинаковые сокеты.

Мне казалось, что epoll можно использовать из разных потоков. Я не прав? Как получить
многопоточный epoll? Есть ли стандартное решение или он просто заменяет select() и
многопоточность нужно реализовывать самому?
    


Ответы

Ответ 1



Все оказывается до банальности просто, достаточно использовать флаг EPOLLONESHOT в epoll_ctl() и сокет будет выдаваться один раз.

Переполнение буфера при помощи “jmp esp” в gnu/linux

#linux #ассемблер

                    
Я пытаюсь написать программу для переполнения буфера в ОС gnu/linux.

В одной статье, посвящённой этой проблеме, нашла следующий способ:

[мусор]+[адрес инструкции jmp/call esp]+[шеллкод]          


Дизассемблирование уязвимой программы не помогает.

Каким образом можно найти адрес инструкции jmp %esp в gnu/linux?
    


Ответы

Ответ 1



по вот этой инструкции собрал бинарник на 32-битной системе (на 64-битной ошибка: Error: operand type mismatch for 'jmp', см. обновление ниже). текст программы: $ cat vuln.c #include #include // hard coded jmp *esp function ;-) void jmpesp() { __asm__("jmp *%esp"); } int main(int argc, char *argv[]) { char buffer[100]; strcpy(buffer, argv[1]); printf("buffer: [%s].\n", buffer); return 0; } сборка бинарника vuln: $ gcc vuln.c -o vuln -ggdb -fno-stack-protector -z execstack а вот она, инструкция: $ objdump -d vuln | grep 'ff e4' 804844f: ff e4 jmp *%esp обновление на 64-битной системе, видимо, вместо esp следует использовать rsp: __asm__("jmp *%rsp"); тогда сборка проходит удачно. и инструкция присутствует: $ objdump -d vuln | grep 'ff e4' 40054a: ff e4 jmpq *%rsp

Х без мыши, или mouse jail, или?.. подробности

#linux #x

                    
Этот вопрос гугленьем я не решил однозначно, поэтому прошу совета. Именно совета,
а не прямого решения.

Есть Хvesa без оконного менеджера, в ней висит dosbox.
Х почему-то всегда запускается с мышью, даже когда я намеренно убираю мышиные параметры
из строки запуска в .xsession . И это мешает, потому что в Xvesa по умолчанию (без
менеджера, очевидно) та забавная система фокусировки, когда регион получает фокус только
когда курсор мыши находится в нем. Стоит отвести мышь в сторону от окна - и любое управление
с клавиатуры замораживается. Можно ли заставить Xvesa использовать другой алгоритм
фокусировки без использования менеджера, я тоже не нашел в гугле. Вдобавок y мыши два
курсора: один снаружи "коробки", другой внутри. Когда один подходит к границе, то застывает
рядом с ней, а второй "оживает" и продолжает движение. Залочить курсор внутри dosbox
не получается, возможно, потому что это должен делать менеджер окон.

Вот и вопрос. Что лучше:


Использовать чей-то самописный скрипт или бинарник, реализующий принцип mouse jail,
ограничивающий движение мыши в заданном регионе.
Использовать более "официальный" xdotool.
Запустить Xvesa без мыши, чтобы она инициализировалась только в dosbox. Если да, то как?


Второму варианту я не доверяю, т.к. в голове почему-то отложилось, что xdotool делает
вещи неоптимально и может давать слишком большую нагрузку для маленькой задачи. Не
то, чтобы у меня может чего-то не хватить, но я потому и пытаюсь все сделать так, как
делаю, чтобы ради собственного удовольствия обойтись наименьшими ресурсами. Сейчас
система жрет 40 Мб ОЗУ, куда уж больше. xdotool, скорее, будет процессор нагружать,
но это тоже нежелательно.
Первому варианту по этим же причинам стоит не доверять еще больше, т.к. мало ли кто
там как это писал. Может, там вообще утечка памяти будет. :)
Ну а с третьим попросту не понятно, так как его-то я уже пробовал: удалил параметры
-2button -mouse из аргументов Xvesa. А он все равно запускается с мышью.
    


Ответы

Ответ 1



справедливо для «полноценного» xserver-а. как будет себя вести xvesa — не знаю. проще всего проверить. 1. мышь можно «обездвижить» (и отключить кнопки), например, с помощью xinput. показываю на примере. список устройств-pointer-ов (тут не мышь, а trackpad, что несущественно): $ xinput --list | grep pointer | Virtual core pointer id=2 [master pointer (3)] | ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] | ↳ Cypress APA Trackpad (cyapa) id=12 [slave pointer (2)] id у нужного устройства — 12 (но надёжнее обращаться по имени Cypress APA Trackpad (cyapa): id может меняться). отключаем и включаем, по номеру и по имени: $ xinput --disable 12 $ xinput --enable 'Cypress APA Trackpad (cyapa)' 2. а курсор мыши можно скрыть, например, с помощью xsetroot.

Ответ 2



dosbox не сможет использовать мышь, если вы ее отключите совсем в Хvesa. Просто потому что dosbox не напрямую работает с мышью, а получает "мышиные" события от X сервера. Не обманывайтесь тем, что там якобы есть вторая мышь - это лишь второй рисунок той же самой мыши. Так что ваш третий вариант отпадает. Я правильно понимаю, что у вас кроме dosbox ничего оконного не запущено? Почему бы тогда не использовать полноэкранный режим dosbox?

Онлайн ACM подобные тестирующие системы

#linux #память #время #memory

                    
Я прочитал данную статью про лимиты памяти, и написал некий код, который вычисляет
те или иные значения памяти и времени.


Как я понял, функция clock() измеряет время процессора, которое сильно отличается
от того, что выводит мне команда time в шелле. Каким образом в тестирующих системах
это отслеживается?
Есть куча разных полей типа:

VmPeak:    11884 kB
VmSize:    11884 kB
VmLck:         0 kB
VmHWM:      1108 kB
VmRSS:      1108 kB
VmData:      272 kB
VmStk:        88 kB
VmExe:        16 kB
VmLib:      3244 kB
VmPTE:        48 kB
VmSwap:        0 kB


Как именно ограничивают ресурсы в тестирующих системах?
Вариант с ps aux совсем не годен для коротко работающих программ.

    


Ответы

Ответ 1



Обычно измеряется процессорное время. Это то, что time выводит как user. По памяти - вам нужен показатель VmSize. Или VmPeak - это пиковое значение VmSize. Если хотите считать совсем честно - то надо отнять от него data/stack/exe/lib - это не "использование памяти" в смысле явного выделения в коде. Данные по памяти нельзя определить после завершения процесса, так что единственный вариант - достаточно часто опрашивать данные в фоне. Значение VmPeak за долю секунды до завершения кода будет практически актуальным как "максимум использованной памяти". И заодно следить за превышением выделенного времени выполнения. Писать свою систему с нуля достаточно тяжело. Посмотрите исходники существующих систем, например ejudge.

Ответ 2



ограничить время выполнения какой-нибудь программы можно, например, так: $ программа & sleep 0.5; kill $! &>/dev/null && \ echo "программа не уложилась в пол-секунды". пример — «уложилась»: $ sleep 0.4 & sleep 0.5; kill $! &>/dev/null && \ echo "программа не уложилась в пол-секунды" [1] 31136 [1]+ Done sleep 0.4 пример — «не уложилась»: $ sleep 0.6 & sleep 0.5; kill $! &>/dev/null && \ echo "программа не уложилась в пол-секунды" [1] 31139 программа не уложилась в пол-секунды [1]+ Terminated sleep 0.6

Нет прав для доступа к серверу при одном и том же владельце папки и процесса Apache. Как устранить?

#linux #apache

                    
Расклад следующий. Удаленный VDS-сервер, ставлю LAMP.

Указываю в файле /etc/apache/envvars

APACHE_RUN_USER = musaevhs
APACHE_RUN_GROUP = musaevhs


В файле /etc/apache2/sites-enabled/000-default.conf


    ServerName musaevhs.ru
    DocumentRoot /home/musaevhs/www

    
        AllowOverride All
        Allow From All
    

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined




Владелец папки - musaevhs, у этого пользователя sudo-права.
И все равно выплевывает


  Forbidden You don't have permission to access / on this server.
  Apache/2.4.7 (Ubuntu) Server at musaevhs.ru Port 80


Есть соображения, куда копать? Если выставляю DocumentRoot в папку /srv, которую
создал в корне, то все работает, файлы читает. У папки /srv владелец root.
    


Ответы

Ответ 1



часто применяемая для такой ситуации практика — добавлять пользователя, от имени которого выполняются «дочерние» процессы apache («родительский» всегда должен работать от имени root-а — ведь только root имеет право создавать сокеты на портах с номером меньше 1024), в требуемую группу. чаще всего встречается пользователь www-data (зависит от того, как собран и сконфигурирован apache, уточнить можно, например, по первому полю в списке процессов: ps aux | grep 'USER\|apache\|httpd). в вашем случае добавить его в группу musaevhs можно, например, так: $ sudo usermod -a -G musaevhs www-data после этого надо перезапустить apache (именно перезапустить: сделать не reload, а restart). естественно, и каталог /home/musaevhs, и каталог /home/musaevhs/www, и подкаталоги последнего должны принадлежать группе musaevhs и быть читабельны для группы. можно в этом убедиться с помощью команды ls -ld /путь/к/каталогу, а можно сразу и исправить, не уточняя, например, так: $ sudo chown :musaevhs /home/musaevhs $ sudo chmod g+rx /home/musaevhs $ sudo chown -R :musaevhs /home/musaevhs/www $ sudo find /home/musaevhs/www -type d -exec chmod g+rx {} +

четверг, 9 апреля 2020 г.

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

#linux #изображения

                    
Есть ли возможность у findimagedupes сравнивать изображения в одной папке с другой?

Например, в одной папке 100 изображений, и в другой столько же. В первой папке есть
одно изображение, более, чем на 85%, похожее на одно изображение в другой папке.

Я пробовал делать так:

findimagedupes -t 85 "первая_папка/*"  "вторая_папка/*"


но дело в том, что он показывает совпадения, которые нашлись в первой папке и/или
во второй. А надо, чтобы сообщал, что «найдено изображение в папке первая_папка, которое
совпадает с изображением во вторая_папка»
    


Ответы

Ответ 1



можно в цикле перебрать все пары файлов: $ for f1 in первый_каталог/*; do \ for f2 in второй_каталог/*; do \ findimagedupes -t 85 $f1 $f2; done; done если же требуется, чтобы в выводимых строках пары файлов не были перемешаны (первым может идти файл то из первого, то из второго каталога), то можно каждую строку отсортировать, воспользовавшись возможностью программы findimagedupes передавать получаемые строки на обработку указанному скрипту (см. man findimagedupes): $ for f1 in первый_каталог/*; do \ for f2 in второй_каталог/*; do \ findimagedupes -t 85 -i \ 'VIEW(){ for f in "$@"; do echo $f; done | sort | xargs echo; }' -- \ $f1 $f2; done; done такой перебор каждого-с-каждым довольно ресурсоёмок («отпечатки»-fingerprints вычисляются при каждом запуске), поэтому для большей оптимальности следует либо дополнить нужной функциональностью саму программу, либо, вызывая её для всех файлов сразу, несколько усложнить скрипт, передаваемый программе опцией -i. обновление «усложнил» скрипт: #!/bin/bash d1=$(realpath $1) d2=$(realpath $2) e1=$(echo $d1 | sed 's,/,\\/,g') findimagedupes -t 85 -i 'VIEW() { n1=$(for f in "$@"; do echo $f; done \ | sed -n "/^'$e1'/{p;q}"); n2=$(for f in "$@"; do echo $f; done \ | grep "^'$d2'" | xargs echo); if [ -n "$n1" -a "$n2" ]; then \ for f in "$@"; do echo $f; done | sed -n "/^'$e1'/!{s|^|$n1 |;p}"; fi; \ }' $d1/* $d2/* вызывается он с двумя параметрами: первый_каталог второй_каталог (без каких-либо масок, просто пути к каталогам). для каждой строки, генерируемой программой, он оставляет только один файл из первого каталога (первый встретившийся), но разбивает её на несколько строк так, чтобы в каждой получившейся строке было только по одному файлу из второго каталога. например, строку dir1/file1 dir1/file2 dir2/file1 dir2/file2 он заменит на две строки: dir1/file1 dir2/file1 dir1/file1 dir2/file2 и, конечно, строки, в которых присутствуют только файлы из первого или только из второго каталога, игнорируются.

pc speaker c++ beep();

#cpp #linux

                    
Для winapi существует стандартная библиотека windows.h с функцией Beep().

Есть ли аналог в gnu/linux, или необходимо использовать сторонние библиотеки?
    


Ответы

Ответ 1



Если есть conio.h, можно воспользоваться putch('\a'); Про putchar рядом была тема, что не работает, но думаю, putch должен.

Ответ 2



Можно использовать возможности консоли линукс. Для этого нужно залогиниться в текстовый терминал. Далее использовать управляющие последовательности (в формате для printf): \033[10;%d] - установить частоту. \033[11;%d] - установить длительность в миллисекундах. \a - собственно выдать сигнал установленной частоты и длительности. Перед выдачей нового сигнала нужно подождать пока закончится текущий, иначе он будет прерван и сразу зазвучит новый. Может потребоваться загрузить модуль ядра для поддержки pc-speaker pcspkr или snd_pcsp и с помощью alsamixer включить всё, что касается speaker и beep. Код: #include #include void Beep(int Hz, int msec) { fprintf(stderr,"\033[10;%d]\033[11;%d]\a", Hz, msec); usleep(msec*1000); } int main(int argc, char* argv[]) { Beep(494, 250); Beep(523, 250); Beep(587, 500); Beep(523, 250); Beep(494, 250); Beep(440, 500); return 0; } Запускать необходимо из текстовой консоли или перенаправить вывод stderr на неё. Думаю в настоящее время более удобным является другой способ -- использовать одну из портируемых библиотек. Поэтому предлагаю реализацию Beep с помощью SDL в котором использовал идею алгоритма Брезенхема. Справедливости ради скажу, что для высоких частот звук консоли лучше. #include #include #include typedef struct { SDL_AudioSpec spec; int freq; int t; int err; int newfreq; int newt; Uint8 v; } udata_t; static udata_t uData; static void fill_audio(void *udata, Uint8 *stream, int len) { udata_t * const d= udata; while(len--) { if(!d->t) { if(d->newt) d->t = d->newt; d->freq = d->newfreq; d->newt = 0; } if(d->t) { d->t--; d->err += d->freq; if(d->err >= d->spec.freq) { d->err -= d->spec.freq*2; d->v= ~d->v; } } else if(!len) { SDL_PauseAudio(1); } *stream++ = d->v; } } void Beep(int Hz, int msec) { while(uData.newt) { usleep((uData.t*1000+uData.spec.freq-1)/uData.spec.freq*1000); } uData.newfreq= Hz*4; uData.newt= uData.spec.freq*msec/1000; if(!uData.t) SDL_PauseAudio(0); } void wait_audio() { while(uData.newt || uData.t) { usleep((uData.t*1000+uData.spec.freq-1)/uData.spec.freq*1000); } } void init_audio() { SDL_AudioSpec wanted; /* Set the audio format */ wanted.freq = 65535; wanted.format = AUDIO_U8; wanted.channels = 1; /* 1 = mono, 2 = stereo */ wanted.samples = 1024; /* Good low-latency value for callback */ wanted.callback = fill_audio; wanted.userdata = &uData; /* Open the audio device, forcing the desired format */ if ( SDL_OpenAudio(&wanted, &uData.spec) < 0 ) { fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); exit(1); } uData.err= uData.spec.freq; } int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_AUDIO); init_audio(); Beep(494, 250); Beep(523, 250); Beep(587, 500); Beep(523, 250); Beep(494, 250); Beep(440, 500); wait_audio(); return 0; } Компиляция: gcc beepsdl.c `sdl2-config --cflags --libs` либо sdl-config вместо sdl2-config в зависимости от версии. Возможно потребуется поставить libsdl2-dev.

Очередь команд в консоли Linux

#linux #shell

                    
Предположим, что в данный момент в консоли уже выполняется какая-то команда. Она
занимает продолжительное время. Я хотел бы выполнить одну или несколько команд после
того, как завершится эта. Как это сделать?

Я знаю, что можно Ctrl + Z и bg, но это не совсем то. Нужно не в бэкграунд отправить
команду, а именно дождаться ее завершения.
    


Ответы

Ответ 1



используйте не bg (background), а fg (foreground), после которой добавьте нужную команду (команды): $ date; sleep 10 Fri Oct 2 10:45:04 MSK 2015 ^Z [1]+ Stopped sleep 10 $ fg; date sleep 10 Fri Oct 2 10:45:14 MSK 2015 fg и последующую команду можно связать и условиями, например: && или ||.

Что означают следующие ANSI escape последовательности?

#c #linux #escape

                    
Просмотрел несколько источников, в том числе англоязычных, но нигде не нашел расшифровку
следующих escape-последовательностей:

\e[%i%d;%dr (В библиотеке S-lang присваивается переменной с именемScroll_R_Str)

\e[%i%d;%dH (Тут 3 аргумента, но для установки позиции, согласно документации, используется
2, я не понял этого момента..., в библиотеке S-lang данная последовательность присваивается
переменной с именемAbs_Curs_Pos_Str)

\e[P
\e[%dM
\e[%dL


Обновлено: неизвестны для меня также следующие последовательности (первые две, насколько
я понимаю, не являются ESC-последовательностями, так ли это?)

\016
\017
\e(B\e)0


Помогите пожалуйста в них разобраться и понять, что они делают?
    


Ответы

Ответ 1



Посмотрите man console_codes или то же самое в сети или по-русски. С ESC[ начинаются CSI-последовательности.

Ответ 2



Посмотрите тут: http://www.opennet.ru/docs/BSD/pascal/syscons/ansi.html Нашел там Esc[nM, Esc[nL - удалить / вставить n строк В английской википедии, вроде норм расписан принцип https://en.wikipedia.org/wiki/ANSI_escape_code int i, j; qDebug() << std::sscanf("12345", "%i%d", &i, &j) << i << j; выводит 1, 12345, 0 qDebug() << std::sscanf("12 345", "%i%d", &i, &j) << i << j; выводит 2, 12, 345. Может чем поможет

Как получить IP и MAC адреса в сети? Работа с arp cache в linux(android)

#linux #android #сеть #arp

                    
Два дня пытаюсь понять как заполнить arp cache? Мне нужно получить ip и mac адреса
всех устройств в домашней сети для одного приложения под android. Порылся в разных
ресурсах. Как я понял нужно сделать широковещательный запрос в подсеть и ждать.
Ситуация такая:
Я подключен через WiFi к сети домашнего маршрутизатора. ip адрес моего устройства
192.168.0.71, а широковещательный адрес 192.168.0.255, маска подсети 255.255.255.0(то
есть 254 хостов может быть как я понял).
Смотрю arp cache:

 
arp -a
 

Только адрес маршрутизатора 192.168.0.1, а в сети на самом деле как минимум 6 устройств.

Делаю широковещательный пинг

 
ping -c 1 -b 192.168.0.255
 

Пишет что 100% потеря пакетов, лол

Вновь смотрю arp cache - ничего нового.
Пытался под root и не под root.
Есть ли какие нибудь другие пути получить ip и mac адреса в сети?
Помогите плиз! По сетям не силен!
    


Ответы

Ответ 1



Либо ставить nmap на android, либо fping. В общем общая схема такая: пинговать каждый хост в подсети (вне зависимости от его доступности), а потом уже делать arp -a | grep Для nmap будет что-то типа: nmap -sP 192.168.0.* Для fping fping -g 192.168.0.0 192.168.0.255

Ответ 2



Чтобы linux отвечал на широковещательный пинг, надо его включить (на каждом хосте): # echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts При чём -c1 приведёт к тому, что ping завершится после приёма первого пакета и не станет ждать других устройств. Лучше ограничить время 1 секундой: ping -w 1 -b 192.168.0.255 Сканировать подсеть перебором всех адресов можно так (под рутом результат лучше): # nmap -sP -n -T5 192.168.1.0/24

Проблема с ярлыком запуска

#linux

                    
Здравствуйте.
Ничего не могу понять - помогите прояснить ситуацию.

Имеется:
Debian 8, amd64, Mate и приложение sqldeveloper.

Из консоли приложение запускается без ошибок:

everhide@station:~$ sh /opt/sqldeveloper/sqldeveloper.sh 

 Oracle SQL Developer
 Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.


По ярлыку генерируемому автоматически нет - ничего не происходит.
Код ярлыка: 

everhide@station:~/desktop$ cat Oracle-sqldeveloper.desktop 
#!/usr/bin/env xdg-open
[Desktop Entry]
Encoding=UTF-8
Name=SQL Developer
Comment=Oracle SQL Developer
Icon=/opt/sqldeveloper/icon.png
Exec=sqldeveloper
Terminal=false
Type=Application
X-Desktop-File-Install-Version=0.22
Categories=X-Red-Hat-Extra;Application;Development;


Остальные ярлыки полностью работоспособны.
Я так понимаю, возможный корень проблемы кроется в том, что приложение изначально
разрабатывалось для систем RedHat\CentOS\Fedora и было установлено мною c помощью alien.
Тем не менее... Подскажите, куда копать? На что смотреть? Буду благодарен за советы.
    


Ответы

Ответ 1



вместо: Exec=sqldeveloper можно указать команду, которую надо вызывать: Exec=sh /opt/sqldeveloper/sqldeveloper.sh если при «запуске» ярлыка нет никакой реакции, посмотрите, какие строки при этом добавляются в файл ~/.xsession-errors. в качестве гипотезы: возможно, этому скрипту (или какой-нибудь из программ, вызываемых внутри скрипта) требуется полноценный tty, который, естественно, не создаётся при «запуске» ярлыка. для таких случаев и предназначен параметр terminal=true, при наличии которого запускается эмулятор терминала, которому уже и передаётся для выполнения команда, указанная в параметре exec=....

Удалить дубли в Linux по маске

#linux #регулярные_выражения #centos

                    
Составить команду для Linux CentOS

Нужно удалить дубли с практически одинаковыми названиями, содержащими цифры в конце.

Есть:

Авария на Чернобыльской АЭС.ppt
Авария на Чернобыльской АЭС 345.ppt
АА Лекция 13 Ю Защита в чс ДЛЯ ЗО.ppt
АА Лекция 13 Ю Защита в чс ДЛЯ.ppt
Обозначения в автоматике 194.ppt
Барклай де Толли.ppt


Оставить:

Авария на Чернобыльской АЭС.ppt
АА Лекция 13 Ю Защита в чс ДЛЯ.ppt
Обозначения в автоматике 194.ppt
Барклай де Толли.ppt


fdupes удалить дубли не помог.
    


Ответы

Ответ 1



Нашла на мой взгляд самое правильное решение ls | sort -f | uniq -dw 10 | while read d; do echo "$d"; done Команду после теста заменяем на rm и выставляем правильное количество знаков по которым ведется отбор. У меня стоит 10 но есть резон оптимизировать опытным путем

Сколько используется ресурсов процессора согласно выводу программы top?

#linux #top

                    
Сервер работает на дистрибутиве debian gnu/linux 7. Запускаю конвертацию видеофайла
через ffmpeg размером 400мб из формата avi в mp4. Команда простейшая, без дополнительных
параметров:

$ ffmpeg -i pathInput -f mp4 pathOutput


Решил посмотреть использование ресурсов сервера командой top.
Вот какую информацию получил по процессу ffmpeg

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
55291 admin     20   0  379m 120m 5484 S 378.5  0.2  17:08.12 ffmpeg


Если не ошибаюсь, согласно этим данным, используется 378.5% CPU.

Как это может быть? Я неправильно интерпретирую эти значения?
    


Ответы

Ответ 1



число в столбце %cpu (процент использоания процессора) суммируется по всем ядрам (реальным или виртуальным) всех процессоров. в данном случае число 378.5 говорит, скорее всего, о том, что четыре ядра используются почти на сто процентов. кстати, у программы top есть возможность показывать (в верхней, «заголовочной» части «окна» программы) не только общую нагрузку на все ядра всех процессоров, но и на каждое ядро в отдельности. переключается этот режим нажатием кнопки 1. пример вывода по всем ядрам: top - 18:17:10 up 11 days, 13 min, 19 users, load average: 0.11, 0.25, 0.25 Tasks: 203 total, 1 running, 202 sleeping, 0 stopped, 0 zombie %Cpu(s): 1.9 us, 0.5 sy, 0.0 ni, 95.8 id, 1.8 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 8218532 total, 3391900 used, 4826632 free, 468744 buffers KiB Swap: 2719740 total, 0 used, 2719740 free, 1168472 cached пример вывода по каждому ядру отдельно: top - 18:17:17 up 11 days, 13 min, 19 users, load average: 0.09, 0.24, 0.25 Tasks: 203 total, 1 running, 202 sleeping, 0 stopped, 0 zombie %Cpu0 : 1.6 us, 1.6 sy, 0.0 ni, 96.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu3 : 0.8 us, 0.8 sy, 0.0 ni, 98.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 8218532 total, 3409680 used, 4808852 free, 468744 buffers KiB Swap: 2719740 total, 0 used, 2719740 free, 1190592 cached

суббота, 4 апреля 2020 г.

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

#linux #c

                    
Выяснил, что символы стрелок имеют следующие ASCII коды:

72 - вверх
75 - влево
77 - вправо
80 - вниз


Но эти же коды имеют некоторые буквы в верхнем регистре.

Возможно, эта информация ошибочна, но при проверке мне никак не удалось напечатать
символы стрелок.
Подскажите пожалуйста как это сделать через обычный printf?
Поддерживается только ASCII.
    


Ответы

Ответ 1



эти коды хоть и соответствуют стрелочкам, но не все так просто - они там составные. То есть, код стрелки - это два байта, а не один. И первый байт Вы забили указать. Этот байт - 224. То есть, код стрелки вверх - 224 72. Вот только распечатать их нельзя. Это управляющие символы клавиатуры. Более того, их нет в стандартной аски таблице. Когда то давно, когда был дос и нужны были стрелочки, делали кодогенераторы. То есть, готовиться своя таблица, в которой прописано отображение каждого символа. И можно взять часть символов, записать туда правильные картинки и использовать. Я даже не знаю, возможно ли это сейчас, но думаю, что все возможно. В любом случае, можно перевести видеорежим в графический и рисовать красиво.

Ответ 2



Используйте эти коды: ASCII value of character ↑: 24 ASCII value of character ↓: 25 ASCII value of character →: 26 ASCII value of character ←: 27

как организовать контроль date на нескольких машинах?

#linux #datetime

                    
Есть насколько машин с линуксом, требуется организовать одновременный контроль даты
и времени на них с промежутком примерно в полчаса, чем такое сделать можно? В идеальном
случае, без постороннего софта на контролируемых машинах.
    


Ответы

Ответ 1



я проверяю время на машинах таким скриптом: #!/bin/bash for i in "$@"; do echo -n "$i " r=$(ssh $i TZ=UTC /bin/date -R) l=$(TZ=UTC /bin/date -R) if [ "$r" != "$l" ]; then echo "remote: $r local: $l" else echo ok fi done используется беспарольный ssh-доступ (так удобнее, чтобы пароли постоянно не вводить). пример вызова: $ этот-скрипт user1@host1 user2@host2 user1@host1 remote: Mon, 14 Mar 2016 11:48:38 +0000 local: Mon, 14 Mar 2016 11:48:40 +0000 user2@host2 ok видно, что на host1 часы отстают примерно на две секунды от часов на локальной машине, где запускался скрипт. сравниваются, собственно, строки, возвращаемые командой /bin/date -R, т.е., если разница во времени немного меньше секунды, в большинстве случаев сравнение даст положительный результат. для большей точности лучше поставить пакет с ntpd (обычно пакет так и называется). тогда и сверять время надо будет только в диагностических целях. даже если у машин нет выхода в интернет, с помощью ntpd можно настроить синхронизацию между ними, без привязки к внешнему миру.