The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Создать новую тему
 - Свернуть нити
Пометить прочитанным
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Архив | Избранное | Мое | Новое | | |  
Форум Программирование под UNIX
ассемблерные вставки в код Линукса 'это другое'?, !*! Анонимище, (Rust) 20-Фев-25, 12:00  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Слышал жалобы на то, что якобы введение Раста в ядро Линукса нарушит идиллию, так как сейчас весь код на Си, а теперь будет смесь двух языков.

Простите, но а как же ассемблерные вставки в коде ядра? Наверняка они там есть(буду очень удивлен если их там нет), причем под разные платформы. То есть, зоопарк ассемблеров это не проблема, а еще один язык, причем высокоуровневый (по сравнению с ассемблером) почему-то приведет к проблемам.

Rust: Как разделить типаж на части?, !*! Ан Оним, (Rust) 16-Фев-25, 00:32  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Можно ли как-то большой типаж (trait) с большими методами по-умолчанию разделить на несколько файлов? Ну то есть часть функций в одном файле описать, а остальные - в другом.
Селектор и повторитель-запускатель команд из .bash_history, !*! dcc0, (C/C++) 24-Янв-25, 01:25  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Если время есть - минут 5, хочу попросить кого-нибудь протестировать программу и сказать своё мнение. Но не по коду, а больше по самому функционалу.
Программа для Linux. Написана на C. Реализует возможность просмотра и выполнения команд из файла .bash_history по номеру.

Управление: s - сброс, клавиши 0-9 (можно переходить по разрядам) - переход к номеру команды. Стрелки вверх и вниз - переход к ближайшим командам. Выход 501 или "`".
Работает из директории пользователя. Прокрутки нет (только стрелки), но если нужна, то можно использовать в сочетании с tmux:


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////ПОИСК И ЗАПУСК КОМАНД ИЗ .BASH_HISTORY/////
//////////MSK. 2025///////
//////////Сrafted by: dcc0@yandex.ru///////////
/////////MoLoT////////
//////////Принцип: селектор, выбор через цифры. Enter: подтверждение//////////
////////////////////////////////////////////////////Рассчитан на 500 строк .bash_history/////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>

#include <stdlib.h>

#include <termios.h>

#include <string.h>

#include <unistd.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*Перевод в режим non-canonical, getch работает без Enter. Этот фрагмент кода взят в Интернете*/
//This function found on stackoverflow
                           //////////////////////////////////////////////SWITCH TO NON-CANONICAL///////////////////////
                           /////////////////////////////////////////////////////////ФУНКЦИЯ////////////////////////////////////////////
/////////SOURCE: stackoverflow.com SLASH questions/63751531/non-canonical-terminal-mode-buffer-stdout-in-c-program//////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static struct termios stored_settings;

void set_keypress(void) {
  struct termios new_settings;

  tcgetattr(0, & stored_settings);

  new_settings = stored_settings;

  /* Disable canonical mode, and set buffer size to 1 byte */
  new_settings.c_lflag &= (~ICANON);
  new_settings.c_cc[VTIME] = 0;
  new_settings.c_cc[VMIN] = 1;

  tcsetattr(0, TCSANOW, & new_settings);
  return;
}

