• Не удается запустить автотест на Cucumber+Selenid, запускаю впервые, что делаю не так?

    3vi1_0n3
    @3vi1_0n3
    Ошибка не имеет отношения ко всему этому коду.
    Обновите хромдрайвер до версии, которая поддерживает вашу версию браузера.
    Ответ написан
  • Какой выбрать легкий и простой дистрибутив Linux для серфинга интернета?

    3vi1_0n3
    @3vi1_0n3
    Буду оригинален. Если основная задача - интернет-браузинг, то может что-то вроде ChromeOS Flex?
    Вроде где-то видел, что туда уже завезли Linux окружение как во взрослом ChromeOS.
    И сделано оно вроде на Дебиане.
    Ответ написан
    Комментировать
  • Почему после компиляции своего ядра linux его размер в разы больше?

    3vi1_0n3
    @3vi1_0n3
    Собирал свежие ядра пару лет под Дебиан, пока поддержку некоторого железа в пакетном не завезли через два релиза, потом перестал. Там очень много непонятного между пакетными ядрами и сборкой из исходников.
    Несколько примеров:
    1. По умолчанию куча новых модулей (не входящих в старые версии) включена. Если использовать конфиг от старого ядра, новые модули может понадобиться отключать руками.
    2. По умолчанию куча модулей для старого железа включена.
    3. Есть шанс, что определенные модули идут в разных пакетах и не входят в дженерик в дистрибутивных сборках, либо исключены совсем. Из сырцов вы получите всё, вообще всё, что есть в исходниках, либо в модулях, либо в основном ядре, если специально не отключать, в том числе кучу старых девайсов, которых у вас скорее всего нет, или платы видеозахвата, которые вам, например, не нужны.
    4. Если хотите собрать ядро поменьше, придется внимательно читать информацию по железу и тратить реально дофига времени на то, чтобы оставить в монолитном куске только то, что нужно, включая все зависимости, остальное либо собирать модулями, либо отключать совсем.
    5. Можно поотключать вообще всё и постепенно включать то, что имеет смысл. Грузиться нормально скорее всего сразу не будет, но по ошибкам обычно можно примерно понять куда копать.

    Разобраться с этим списком быстро не будет. Можно взять конфиг из пакетного ядра, и начать копать от него, в любом случае это вопрос количества попыток, опыта и уровня понимания что там зачем. Scheduler, например. Есть возможность выбрать один из поддерживаемых, но надо знать, что это такое, и различия между ними. Где-то видел
    статью про планировщики, возможно на хабре.

    Я обычно собирал реально только то, что использовал, преемптивное ядро, плюс USB-устройства выборочно (клавы-мыши в монолит, то, что потенциально могу использовать - в модули), плюс поддержку в ядре файловых систем выборочно (одну, которая используется на корневом разделе, в монолит) и так далее. И после успешной загрузки проходил еще несколько раз и смотрел, что я могу еще отключить совсем, чтобы не собирать ненужное. Занимает обычно лютое количество времени, чтобы найти, прочитать и понять что там что, и довести до состояния "только необходимое плюс немного на перспективу". Собственно поэтому бросил этим страдать сразу как дистрибутивное ядро в пакетах проапдейтилось до нужной версии.

    В плане как собирать, пакетом или через make - пакетом скорее всего удалится чище, руками не надо удалять ничего, и по размеру пакета можно оценить размер сборки сразу. Хотя это и так несложно, всё лежит в известных местах.

    Руководства, которое объясняет, что надо, а что не надо, не видел никогда. Скорее всего потому, что всё очень быстро меняется, за полгода в ядро вливают кучу кода. Это было заметно даже во времена версий 2.4/2.6.
    Поэтому make menuconfig и гуглить непонятное.
    Ответ написан
    2 комментария
  • Как в bash создать динамический select?

    3vi1_0n3
    @3vi1_0n3
    Исходя из описания задачи вот так:
    #!/bin/bash
    
    select site in $(jq -r '.sites[].title' sites.json) 
    do
        select area in "admin" "front"
        do
            # get links for "area"
            links=$(jq '.sites[] | select(.title == "'${site}'") | .'${area}' |.[]' sites.json)
            # here you can do whatever you want - iterate through links, opening them with xdg-open, or just print them out
            echo $links
            break
        done
        break;
    done

    Если это не то, что надо, уточните описание.

    Если надо динамически брать набор ключей с исключением "title", то
    select area in "admin" "front"
    заменить на
    select area in $(jq -r '.sites[] | select(.title == "'${site}'") | keys | .[] | select(. != "title")' sites.json)
    Ответ написан
    1 комментарий
  • Как написать bash мониторинг файловой системы EXT4?

    3vi1_0n3
    @3vi1_0n3
    Тут уже много интересного написали. Штука только в том, что в вопросе недостаточно информации, что не позволяет эту задачу решить эффективно. Есть вопросы, на которые надо ответить, прежде чем приступать:

    1. Где хранятся эти файлы, которые могут потенциально вырасти до таких размеров и сколько их?
    Если они хранятся в одной директории, тогда смысла делать поиск по всей системе нет. На моем десктопе с 500К файлов поиск занимает примерно 9.5 секунд с полным сканированием дерева файловой системы. Если файлов потенциально пара сотен, и они все в одной директории или в поддереве директорий, время поиска можно сильно сократить. Я подозреваю, что find читает информацию о размере из inode'ов, поэтому количество файлов играет значительную роль.

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

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

    Про inotify там выше уже дали ссылку на мою статью 2016 года. Это на самом деле самый лучший вариант, если надо сразу знать об изменениях файлов, и самый удобный. Вот только он может вполне быть "из пушки по воробьям", если вам не надо прямо сразу узнавать о событиях файловой системы и обрабатывать их, а достаточно периодических проверок (с учетом вопросов выше).

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

    Учитывая, что вы хотите это сделать через bash, я бы сначала посчитал, сколько подобных событий (увеличение размера файлов до 16+Тб) происходит и попробовал оптимизировать поиск таких файлов за счет отсекания ненужного поиска (специфическая директория, фильтрация по типу файлов, имени и прочее).

    Если файлы имеют какую-то одинаковую часть имени, можно использовать locate (вместо find) для получения списка файлов, и потом передавайте его в скрипт, который тупо проверит размер каждого (через stat, например). В этом случае надо при появлении новых файлов не забывать вызвать updatedb, если это не происходит автоматически по какой-то причине.

    Как-то так. Посмотрел другие ваши вопросы. Некоторым из них чуть больше контекста тоже не помешало бы.

    P.S. updatedb делает то же самое примерно, что и find, поэтому не надо его вызывать каждый раз перед использованием locate
    Ответ написан
    Комментировать
  • Как увеличить размер памяти флешки в угоду её длительности жизни при помощи команды devicehigh или loadhigh?

    3vi1_0n3
    @3vi1_0n3
    Хехе. Я думаю препод большой шутник, если так завуалировал DBLSPACE, который можно загрузить в верхнюю память в том числе
    Ответ написан
    2 комментария
  • Как правильно подменить (скопировать) скрипта в самом скрипте?

    3vi1_0n3
    @3vi1_0n3
    Заменять скрипт в /etc/init.d из самого себя не очень правильная идея.
    Да, заменить или модифицировать скрипт из самого себя можно, но, по идее, скрипты для запуска сервисов/демонов не должны модифицироваться напрямую, желательно только с новой версией пакета (если он есть).
    Даже я бы так не стал делать, хотя я тот еще нетрадиционный баш-скриптер.

    Если вам прям очень надо именно заменять сам скрипт по условию, то лучше это делать так:
    1. Вызываем /etc/init.d/medteco.sh
    2. Скрипт /etc/init.d/medteco.sh проверяет наличие скрипта на флэшке
    3. Скрипт /etc/init.d/medteco.sh проверяет целостность скрипта на флэшке
    4. Если скрипт существует и проверка целостности проходит, копируем на диск под другим именем, проверяем целостность еще раз. Контрольную сумму можно заранее посчитать тем же md5 и положить в файл рядом с новым скриптом.
    5. Если шаг 4 успешен, удаляем/переименовываем старый скрипт (тот, который не /etc/init.d/medteco.sh, а старая версия скрипта с флэшки), переименовываем новый скрипт в старый.
    6. Безусловно выполняем/source'им тот самый скрипт, передавая ему параметры при необходимости. В этом случае у вас будет вызвана либо старая рабочая версия, либо новая рабочая версия.

    Скрипт /etc/init.d/medteco.sh затронут не будет (и не должен), он будет нужен для обработки ошибок и т.д., чтобы контролировать процесс независимо от его результата. Если прямо очень надо, чтобы старая версия не запускалась, бросаем ошибку и прерываем выполнение скрипта.

    Альтернативный вариант: собираем пакет, который будет устанавливаться в систему, устанавливаем его прямо с флэшки. Пакетный менеджер прервет установку, если пакет поврежден и не должен заменить рабочую версию в теории.
    Ответ написан
    Комментировать
  • Сравнить файлы и удалить совпадения по первым 7 символам?

    3vi1_0n3
    @3vi1_0n3
    На баше как-то так (минимум внешних команд, от cat можно избавиться, если использовать exec):
    #!/bin/bash
    
    octets=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
    
    addrtobin(){
        for digit in ${1//./ }; do echo -n ${octets[digit]}; done
    }
    
    # Просто пример для списков адресов и сетей.
    # Лучше используйте exec N<>filename.txt + read -u N
    ips=$(cat ips.txt)
    nets=$(cat nets.txt)
    
    for ip in $ips
    do
        out=1
        bin_ip=$(addrtobin $ip)
        for net in $nets
        do
            bin_net=$(addrtobin ${net%%/*})
            net_mask=${net#*/}
            if [ "${bin_ip:1:$net_mask}" == "${bin_net:1:$net_mask}" ]
            then
                out=0
                break # Чтобы не проходить до конца списка сетей, если адрес уже найден
            fi
        done
        [ $out -eq 1 ] && echo $ip
    done


    К сожалению, придется делать двойной цикл. К счастью, можно не прогонять внутренний цикл до конца, если совпадение найдено, поэтому будет самую малость быстрее.
    Ответ написан
    Комментировать
  • Можно ли под Windows 7 установить по приложениям ограничения - приоритет либо максимальное значение скорости операций чтения/записи на диск?

    3vi1_0n3
    @3vi1_0n3
    Попробуйте Process Explorer отсюда - https://learn.microsoft.com/en-au/sysinternals/dow...
    Он вроде бы умеет приоритет на I/O.
    Точнее он умеет в Background приоритет, что влияет в том числе на I/O
    Ответ написан
    Комментировать
  • Night Light(Режим для чтения) как устанвоить на manjaro с i3wm?

    3vi1_0n3
    @3vi1_0n3
    Ну, например так, как описано в арч вики - https://wiki.archlinux.org/title/Redshift
    Ответ написан
    Комментировать
  • Почему не могу зайти на сайт по ip, только по имени?

    3vi1_0n3
    @3vi1_0n3
    Это значит, что дефолтный сайт и тот, который использует имя - это могут быть разные сайты.
    Сайт с именем настроен, а дефолтный либо не настроен, либо настроен неправильно.
    Например, в конфигах nginx есть секция server, в которой указывается server_name и является ли он дефолтным.
    Если вы не передаете заголовок "Host: randomname", то не факт, что соединение будет с тем самым сервером.
    Как можно проверить, какой сертификат отдается - попробовать openssl:
    openssl s_client -showcerts -connect 10.255.0.20:4005

    Если вы получите TLS-сертификат сервера, значит на уровне SSL/TLS соединение устанавливается и дело в настройках самого сервера.
    Ответ написан
    2 комментария
  • Как ускорить sql запрос?

    3vi1_0n3
    @3vi1_0n3
    Выглядит достаточно плохо, но, мне кажется, я понимаю, какая у вас структура данных в базе плюс-минус.
    Самый простой вариант оптимизации для начала:
    SELECT t1.sum_za_zakazy AS sum_za_zakazy,  t2 .......
    
    FROM ( SELECT COALESCE (sum(v2.meta_value),0) AS sum_za_zakazy
           FROM wp_posts
           JOIN wp_postmeta v1 ON (wp_posts.ID = v1.post_id)
           JOIN wp_postmeta v3 ON (wp_posts.ID = v3.post_id)
           JOIN wp_postmeta v2 ON (wp_posts.ID = v2.post_id)
    WHERE wp_posts.post_type='zakazy'
    AND wp_posts.post_status='publish'
    AND v1.meta_value = '%current_field|id_uchastnika%'
    AND v3.meta_value
        BETWEEN '%current_field|data_1%' AND '%current_field|data_2%'
    AND (
       (v1.meta_key = 'id_shvei_1'           AND v2.meta_key = 'summa_shvei_1'           AND v3.meta_key = 'shveia-1-data')
    OR (v1.meta_key = 'id_shvei_2'           AND v2.meta_key = 'summa_shvei_2'           AND v3.meta_key = 'shveia-2-data')
    OR (v1.meta_key = 'id_shvei_3'           AND v2.meta_key = 'summa_shvei_3'           AND v3.meta_key = 'shveia-3-data')
    OR (v1.meta_key = 'id_razborshhika_1'    AND v2.meta_key = 'summa_razborshhika_1'    AND v3.meta_key = 'razborshchik-1-data')
    OR (v1.meta_key = 'id_razborshhika_2'    AND v2.meta_key = 'summa_razborshhika_2'    AND v3.meta_key = 'razborshchik-2-data')
    OR (v1.meta_key = 'id_sborshhika_1'      AND v2.meta_key = 'summa_sborshhika_1'      AND v3.meta_key = 'sborshchik-1-data')
    OR (v1.meta_key = 'id_sborshhika_2'      AND v2.meta_key = 'summa_sborshhika_2'      AND v3.meta_key = 'sborshchik-2-data')
    OR (v1.meta_key = 'id_sborshhika_3'      AND v2.meta_key = 'summa_sborshhika_3'      AND v3.meta_key = 'sborshchik-3-data')
    OR (v1.meta_key = 'id_dostavki_v_czeh'   AND v2.meta_key = 'czena_dostavki_v_czeh'   AND v3.meta_key = 'data-zabora')
    OR (v1.meta_key = 'id_dostavki_iz_czeha' AND v2.meta_key = 'czena_dostavki_iz_czeha' AND v3.meta_key = 'data-dostavki')
    OR (v1.meta_key = 'id_menedzhera'        AND v2.meta_key = 'summa_menedzhera'        AND v3.meta_key = 'data-zakaza')
    )) t1
    
    CROSS JOIN( SELECT COALESCE (sum(v2.meta_value),0) AS ....... t2


    Так хотя бы более понятно.
    Все общие условия выносите в начало. Всё, что используется всегда, для всех комбинаций ключей.
    Я поменял порядок джоинов (v2 и v3), на случай, если планировщик не додумается, в каком порядке фильтровать, хотя я не уверен, что это будет проблемой, но планировщики не всегда работают умно, иногда надо подсказывать. По дефолту JOIN в MySQL, если правильно помню, INNER, поэтому в теории можно подрезать набор данных слева таким образом.
    Вот после этого попробуйте, сравните время запроса и результат с тем, что до, и потом используйте EXPLAIN <ваш запрос>. Есть вероятность, что внутренний SELECT выполняется для каждой записи.
    На поля wp_posts.post_type и wp_posts.post_status можно будет потом (при необходимости) сделать индексы, если их еще нет (можно комбинированный).
    На wp_postmeta.meta_key исходя из полученной картины можно будет сделать индекс, если его еще нет, как и на wp_postmeta.meta_value, хотя я бы ожидал, честно говоря, что они уже есть.
    Просто так индексы создавать не надо, только при необходимости.
    Ответ написан
    2 комментария
  • Не могу отловить процесс нагружающий Linux процессор?

    3vi1_0n3
    @3vi1_0n3
    Можно попробовать atop. Он умеет собирать статистику, и ее потом можно просматривать. Ну, и в интерактивном режиме умеет. Должен быть в стандартных репозиториях.
    Единственное надо будет задать интервал сбора метрик покороче, если хочется поймать краткие всплески.
    Ответ написан
    Комментировать
  • Selenium nodejs android и парсинг?

    3vi1_0n3
    @3vi1_0n3
    Есть некоторая вероятность, что пакеты, которые работают с chromedriver, используют нативные бинарники, которые тянут сами (во время установки пакета, например). Не для всего эти бинарники есть под не-Интел архитектуры.
    Например, локальный запуск chromedriver'а может не сработать, потому что нет chromedriver'а под архитектуру вашего телефона. Под нее в теории может быть chromium-driver (который делает ровно то же самое), но не факт, что он есть для termux в принципе. Для других linux-дистрибутивов он может быть скомпилирован майнтейнерами дистрибутива.
    Тут может быть более одной проблемы, недостаточно информации, чтобы сказать точнее. А именно: что используется в скриптах в качестве эндпоинта для селениума, локальный URL или удаленный, какие именно пакеты ставятся для работы с Selenium, тянут ли они свой бинарь для вебдрайвера и так далее.
    Ответ написан
    Комментировать
  • Какие программы есть для автоматизации действий в веб браузере?

    3vi1_0n3
    @3vi1_0n3
    Посмотрите Ссылка удалена модератором. Selenium IDE. Похоже на то, что надо?
    Ответ написан
    1 комментарий
  • Как разобрать данные ssl записи для домена?

    3vi1_0n3
    @3vi1_0n3
    Вот так скачать все одной командой:
    echo "" | openssl s_client -showcerts -connect d.codeartifact.eu-north-1.amazonaws.com:443 | sed -ne '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > certs.txt


    Если сертификат самого сервера не нужен, то можно его удалить из этого файла (certs.txt), но я, честно говоря, оставил бы, если вам надо проверять аутентичность соединения именно с этим доменом.
    Ответ написан
  • Selenium или что другое?

    3vi1_0n3
    @3vi1_0n3
    Из своего опыта с селениумом подозреваю, что в какие-то моменты элемент DOM может там уже не быть, когда вы пытаетесь его использовать, это одна из проблем, которые вылезают в селениуме на динамических приложениях, в частности на многих SPA на реакте.

    Это из-за того, что визуально сам веб-элемент как бы не изменился, но на самом деле это уже вообще не тот элемент, даже если локатор совпадает. При поиске элемента по локатору возвращается element id (выглядит как UUID) этого элемента, с которым и происходят операции. Если дерево было перестроено после получения element id, то возникает ошибка поиска этого элемента, чтобы осуществить над ним действие.

    Обычно может помочь получать элемент по локатору прямо перед его использованием (типа find_element().click()), либо ждать, пока обновления закончатся и как-то это определять. Сам selenium не ждет, пока обновление всего DOM закончится окончательно (хотя у него и есть таймаут поиска), так что над этим придется поэкспериментировать, чтобы определять, что в момент действия вероятность обновления либо нулевая, либо низкая. Его, собственно, многие за это и не любят, хотя при правильном понимании и приготовлении (что обычно занимает время), он может быть очень стабильным.

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

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

    3vi1_0n3
    @3vi1_0n3
    Тут больше, чем один вариант на самом деле.
    1. В Mint'е был баг с похожими симптомами, когда установлено больше одного графического окружения. Если это тот вариант, то переключиться через Alt+2 или Ctrl+Alt+2 в терминал, удалить второе графическое окружение и перезагрузиться
    2. Есть вариант, что что-то не так в файловой системой. Тут тоже переключиться в терминал, попробовать fsck. Если вдруг проблемы найдены, но не может починить, может потребоваться переключиться в другой уровень загрузки (init 3 или типа того, не готов сказать, что там в минте)
    3. Есть вариант, что какие-то файлы повреждены, можно попробовать переустановить графическое окружение. Так же в терминал, и там "apt reinstall <название пакета, через который ставится графическое окружение>".

    Можно посмотреть в логах, есть ли ошибки (если есть такие логи):
    1. /var/log/Xorg.0.log
    2. /var/log/messages
    3. /var/log/syslog
    4. /var/log/kern.log
    5. /var/log/user.log
    Больше по этой информации тяжело сказать, без логов и прочего.

    P.S. Обновить пакеты пробовали?
    P.P.S. Могут быть еще проблемы с драйверами видеокарты потенциально.
    Ответ написан
    Комментировать
  • Линукс. Есть ли способ заполнять пути в консоли из файлового менеджера?

    3vi1_0n3
    @3vi1_0n3
    Если я правильно понимаю задачу, может быть можно обойтись без файлового менеджера?
    Вот так, например:
    alias get='dialog --erase-on-exit --fselect $PWD 30 100 --stdout'
    cp $(get) $(get)

    Тут для каждого вызова $(get) будет отдельный выбор файла в текстовом, гуй с иксами не нужен. По пробелу выбор директории из списка, при наборе символов установка курсора на директорию, которая подпадает под введенный текст.
    Но есть нюансы.
    1. Интерфейс слегка своеобразный, надо попривыкнуть.
    2. Очистка экрана, если --erase-on-exit есть, и остатки текстовых окон на экране, если --erase-on-exit нет.
    3. Сразу вставит в команду, без помещения в командную строку значения
    Ответ написан
    Комментировать
  • Почему не отрабатывает exit на третьем уровне скрипта?

    3vi1_0n3
    @3vi1_0n3
    Я могу предположить, что такая структура скриптов призвана обеспечить определенную независимость каждого подменю. Если брать ровно те скрипты, которые у вас есть, то:
    1. Добавляем код возрата в функцию PMI - просто добавляем строчку "return $g" после "esac". Это не сломает существующий скрипт. Но! Придется разбираться с ошибками выполнения вызовов IPMI меню отдельно.
    2. Проверяем код возврата в unem
    read b
            case $b in
              1) clear ; ./1_1_system_menu.sh && exit; unem ;;
              2) clear; ./1_1_ipmi_menu.sh && exit; unem ;;
              3) clear ; menu ;;
              0) exit 0 ;;
            esac

    " && exit" здесь выполнится, если скрипт возвращает 0, что и произойдет, если PMI() вернет 0. Соответственно, при выборе любого другого варианта выхода не будет.

    Однако, несмотря на то, что с такими минимальными изменениями оно может работать как надо, все-таки имеет смысл сделать так, как jcmvbkbc уже упомянул - не исполнять скрипты, а включать их. Я не согласен по поводу места в скрипте, куда их включать, я бы поставил source до определения функции unem.
    И я лично сделал бы это несколько по-другому. Как-то так:

    menu.sh
    #!/bin/bash
    
    # Insert necessary sub-menus
    . ./ipmi_menu.sh
    
    declare -A MAINITEMS
    MAINITEMS['System settings']="echo 'System settings selected'"
    MAINITEMS['Ipmi tools']="PMI"
    MAINITEMS['Back to previous']="break"
    MAINITEMS['Exit']="exit"
    
    while :
    do
      select menuitem in "${!MAINITEMS[@]}"
      do
        echo "Menu item: $menuitem"
        ${MAINITEMS[$menuitem]}
      done
    done

    ipmi_menu.sh
    #!/bin/bash
    
    PMI(){
    echo "PMI functions"
    
    PMI_TITLES=(\
            "Sensors check" \
            "Writing Motherboard FRU information"\
            "Writing MAC address  BMC"\
            "Wtiting MAC address Motherboard"\
            "Back to previous"\
            "Exit")
    PMIITEMS[1]="echo Sensors check"
    PMIITEMS[2]="echo fru information"
    PMIITEMS[3]="echo mac address"
    PMIITEMS[4]="echo mac address motherboard"
    PMIITEMS[5]="break"
    PMIITEMS[6]="exit"
    
    select pmiitem in "${PMI_TITLES[@]}"
    do
      ${PMIITEMS[$REPLY]}
    done
    }


    В menu.sh я использую associative array, это сильно упрощает добавление элементов в главное меню.

    В ipmi_menu.sh я использую обычный массив, чтобы соблюсти порядок пунктов меню. Тут PMIITEMS[XXX] будет просто имя функции, содержащейся в файле ipmi_menu.sh

    В этом примитивном варианте экран не очищается и перерисовка пунктов текущего меню происходит по нажатию ENTER, зато это должно (по идее) работать в любом, даже самом тупом терминале. Если надо красоты, можно select поменять на echo+read, смысл от этого не поменяется, все равно можно брать список функций из массива.
    Ответ написан
    Комментировать