Nano Hash - криптовалюты, майнинг, программирование

Изменение переменной в функции в зависимости от флага getopts bash

У меня есть сценарий bash, который находит подключенные устройства и записывает вывод последовательного порта в файл. Я использую getopts для выбора метода ведения журнала. Две функции одинаковы, за исключением одной строки. Я хотел бы изменить его на одну функцию с переменной для одной строки, которая отличается (моя попытка ниже), но не добилась успеха. Как я могу сделать это с помощью getopts? Большое спасибо.

#!/bin/bash
#script to capture camera serial port logs via usb or UART.

file_name='DashcamLog'
#Date e.g: 20210204T120159 (ISO 8601)
current_date=$(date +%Y%m%dT%H%M%S)
BAUDRATE='115200'
#change to reflect udev rules e.g /dev/h1*
BOARDS=(/dev/ttyUSB* /dev/ttyACM*)
screen="$(screen -Sdm $port_name -L -Logfile $new_file_name $i $BAUDRATE)"
minicom="$(screen -Sdm ${port_name} minicom -b ${BAUDRATE} -D ${i} -C ${new_file_name})"

usage() {
    echo "Usage:"
    echo "Use $0 -a to use GNU screen to automatically capture logs on USB plug in"
    echo "Use $0 -s to use GNU screen to capture logs WITHOUT automatic capture on USB plug in."
    echo "Use $0 -m to use minicom to capture logs WITHOUT automatic capture on USB plug in."

}

#detects current + new devices + automatically starts logging
autoStartLog() {

    while true;do

        current_date=$(date +%Y%m%dT%H%M%S)

        for i in $BOARDS; do

            port_name=${i#/dev/}

            if ! screen -ls | grep -o $port_name > /dev/null;then
                (
                    serial_no="$(udevadm info --attribute-walk $i | grep -m 1 ATTRS{serial})"
                    #file name e.g = DashcamLog_20210208T094013_peri_h1p1.log
                    new_file_name="${file_name}_${current_date}_${HOSTNAME}_${port_name}.log"
                    $screen
                    echo $port_name 'serial_no: ' $serial_no $new_file_name
                )
            fi

        done

    done

}

#detects current devices + starts logging using screen(-s)/minicom(-m)
startLog() {

    for i in $BOARDS; do
        (
            port_name=${i#/dev/}
            serial_no="$(udevadm info --attribute-walk $i | grep -m 1 ATTRS{serial})"
            new_file_name="${file_name}_${current_date}_${HOSTNAME}_${port_name}.log"
            $1
            echo $port_name 'serial_no: ' $serial_no $new_file_name
        )
    done

}


while getopts ":hmsa" opt; do
    case ${opt} in
        h)
          usage
          ;;

        a)
          autoStartLog
          ;;

        s)
          startLog $screen
          ;;

        m)
          startLog $minicom
          ;;

        \? )
          echo "Invalid Option: -$OPTARG" 1>&2
          usage
          exit 1
          ;;
    esac
done
shift $((OPTIND -1))
08.02.2021

  • Какая линия? Если я смотрю autoStartlog и startLog, то они отличаются не более чем на 1 строчку. Детали необходимы для того, чтобы мы могли понять ваш вопрос. Это while true в autoStartLog? Если это так, вы можете создать третью функцию, которая выполняет обработку. В autoStartLog выполните while и вызовите эту 3-ю функцию. В startLog вы просто вызываете третью функцию один раз. К вашему сведению, вам не нужны ( ) вокруг блоков if или for. do и done достаточно. 09.02.2021
  • Спасибо за быстрый ответ и подсказку про скобки. Я пытаюсь изменить $1 в startLog, чтобы в зависимости от выбранной опции он начинал ведение журнала с использованием разных методов, например. ./log.sh -s вызывает startLog и использует screen для регистрации, а ./log.sh -m вызывает startLog и использует minicom для регистрации. 10.02.2021

Ответы:


1

Я изменил пару вещей, потому что понял, что объяснять все мелкие детали в комментариях будет слишком долго.

Вот код:

#!/bin/bash

#script to capture camera serial port logs via usb or UART.

file_name='DashcamLog'
#Date e.g: 20210204T120159 (ISO 8601)
current_date=$(date +%Y%m%dT%H%M%S)
BAUDRATE='115200'
#change to reflect udev rules e.g /dev/h1*
BOARDS=(/dev/ttyUSB* /dev/ttyACM*)

usage()
{
    echo "Usage:"
    echo "Use $0 -a to use GNU screen to automatically capture logs on USB plug in"
    echo "Use $0 -s to use GNU screen to capture logs WITHOUT automatic capture on USB plug in."
    echo "Use $0 -m to use minicom to capture logs WITHOUT automatic capture on USB plug in."
    exit 1
}

#detects current devices + starts logging using screen(-s)/minicom(-m)
startLog()
{
    for i in "${BOARDS[@]}"
    do
        port_name="${i#/dev/}"
        serial_no=$(udevadm info --attribute-walk "$i" | grep -m 1 "ATTRS{serial}")
        new_file_name="${file_name}_${current_date}_${HOSTNAME}_${port_name}.log"
        case "$1" in
            "screen")
                echo "PUT THE SCREEN COMMAND HERE"
                ;;
            "minicom")
                echo "PUT THE MINICOM COMMAND HERE"
                ;;
            \?)
                echo "Invalid Option: -$OPTARG" 1>&2
                usage
                ;;
        esac
        echo "$port_name serial_no:  $serial_no $new_file_name"
    done
}

while getopts ":hms" opt
do
    case "$opt" in
        h)
            usage
            ;;
        s)
            startLog screen
            ;;
        m)
            startLog minicom
            ;;
        \?)
            echo "Invalid Option: -$OPTARG" 1>&2
            usage
            ;;
    esac
done
shift $((OPTIND -1))

Подробности:

  • когда вы определяете переменные screen и minicom, у вас было "$( ... )". Команда внутри $() выполняется именно тогда, а не позже, когда вы поставите $1 позже. Вот почему я удалил эту часть и поместил команды прямо в функцию.
  • в startLog() я повторно использовал case. Также можно использовать if.
  • BOARDS - это массив. Поэтому, когда вы выполняете $BOARDS без указания индекса, вы получаете только первый элемент. Вы должны сделать ${BOARDS[@]}, чтобы обработать все элементы.
  • если вы не знали, BOARDS=(/dev/ttyUSB* /dev/ttyACM*) расширит *, поэтому BOARDS будут определены как все файлы /dev/ttyUSB* и все файлы /dev/ttyACM*. Он не останется с *.
  • когда вы определяете переменную из другой команды (var=$(command)), вам не нужно помещать вокруг нее " ". Это также сбивает с толку, поскольку вы должны заключать переменные в двойные кавычки внутри $(), поэтому у вас будут двойные кавычки внутри других двойных кавычек.

Я также помещаю его в тот стиль кода, который предпочитаю, но он гибкий и зависит от личных предпочтений.

Вы можете поместить свой код на https://www.shellcheck.net/ для проверки синтаксиса.

11.02.2021
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..