void reset_keypress(void) {
  tcsetattr(0, TCSANOW, & stored_settings);
  return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                      //////////////////////////////Вызов Селектора/////////////////
                 ///////////////////////////////////////////////////////////////////////////////////
      /////////////////////////////////////////////////ФУНКЦИЯ////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Функция вывода селектора.  Возвращает название программы
char * print_select(int select, char * p, char  arr1[500][200], int z)  {
  int j = 0;
  /*Выделение цветом*/
  char colored[14] = "\033[43m";
  /*Сброс цвета*/
  char uncolored[14] = "\033[0m";

  //====ВЫВОДИМ СЕЛЕКТОР===
  /*Очистим экран. Обновим. Первый раз выводим*/
  system("clear");
  if (select == 0) {
    /*Количество вариантов выбора в переменной z*/
    for (j = 0; j != z; j++) {
      printf("%d.[%s]\n", j + 1, arr1[j]);
    }
  }

  //====ЕСЛИ СДЕЛАН ВЫБОР===
  int choice = select - 1;
  // Выводим результат выбора
  if (select > 0) {
    for (j = 0; j < z; j++) {
      // Выделяем цветом выбор
      if (select == j && select != 501) {
        // Запомним выбор. Нужно, чтобы напечатать в правильно
        // последовательности так как селектор с 1 по 6, массив с 0 по 5
        choice = select - 1;
        printf("->[%s%s%s]\n", colored, arr1[select - 1], uncolored);
        /* Возвращаем указатель на область памяти, где эта строка. Заодно
         * выделили память под нее (strlen - если не известен размер)*/
        //p = (char * ) malloc(strlen(arr1[select - 1]) + 1);
        //Но мы знаем размер 20. char * - приведение к типу "указатель на строку"
        p = (char * ) malloc(400);
        strcpy(p, arr1[select - 1]);
        break;
      }
      if (j != choice) printf("%d.[%s]\n", j + 1, arr1[j]);
    }

//Последнюю опцию добавим вне цикла
if (select ==500) {
    printf("->[%s%s%s]\n", colored, arr1[select - 1], uncolored);
      p = (char * ) malloc(400);
     strcpy(p, arr1[select -1]);
}

  }

  printf("Для выхода: `  или 501 \n");
  printf("Для сброса нажмите  букву: s  \n");
  printf("Если трехзначное число, то нажатие s обнулит буфер!\n");

  /*Вернем название программы, которую надо выполнить*/
  if (p != "")
    return p;
  return "1";
}

              //////////////////////////////BUFFERING ////////////////////////////////
        ////////////////////////////БУФЕРИЗАЦИЯ ФАЙЛА//////////////////////////
/////////////////////////////////////////////ФУНКЦИЯ/////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////


char * buffering (char arr1[500][200], int z_size ) {


///////////////////////////////////////////////////////////////////////////////////////////
  //==================READING FILE============//
  /////////////////////////////////////////////////////////////////////////////////////////
  // Читаем файл с программами 1 раз. Потом будем хранить в буфере arr1
  FILE * file;
  char buffer1;
  char str[200];
  int i = 0;
  /*Количество вариантов*/
  int z = 0;
  int j = 0;
  // Количество показываемых файлов. Массив. Буфер для .bash_history

  file = fopen(".bash_history", "r");

while ((buffer1 = getc(file)) != EOF) {
    if(z==500)
    break;
    str[i] = buffer1;

    if (str[i] == '\n') {
      // Пишем строку  посимвольно в отдельный массив
      for (j = 0; str[j] != '\n'; j++) {
        arr1[z][j] = str[j];
      }
      /*Запишем 0 в конец строки*/
      arr1[z][j] = '\0';
      z++;
      //Сбросим i , чтобы очистить str[0]
      //Так как ниже инкремент, то сбросим в -1, т.е. ниже i уже = 0
      //Иначе в str[0] всегда будет в начале первый символ
      i = -1;
    }
    i++;
  }

  fclose(file);
  //Вернем указатель на массив
  return * arr1;

}
                      ////////////////////////////////MAIN///////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                     ///////////////////////////////////////////////////////////////////////////////
                  ////////////////////////////////////ФУНКЦИЯ//////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main(void) {

      ////////////////////////////////KEYS//////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////УПРАВЛЕНИЕ/////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////////////
    char  const KEY_A='A'; //Стрелка вверх
    char const KEY_B='B'; //Стрелка вниз
    char const KEY_s='s';  //Сброс
    char const KEY_EXIT='`'; //Выход (`)
    char const KEY_SPACE=' '; //Пробел
    char const KEY_ENTER='\n'; //Enter
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////

//Массив хранит .bash_history
  char arr1[500][200];
//Функция буферизации
  buffering(arr1, 500);
//Размер массива - буфера
  int z = 500;
///////////////////////////////////////////////////////////////////////////////


  char * run_program;
  //для названия команды
  char * p;
  //Цвет
  char colored[14] = "\033[43m";
  /*Сброс цвета*/
  char uncolored[14] = "\033[0m";
  int select = 0;
  //Вызываем селектор 1 раз, пустой
  print_select(select, p, arr1, z);
  //С помощью terminos переключим вывод терминала в non-canonical mode.
  //Это позволит не нажимать Enter при переходе от опции к опции, но для выполнения нажать надо
  set_keypress();
  //Для чтения   с терминала
  char value = getchar();
  //Для перемещения по разрядам
  char buffer[3] = {0};
  //Счётчик буфера
  int i = 0;
  int y = 0;


//////////////////////////////////////////////////////////////////////////////////
////////////////////////СЕЛЕКТОР В ЦИКЛЕ////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

  while (1) {
//////////////////////////////////////////////////////////////////////////////////
///////////////////УПРАВЛЕНИЕ СТРЕЛКАМИ///////////////////
//////////////////////////////////////////////////////////////////////////////////
//Листаем вниз
     if (value == KEY_B) {
         y++;
         value = KEY_SPACE;
        select=select+y;
        run_program = print_select(select, p, arr1, 500);
        select=0;
        }

//Листаем вверх
    if (value == KEY_A) {
        y--;
         value = KEY_SPACE;
        select=select+y;
        run_program = print_select(select, p, arr1, 500);
        select=0;
        }
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

    if (value != KEY_SPACE && value != KEY_s) {
      buffer[i] = value;
      value = KEY_SPACE;
      //Приведем к int
      select = strtol(buffer, NULL, 10);
      //Вызываем селектор с выбором
      run_program = print_select(select, p, arr1, 500);
      i++;
      //Освободим память
      //free(run_program);
    }


    ///////////////////////////////////////////////////////////////////////////////
    //Проверим буфер. Если буфер заполнен, то обнулим его. Напечатаем то что в нем было в начале
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    //Проверим буфер. Если буфер заполнен, то обнулим его. Напечатаем то что в нем было в начале
    //Можно описать циклом, но оставим всё явно для наглядности
    //Тут конъюнкция (логическое "и", логическое сложение, в курсе булевой алгебры или логики:))
    if (value !=  KEY_A && value !=  KEY_B && y == 0)  {
        if (buffer[0] > 0  && buffer[1]  == 0) {
      printf("%c", buffer[0]);

    }

       if (buffer[0] > 0 && buffer[1] > 0 && buffer[2]  == 0) {
      printf("%c %c", buffer[0], buffer[1]);

    }

         if (buffer[0] > 0 && buffer[1] > 0 && buffer[2] > 0) {
      printf("%c %c %c", buffer[0], buffer[1], buffer[2]);

    }
    value = KEY_SPACE;
}
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////


    //Добавляем новое число в буфер
    if (buffer[i] > 0) {
        //Чтобы не получить stack smashing
        if (i >= 3) {
            i = 3;
        }
      buffer[i] = value;
    }

    //Ожидаем ввод
    value = getchar();
    //Выполним программу
    //Проверим, что нажат Enter (\n) и то, что не выходим
    if (value == KEY_ENTER && select !=501) {
        system(run_program);
      //Чтобы остановить обновление
      //и показать результат программы
    value = KEY_SPACE;
    }
    //Обнулим проход (для наглядности все опишем явно)
    if (value == KEY_s && select!=501) {
      //Обнулим буфер
      buffer[0] = 0;
      buffer[1] = 0;
      buffer[2] = 0;
      //Обнулим счётчик буфера
      i = 0;
      select = 0;
      y = 0;
      print_select(select, p, arr1, z);
    }
    //Выход (дизъюнкция - нестрогое "или".  Или то, или то. Если первое условие верно, то второе не проверяется)
    if (value == KEY_EXIT || select==501) {
      break;
  }

  }

  printf("\033[43m Выход \033[0m \n");
  return 0;
}


  

Схема Как понять Продолжения?, !*! noname nobody, (Языки программирования) 02-Янв-25, 16:26  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Ускользает смысл, уже не раз пытался понять.

Схема прекрасна, решил подтянуть матчасть. Если кто понимает простым языком поделитесь.

(define (range start end)
    (if (> start end)
        (list)
        (cons start (range (+ start 1) end))))

(range 1 10); => (1 2 3 4 5 6 7 8 9 10)

Bash regex, !*! Sarge, (Shell скрипты) 19-Дек-24, 16:26  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
например есть каталоги вида
/home/user/qwe123
/home/user/asd456
/home/user/zxc789
надо сделать 2 переменные где:
a='/home/user/qwe'    b='123'
a='/home/user/asd'    b='456'
a='/home/user/zxc'    b='789'

по цифрам вроде нагуглил вот такое
STRING='/home/user/qwe123'
echo ${STRING//[^0-9]/}
123

подскажите как для первой части будет выглядеть

Атомарная замена 'файлов', !*! Аноним, (Разное) 16-Дек-24, 06:07  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
... по-видимому невозможна в Linux.

Требования: транзакционность. Два разрешённых состояния:
* есть оригинальный файл, нет замены нигде
* есть замена в нужном месте, оригинального файла нет

Два запрещённых:
* есть оригинальный файл, замена насрана где-то
* нет ни оригинала, ни замены

Обычный файл вы можете создать с флагом O_TMPFILE (временный файл, не пишущийся в журнал), а потом попробовать атомарно заменить через renameat2(..., RENAME_EXCHANGE), но файлы в /proc/self/fd - это симлинки, и renameat2 в них не умеет. Можно, конечно, попробовать поиграться с readlink, но он вам выдаст несуществующий путь.

Hardlink - не умеет заменять файлы, флаг AT_REPLACE так и не был добавлен.

Директория/симлинк: вы не можете ни создать их с заменой, ни создать их файлы через open с флагом O_TMPFILE, и потом тип поменять. Сами же вызовы для их создания флаги не поддерживают.

Складывается впечатление, что так сделано намеренно, чтобы с race conditions дел не иметь.

проблемы с точностью команды at, !*! AS, (Shell скрипты) 07-Ноя-24, 12:57  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
вот когда нужно например запустить трояна например ровно в 15:00:58 - at только минуты понимает..
в агонии пришлось заколотить примерно такое:

(while ! date|grep -q '15:00:58'; do sleep 1; done;  ./troyanStart.exe)&

но веть оно после разлогинивания неподсоединяемо
что мне делать? или у меня древняя версия atd?

Команда time вывод в мс., !*! evi, (Shell скрипты) 04-Сен-24, 12:23  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Здравствуйте!

При использовании команды time --format хочу вывод времени в милисекундах при форматированном выводе.

Если использовать команду без аргументов, команда выводит следующим образом _и_такой_вывод_меня_устраивает_:
# time ./my_prog < input.txt
> real    0m0,058s
> user    0m0,019s
> sys    0m0,040s

Но для использования флагов, необходимо использовать абсолютный путь, но от этого меняется формат вывода по default как указано в man 1 time (переменная окружения $TIME не задана), а точность указывается на один порядок меньше:
# /bin/time ./my_prog < input.txt
> 0.02user 0.02system 0:00.05elapsed 96%CPU (0avgtext+0avgdata 2428maxresident)k
> 0inputs+0outputs (0major+302minor)pagefaults 0swaps

Далее проделываю использую флаги -p или -f и вывод тоже с точностью на порядок меньше:
# /bin/time -p ./my_prog < input.txt
> real 0.05
> user 0.02
> sys 0.03

# /bin/time -f "real\t%e\nuser\t%U\nsys\t%S" ./my_prog < input.txt
> real 0.05
> user 0.02
> sys 0.03

#



Подскажите по замене строки с помощью sed, !*! danswano, (Shell скрипты) 04-Июл-24, 14:44  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Всем привет!
Когда я пытаюсь в куче конфигов заменить часть IP-адреса, то пишу команду
sed -i '/s/192.168.0/10.55.200/g'
Проблема в том, что в конфиге dhcpd есть настройки отдачи таблицы маршрутизации вида
24,172,21,0,192,168,0,254
Такие строки в результате выполнения sed заменяются на
24,172,21,0,10.55.200,254
Вопрос: как правильно написать выражение для sed, чтобы он корректно обработал эти строки или просто пропустил их? Запятая в качестве разделителя встречается только в конфиге dhcpd, если я правильно помню...
psycopg2 не может вернуть текущую схему через команду SHOW, !*! xintrea, (PostgreSQL) 20-Июн-24, 16:44  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
1. Создаю собственную схему,
2. переключаюсь на нее,
3. и сразу хочу посмотреть какая схема используется.

Делаю это следующим кодом:


# Подключение к БД с заданными параметрами
connection = psycopg2.connect(**pgConnectionParameters)
cursor = connection.cursor()

# Переключение на заданную схему
dbSchema = 'our_schema'
cursor.execute("CREATE SCHEMA IF NOT EXISTS %s" % dbSchema)
cursor.execute("SET search_path TO %s" % dbSchema)

# Проверка текущей схемы
result = cursor.execute("SHOW search_path;")
print( result )


А результат None. Соответственно, даже fetchone/fetchall от результата вызвать не могу.

Вопрос: почему переменная result равна None?

Базис S, K на плюсах, !*! Аноним, (C/C++) 04-Июн-24, 22:21  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Ребят, можете проверить, правильно реализовал Комбинаторы базиса S,K лямбдами на C++11?

// C++11
#include <iostream>

int main() {
    //-I-----------------------------
    const auto I = [](const auto x){
        return x;
    };
    //-K-S----------------------------
    const auto K = [](const auto x){
      return [x](const auto y){ return x; };
    };
    const auto S = [](const auto x){
        return[x](const auto y){
            return [x,y](const auto z){
                auto xz = x(z);
                return xz(y(z));
            };
        };
    };
    //------------------------------
    const auto x = 42;
    const auto y = 41;

    const auto Ix = I(x);
    const auto Iy = I(y);
    const auto SKKx = S(K)(K)(x);

    if( Ix == SKKx ) std::cout << "Success! : Ix == SKKx" << std::endl;
    if( Iy not_eq SKKx ) std::cout << "Success! : Iy not_eq SKKx" << std::endl;
    

    return 0;
}
// https://github.com/kodxxl/CL/blob/main/SKbasis.cpp

GDB. Команда 'step' не входит в функцию., !*! Tsorion, (Отладка и профилирование) 12-Май-24, 19:37  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Здравствуйте!
Использую язык C++ и отладчик gdb. Вот исходный код:

---------------------------------------------------------------
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

pair<bool, double> CalcMedian(vector<double> samples) {
    // верните {true, медиана}, если она существует,
    // то есть вектор непустой,
    // иначе - {false, 0}
    // обратите внимание - вектор принимаем по значению,
    // так как его придётся немного подпортить, чтобы вернуть ответ
    pair<bool, double> result(false, 0);

    if (!samples.empty())
    {
        sort(samples.begin(), samples.end());
        double median = 0;
        int mid_index = samples.size() / 2;
        if (samples.size() % 2 == 0)
        {
            median = (samples[mid_index - 1] + samples[mid_index]) / 2;
        }
        else
        {
            median = samples[mid_index];
        }
        result.first = true;
        result.second = median;
    }
    return result;
}

int main() {
    int size;
    cin >> size;

    vector<double> samples;
    for (int i = 0; i < size; ++i) {
        double sample;
        cin >> sample;
        samples.push_back(sample);
    }

    pair<bool, double> result = CalcMedian(samples);
    if (result.first) {
        cout << result.second << endl;
    } else {
        cout << "Empty vector"s << endl;
    }
}
---------------------------------------------------------------

Здесь важна строчка "pair<bool, double> result = CalcMedian(samples);" в функции main(). Если, находясь на этой строчке, в gdb вызвать команду "step", то я не оказываюсь в функции CalcMedian(). Меня бросает, как я понимаю, в конструктор класса vector:

---------------------------------------------------------------
...
vector(const vector& __x)
: _Base(__x.size(),
_Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
...
---------------------------------------------------------------

Почему вызывается конструктор, я понимаю, но я хочу каким-то способом избежать этого, и сразу попасть внутрь функции CalcMedian(). Как сделать это? Только не через установку break внутри функции CalcMedian().

Компилирую так: g++ -g [имя файла]

ошибка в команде wget, !*! Chainikk, (Shell скрипты) 04-Мрт-24, 01:32  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Граждане дорогие. Не первый раз обращаюсь на Ваш спасительный форум)
Нынче бьюсь над командой получить научные данные.
Если просто запустить из адресной строки броузера, то данные мне выдаются:

https://lgdc.uml.edu/common/DIDBGetValues?ursiCode=AT138&cha... fromDate=2024%2F03%2F01+00%3A00%3A00&toDate=2024%2F03%2F02+05%3A00%3A00

Но нужен скрипт на shell, чтобы запускать автоматически.
Вставляю я во wget, но увы, в результате создается папка AT138202403f.txt с файлом "DIDBGetValues?ursiCode=AT138"

и файл этот вместо данных содержит назидательное содержимое:

To access this servlet use format: DIDBGetValues?ursiCode=CODE&charName=NAME&fromDate=yyyy.mm.dd%20(...)%20hh:mm:ss&toDate=yyyy.mm.dd%20(...)%20hh:mm:ss
For example: DIDBGetValues?ursiCode=DB049&charName=foF2&fromDate=2007.06.25%20(...)%2000:00:00&toDate=2007.06.26%20(...)%2000:00:00
or: DIDBGetValues?ursiCode=DB049&charName=foF2&fromDate=2007.06.25&toDate=2007.06.26

Пробовала как написано в файле, - результат такой же((

То есть что-то в грамматике запроса не то.

Может кто знает в чем дело??

(Мой запрос: wget -N -P /var/папка такая-то/AT138202403f.txt https://lgdc.uml.edu/common/DIDBGetValues?ursiCode=AT138&cha...)

Как предложить функциональность в ядро Linux, !*! Аноним, (Средства разработки) 27-Фев-24, 17:08  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Подскажите пожалуйста, куда писать с предложением функциональности в ядро Linux. Конкретно хочется добавить функционал в vfs fs/open.c. Сам наколеночный патч у меня есть и вроде всё работает, но его такой не примут в mainline и стыдно слать, сами они сделают круче - стеково или ещё как. Поэтому не берусь сам программировать, но идея интересная и хочется чтоб её реализовали.
Спасибо.
Подскажите, как в git такую разработку вести?, !*! КриоМух, (Контроль версий, Git, SVN, Bazaar, Mercurial) 26-Фев-24, 15:37  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Добрый день, Уважаемые!

Скажите пожалуйста, есть проект в git. В нём такое дерево файлов:

- index.html
- INSTANCE/
         - INST_1/
               - inst1.html
               .......
         - INST_2/
               - inst2.html
               .......

Как вести разработку условно общей части этого проекта в который не должны входить все директории в INSTANCE/, а эти директории были бы как отдельные подпроекты? Чтобы при клонировании общего проекта, не переносились бы данные всех подпроектов из INSTANCE/*, а их бы уже отдельно разворачивал что-то типа:
cd INSTANCE/
развернуть INST_1 # и в INSTANCE/ появилась бы вся поддиректория INST_1

Извините, что коряво, но как сумел объяснил :)

Сборка vhci_hcd для ядра 6.6, !*! Анон70, (C/C++) 03-Янв-24, 17:19  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Здравствуйте. Есть такой проект virtual usb dirver https://github.com/linuxbuh/vhci_hcd.
Он без проблем собирается на ядрах от 5.х до 6.1. Однако на 6.6 завершается ошибкой:
/home/arch/abs/testing/vhci-hcd/src/build/vhci-hcd/1.15/build/usb-vhci-iocifc.c:1072:10: error: ‘struct class’ has no member named ‘owner’
1072 |         .owner = THIS_MODULE,
      |          ^~~~~
In file included from ./include/linux/linkage.h:7,
                 from ./arch/x86/include/asm/cache.h:5,
                 from ./include/linux/cache.h:6,
                 from ./include/linux/time.h:5,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:13:
./include/linux/export.h:29:21: error: initialization of ‘const char *’ from incompatible pointer type ‘struct module *’ [-Werror=incompatible-pointer-types]
   29 | #define THIS_MODULE (&__this_module)
      |                     ^
/home/arch/abs/testing/vhci-hcd/src/build/vhci-hcd/1.15/build/usb-vhci-iocifc.c:1072:18: note: in expansion of macro ‘THIS_MODULE’
1072 |         .owner = THIS_MODULE,
      |                  ^~~~~~~~~~~
./include/linux/export.h:29:21: note: (near initialization for ‘vhci_iocifc_class.name’)
   29 | #define THIS_MODULE (&__this_module)
      |                     ^
/home/arch/abs/testing/vhci-hcd/src/build/vhci-hcd/1.15/build/usb-vhci-iocifc.c:1072:18: note: in expansion of macro ‘THIS_MODULE’
1072 |         .owner = THIS_MODULE,
      |                  ^~~~~~~~~~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: /home/arch/abs/testing/vhci-hcd/src/build/vhci-hcd/1.15/build/usb-vhci-iocifc.o] Error 1

Вот кусок кода
static struct class vhci_iocifc_class = {
    .owner = THIS_MODULE,
    .name = driver_name
};

#define CHARDEV_NAME "usb-vhci"

static struct device vhci_iocifc_device = {
    .class = &vhci_iocifc_class,
    .release = vhci_iocifc_device_release,
#ifndef NO_DEV_INIT_NAME
    .init_name = CHARDEV_NAME,
#endif
    .driver = &vhci_iocifc_driver.driver
};

Как это исправить ?

Новогодний bash, !*! pavlinux, (Shell скрипты) 22-Дек-23, 17:47  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Дано:  Текстовая строка TEXT="Happy New Year";

Вывести на консоль используя только bash:  

1. Текст в верхнем регистре  (HAPPY NEW YEAR)
2. Текст в нижнем регистре   (happy new year)
3. Текст с инвертированным регистром (hAPPY nEW yEAR)


P.S.
Примитивная долбёжка каждого символа конечно засчитается,
но это скучно и уже есть в коде самого bash.
if  ( 0x61 < с || с < 0x7A ) ля-ля-ля...  if  ( 0x41 < с || с < 0x5A ) ля-ля-ля...  

Нужно записать видео/аудио Telegram-трансляции , !*! strannik7j, (Разное) 04-Дек-23, 02:33  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Нужно написать скрипт (желательно на python) для записи видео/аудио из telegram-трансляции.
Я пытался найти ответ в документации таких библиотек, как tgcalls, pytgcalls, ntgcalls, но то ли это пока невозможно, то ли я плохо искал. А может есть другие подходящие библиотеки.
Задача Java-кодирования: особенности манипулирования датами, !*! Программирование, (Java) 28-Ноя-23, 11:16  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
В настоящее время я работаю над проектом Java, включающим манипулирование датами, и наткнулся на неожиданную проблему в своем коде. Вот упрощенная версия проблемы:


import java.text.SimpleDateFormat;
import java.util.Date;

public class DateManipulation {

    public static void main(String[] args) {
        // Attempting date manipulation
        Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String formattedDate = sdf.format(currentDate);

        // Output the formatted date
        System.out.println("Formatted Date: " + formattedDate);
    }
}

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

сборка meson 0.59 из исходников, !*! executor, (Языки программирования) 04-Окт-23, 17:22  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Кто-нибудь подскажите пожалуйста в чем у меня ошибка пытаюсь собрать meson 0.59 из исходников согласно

https://linuxfromscratch.org/lfs/view/11.0/chapter08/meson.html однако в конце система пишет что мезона нет что делать?
meson


WARNING:root:could not open file '/etc/apt/sources.list'

The program 'meson' is currently not installed. You can install it by typing:
apt install meson
/usr/share/bash-completion/completions/meson
bash: /usr/share/bash-completion/completions/meson: Permission denied

Ниже привожу листинг сборки  

sed -i "s/return 'lib32'/return 'lib'/g" /tmp/meson\-0\.59\.0/mesonbuild/mesonlib/universal.py

python3.6 /tmp/meson\-0\.59\.0/setup.py build

running build

python3.6 /tmp/meson\-0\.59\.0/setup.py install --root=dest

running install
running build
running install_data
creating dest
creating dest/usr
creating dest/usr/local
creating dest/usr/local/share
creating dest/usr/local/share/man
creating dest/usr/local/share/man/man1
copying man/meson.1 -> dest/usr/local/share/man/man1
creating dest/usr/local/share/polkit-1
creating dest/usr/local/share/polkit-1/actions
copying data/com.mesonbuild.install.policy -> dest/usr/local/share/polkit-1/actions
running install_egg_info
running egg_info
creating UNKNOWN.egg-info
writing UNKNOWN.egg-info/PKG-INFO
writing dependency_links to UNKNOWN.egg-info/dependency_links.txt
writing top-level names to UNKNOWN.egg-info/top_level.txt
writing manifest file 'UNKNOWN.egg-info/SOURCES.txt'
reading manifest file 'UNKNOWN.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no directories found matching 'test?cases'
warning: no directories found matching 'manual?tests'
warning: no files found matching '__main__.py'
writing manifest file 'UNKNOWN.egg-info/SOURCES.txt'
Copying UNKNOWN.egg-info to dest/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info
running install_scripts

cd /tmp/meson\-0\.59\.0

cp -rv dest/* /


'dest/usr/local/share/man/man1/meson.1' -> '/usr/local/share/man/man1/meson.1'
'dest/usr/local/share/polkit-1' -> '/usr/local/share/polkit-1'
'dest/usr/local/share/polkit-1/actions' -> '/usr/local/share/polkit-1/actions'
'dest/usr/local/share/polkit-1/actions/com.mesonbuild.install.policy' -> '/usr/local/share/polkit-1/actions/com.mesonbuild.install.policy'
'dest/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info' -> '/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info'
'dest/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info/SOURCES.txt' -> '/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info/SOURCES.txt'
'dest/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info/top_level.txt' -> '/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info/top_level.txt'
'dest/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info/dependency_links.txt' -> '/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info/dependency_links.txt'
'dest/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info/PKG-INFO' -> '/usr/local/lib/python3.6/site-packages/UNKNOWN-0.0.0-py3.6.egg-info/PKG-INFO'
install -vDm644 data/shell-completions/bash/meson /usr/share/bash-completion/completions/meson
'data/shell-completions/bash/meson' -> '/usr/share/bash-completion/completions/meson'
install -vDm644 data/shell-completions/zsh/_meson /usr/share/zsh/site-functions/_meson
install: creating directory '/usr/share/zsh/site-functions'
'data/shell-completions/zsh/_meson' -> '/usr/share/zsh/site-functions/_meson'

meson


WARNING:root:could not open file '/etc/apt/sources.list'

The program 'meson' is currently not installed. You can install it by typing:
apt install meson
/usr/share/bash-completion/completions/meson
bash: /usr/share/bash-completion/completions/meson: Permission denied

Что тут не так?

nasm, деление, !*! ivan, (Разное) 24-Сен-23, 08:42  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Добрый день.
Потребовалось выполнить деление на 1 со знаком.
mov eax, 0
mov ebx, 0
mov, ax, 0xc9
mov bl, 1
idiv bl
Получил исключение. Если вместо 8 битного операнда использовать 16 битовый
idiv bx
то все хорошо.
В чем причина? 0xc9 / 1 = 0xc9 и должно поместиться в al
Проблема при сборке Linux From Scratch, пакет Gettext-0.22, !*! vvm13, (Компиляция) 14-Сен-23, 13:35  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
/Надо отметить, что с C/C++ не работаю и с Linux'ом не очень дружен/

Итак, развлекаюсь со сборкой LFS в виртуалке с Fedora 32.
Всё шло более-менее хорошо, прошёл довольно далеко. И вдруг неожиданно и с размаху налетел на проблему.
Итак, https://www.linuxfromscratch.org/lfs/view/stable-systemd/cha...
Глава 8.32. Gettext-0.22.

Я получаю ошибку в
libtool: link:  gcc -shared  -fPIC -DPIC  -Wl,--whole-archive ./.libs/libgnu.a -Wl,--no-whole-archive  -lc  -g -O2   -Wl,-soname -Wl,libgettextpo.so.0 -Wl,-version-script -Wl,.libs/libgettextpo.ver -o .libs/libgettextpo.so.0.5.9
/usr/bin/ld:.libs/libgettextpo.ver:2: syntax error in VERSION script

Внутри libgettextpo.ver фигня:
[root@fedora .libs]# cat libgettextpo.ver
{ global:
local: *; };

Претензия, видимо, к тому, что после global: должен быть список external-зависимостей a la
{ global:
libgettextpo_version;
local: *; };
, но он пустой.

Формируется он на основе файла .libs/libgettextpo.exp:

libtool: link: /usr/bin/nm -B   ./.libs/libgnu.a | /usr/bin/sed -n -e 's/^.*[    ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[         ][      ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' | /usr/bin/sed '/ __gnu_lto/d' | /usr/bin/sed 's/.* //' | sort | uniq > .libs/libgettextpo.exp
libtool: link: /usr/bin/grep -E -e "^([^l]|l[^i]|li[^b]|lib[^g]|libg[^e]|libge[^t]|libget[^t]|libgett[^e]|libgette[^x]|libgettex[^t]|libgettext[^p]|libgettextp[^o]|libgettextpo[^_]|libgettextpo_version).*" ".libs/libgettextpo.exp" > ".libs/libgettextpo.expT"


Первая команда даёт непустой список:

(lfs chroot) root:/sources/src/gettext-0.22/gettext-tools/libgettextpo# /usr/bin/nm -B   ./.libs/libgnu.a | /usr/bin/sed -n -e 's/^.*[    ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[         ][      ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' | /usr/bin/sed '/ __gnu_lto/d' | /usr/bin/sed 's/.* //' | sort | uniq
libgettextpo_asnprintf
libgettextpo_printf_fetchargs
libgettextpo_printf_parse
libgettextpo_rpl_fopen
libgettextpo_vasnprintf

Но вторая его обнуляет!
libtool: link: /usr/bin/grep -E -e "^([^l]|l[^i]|li[^b]|lib[^g]|libg[^e]|libge[^t]|libget[^t]|libgett[^e]|libgette[^x]|libgettex[^t]|libgettext[^p]|libgettextp[^o]|libgettextpo[^_]|libgettextpo_version).*" ".libs/libgettextpo.exp"
даёт пустой список.

Предполагаю, что на самом деле имеется в виду вырезать всё, кроме "libgettextpo_version". Но этой строки почему-то нет.

Вот то, что я понял из происходящего. И что libgettextpo_version - это какая-то переменная в одном из C-файлов. Но что с ней не так? И ведь не сам же я писал все эти скрипты. И gcc три раза перекомпилён.

Linux + java + firebird embedded, !*! 111, (Firebird, Interbase) 13-Сен-23, 11:40  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Доброго дня, коллеги. Не знаю в какую тему писать. Уж простите.
Помогите с решением. Есть связка приложение написанное под openjdk-8 + firebird 3 embedded.
Вопрос. Это чудо совершенно спокойно работает под astra (alce-2.12.46.6-17.04.2023_15.09.iso) и под RedOS (redos-MUROM-7.3.3-20230815.0-Everything-x86_64-DVD1.iso), и вылетает с ошибкой "Unable to load library 'fbclient': Native library (linux-x86-64/libfbclient.so) not found in resource path" под ubuntu, debian, rocky. Т.е. архив с приложением и всеми конфигурациями в части firebird с "рабочей" системы переносим на "нарабочую" и получаем эту ошибку. Эксперимента ради сносилась через apt purge openjdk с астры, скачивался через apt download сам пакет openjdk, распаковывался без установки и запускалось приложение - полет нормальный. По lsof видно, что в "рабочем" варианте идет обращение к каталогу где находится libfbclient.so, в "нерабочем" - нет. Перед запуском приложения определяются переменные окружения, согласно документации на firebird
export PATH=$PATH:`pwd`/fbembed
export LD_LIBRARY_PATH=`pwd`/fbembed
export FIREBIRD=`pwd`/fbembed
Где проблема закопалась?
Чтоб не телепатить, выводы каких команд предоставить?
Заранее спасибо.

Ошибка понимания списка Python: неожиданный вывод, !*! Jeevan11, (Языки программирования) 01-Сен-23, 13:47  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Я столкнулся с неожиданным результатом при использовании понимания списка в Python. Я пытаюсь создать список квадратов значений четных чисел в заданном диапазоне, но результат не тот, который я ожидал. Вот код, который я использую:

even_numbers = [x for x in range(10) if x % 2 == 0]
squared_values = [x**2 for x in even_numbers]

print(squared_values)

Я ожидал, что результат будет [0, 4, 16, 36, 64], но вместо этого я получаю [0, 4, 16]. Кажется, что последнее четное число (8) и соответствующее ему квадратное значение (64) отсутствуют.

Может ли кто-нибудь помочь мне понять, почему это происходит и как исправить мой код понимания списка, чтобы получить желаемый результат? Есть ли что-то, что я упускаю из виду в своем подходе? Ваши идеи будут очень признательны. Спасибо!

Правка header в fasta, !*! labradorka2112, (Shell скрипты) 12-Авг-23, 12:22  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Добрый день! Вероятно, совсем простая задачка, решается многими способами, но я что-то пока не нашел подходящего.

Входные данные:
есть файл txt, в нем, в том числе, есть строки вида >NC00001 (прочее из этих строк удалено sed -r 's/xxxxx.+//' ) файл.ext
Таких строк 5572 штуки (всего строк в файле существенно больше), т.е. имеем диапазон строк указанного вида >NC00001 - >NC05572, между которыми другие строки. Количество других строк между целевыми строками вида >NC00001 рандомное, но уменьшается к концу файла.

Задача:
получить уникальные числа после константного тэга >NC, так чтобы строка вида >NC****** встечались только один раз в файле )

Условия: 1) нужно чтобы в числовой части строки присутствовало не более одной цифры 0
         2) В подстановке допустимы только цифры, не более 5-6 знаков(цифр) после >NC.
         3) Могут быть в порядке возрастания
         3) нужна проверка вхождения, т.е. что каждый из полученных идентификаторов уникален.
         4) решить на bash, можно и python

Что нашел: если вместо 0000 тупо клеить какие-нибудь числа, с учетом количества строк,очевидно, возникают повторы.
Рассматриваю sed, rev, tac, seq, grep, uniq
Из любопытного, но пока не разобрался : cut -d'' -f1|sort|uniq-c|grep -Ev'^[[:space:]]+1[[:space:]]'

Код нейронной сети, !*! BuxarNET, (Библиотеки, функции) 12-Авг-23, 04:32  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Есть ли в открытом доступе код нейронной сети?

Есть несколько проектов

1. Нужно нейронку научить русскому языку - в частности грамматике, что бы из слов могла и корни определять и речевые обороты строить и т.п.

2. Нужно нейронку научить анализировать фото и 100% разпознавать разновидность растений.

Может уже и готовые есть подобные решения с открытым кодом?

Форвардинг/проксирование TCP/UDP пакетов , !*! akahan, (Rust) 11-Авг-23, 16:44  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Привет всем. Не уверен в каком именно разделе нужно разместить, но суть в сетевом программировании. Это мой первый опыт в таком программировании, поэтому не ругайте, если что))

Я пишу связку ПО реализующую VPN на основе WireGuard с конечным выходом пакетов в интернет через удаленную программу (далее прокси) и обратно.

Общими словами, есть 3 устройства. Клиент, сервер и прокси. На сервере WireGuard интерфейс слушает на UDP порту подключения от клиентов и от прокси. Создает с ними одну сеть.

В целом, средствами обычных конфигов WireGuard это реализуется как тут https://habr.com/ru/companies/xakep/articles/699000/. Все работает. Но в своей реализации я застрял с прокси.
В статье с хабра прокси - это сервер с конфигом wg-external.conf. Там есть выполнение PostUp сркрипта с настройкой iptables, но это не нужно, так как связка работает и без этого правила.

Я пишу код на rust, реализовал сетевой стек в юзер-спейс (smoltcp). Юзерспейс - это важно. Получаю на прокси расшифрованные пакеты с сервера WireGuard. Не понимаю как мне проксировать их в интернет и отдавать обратно на сервер с последующей передачей ответов клиенту обратно.  

Я понимаю, что нужно подменять адреса получателя в IP-пакетах, но как их отправлять в интернет и потом передавать обратно в WireGuard? Нет четкого понимания - застрял. Кто понимает о чем речь укажите направление, подскажите, что нужно сделать, чтобы реализовать мою связку?

Проблема обмена данными через виртуальный USB-com порт, !*! EdiRu, (C/C++) 02-Авг-23, 17:31  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Добрый день! Жизнь заставила переходить с виндов на Linux, столкнулся с проблемой: работаю с железкой по USB через виртуальный ком-порт в Qt Creator. В консольном приложении всё идет на "ура", так же если делаю библиотеку и вызываю через консольное приложение - железка получает команды и отвечает как надо. Попытка использования оконного приложения или "даблклика" по файлу консольного приложения без запуска терминала приводит к тому, что функция read, возвращая нужное количество прочитанной информации, возвращает массив заполненный нулевыми значениями (0х00). Пробовал менять тип массива с char на wchar_t, все равно и старшие и младшие байты нули. Может кто чего подскажет? Примерная последовательность действий:

    int fd = open("/dev/ttyACM0", O_RDWR);
    if (fd < 0) { // обработка ошибок сокращена    }
    fcntl(fd, F_SETFL, 0);
    struct termios oldsettings, newsettings;
    tcgetattr(fileno(stdin), &oldsettings);
    newsettings = oldsettings;
    cfsetospeed(&newsettings, B4000000);
    cfsetispeed(&newsettings, B4000000);
    newsettings.c_lflag &= ~(PARENB|CSTOP|CSIZE);
    newsettings.c_lflag |= CS8;
    newsettings.c_cc[VMIN] = 0;
    newsettings.c_cc[VTIME] = 10;
    newsettings.c_ispeed = 12000000;
    newsettings.c_ospeed = 12000000;
    if (tcsetattr(fd, TCSANOW, &newsettings) < 0) {// обработка ошибок сокращена }

    char buf[50];
    char bufin[2048];
    tcflush(fd, TCIOFLUSH);
    int rP, crd;
// заполнение буфера сокращено, rP=длина буфера
    int cnt = write(fd, &buf, rP);
// обработка ошибок сокращена
    timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 100000;
    fd_set fs;
    FD_ZERO(&fs);
    FD_SET(fd, &fs);
    int res = select(fd+1, &fs, NULL, NULL, &timeout);
    if(res==0) {// обработка ошибок сокращена }
    else if(res<0) {// обработка ошибок сокращена }
    else if(FD_ISSET(fd, &fs))
    {
       memset(bufin, 0x00, sizeof(bufin));
       crd = 20; // устанавливаем с запасом, т.к. заранее не знаем, сколько придет
       cnt = read(fd,&bufin,crd);
// cnt = 19 - пришло сколько нужно, bufin[0] = 0x00, bufin[1] = 0x00 и т.д.

Организация boot сектора Compact Flash (Unix-like System), !*! SergeKS, (Отладка и профилирование) 31-Июл-23, 10:18  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Здравствуйте!

Промышленное оборудование управляется ПК на котором стоит операционная система реального времени (ОСРВ) VxWorks.

Жесткий диск ПК представляет собой Compact Flash (CF).

CF отказала. Купили новую. Завод производитель прислал файлы которые должны быть на этой CF но не в виде образа а в виде архива *.zip.

Простым копированием естественно ОСРВ не стартует.

Нужна геометрия CF.

Подскажите пожалуйста располагает ли кто ни будь информацией о геометрии CF для VxWorks?

Спасибо!  

Как экранировать символы гравис и $ в переменной с помощью sed, !*! Владимир, (Shell скрипты) 19-Июл-23, 11:13  [ | | | ] [линейный вид] [смотреть все] [раскрыть новое]
Добрый день!
есть переменная a, в  которой предполагается хранить команды shell любой сложности для последующей записи этой команды в БД. Для этого мне нужно экранировать все спецсимволы $, чтобы bash не обрабатывал конструкцию $(..), которая будет возвращать результат выполнения команды.
Я думаю решить эту задачу с помощью sed, как указано в скрипте:

#!/bin/bash
a="for personal in $(/bin/awk -F":" '{ if ( $5 ~ /Admin / && $3 > 100 ) print $1 }' /etc/passwd); do passwd -S $personal;done"
b=$(sed 's,$,\\$,g' <<< $a)
echo $b

Но результат получается не тот, который я ожидал:  
for personal in user1\$ user2\$ user3;do passwd -S ;done\$
Очевидно сработала обработка bash подстановки команды.

Если бы я в строке руками экранировал все символы $:
#!/bin/bash
a="for personal in \$(/bin/awk -F":" '{ if ( \$5 ~ /Admin / && \$3 > 100 ) print \$1 }' /etc/passwd); do passwd -S \$personal;done"
echo $a

То результат был бы правильным:
for personal in $(/bin/awk -F":" '{ if ( $5 ~ /Admin / && $3 > 100 ) print $1 }' /etc/passwd); do passwd -S $personal;done

Видимо, что-то я не так делаю в команде sed. Если есть идеи, буду очень признателен.

 
Пометить прочитанным Создать тему
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Архив | Избранное | Мое | Новое | | |



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру