Написание скрипта, содержащего только одно определение функции v.s. перемещение кода в теле функции в скрипт?

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

Замена первой строки вашего цикла for следующей должна решить вашу проблему.

RESULT=$(awk 'BEGIN{curr_f=FILENAME; nr=1} {if(curr_f!=FILENAME){if(mean > max_mean){max_mean=mean; f=curr_f} curr_f=FILENAME; nr=0; sum=0} } { sum+=$4; nr++; mean=sum/nr }  END{if(mean>max_mean){print mean, FILENAME}else{print max_mean, f}}' ${x}[1-4]/${x}[1-4].txt )

2
14.11.2018, 19:45
2 ответа

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

В конце вы можете найти демонстрацию определения одной функции в отдельном, но параметризованном исходном файле.


Функция:

  • и по имени
  • блок кода
  • который можно использовать повторно(вызывать много раз)

Принимая во внимание вышеизложенное, для чего он нужен и есть ли у него альтернативы?

  1. Логическая организация кода

    Группировка пакета команд, предназначенных для определенной цели, имеет большой смысл. Ведь это одно из значений термина функция-что-то имеет такую-то функцию .Однако та же цель может быть достигнута и другими способами:

    • Команды можно группировать визуально, например. занимающие последовательные строки и отделяемые от остального кода пустыми строками и комментариями. Или просто поставить на ту же строку с комментарием, следующим в конце.
    • Их можно сгруппировать в отдельный файл, который может быть выполненным или источником .
    • Их можно просто заблокировать с помощью фигурных скобок {... }.
    • Их можно было даже сгруппировать и выполнить в отдельной подоболочке , если поместить их в скобки (... )подоболочки. 1
  2. Пакетные операции

    Функции позволяют легко перенаправлять массовые операции ввода-вывода с помощью стандартных операторов Bash. Блоки, подоболочки, выполнение скриптов и источники тоже работают, но для чисто визуальных групп команд изменения дескриптора файла ввода-вывода должны применяться с помощью exec.

  3. Локализация

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

    В качестве альтернативы здесь можно использовать отдельные сценарии и подоболочки. Исходные файлы тоже, что касается позиционных параметров.

  4. Параметризация

    Каждая функция получает собственный набор позиционных параметров $1, $2и т. д. Это позволяет явно изменять поведение функций при вызове команды.

    Альтернативы здесь включают автономные -сценарии и исходные файлы.

  5. Код идентификация

    Имя функции уникально, и это означает не только их однозначное распознавание,но и возможность их выполнения. И много раз нужно. Ни блоки {}, ни подоболочка, ни группировка простого текста не предлагают этого -, если они не охватываются циклами. Хотя скрипты и исходные файлы делают.

  6. Информация

    Наконец, как имя функции, так и любые комментарии, которые оно может содержать, учитывают понятность кода. Все остальные варианты дают здесь свободу действий, но анонимные решения, такие как подоболочка и блок {}, не могут облегчить формальное название (и адрес )для блока кода.


Вот пример разумного размещения одной функции в отдельном исходном файле.

case "$1" in
    a)
        f () { echo "This function was defined in a)."; }
        ;;
    b)
        f () { echo "This function was defined in b)."; }
        ;;
    *)
        f () { echo "This function was defined with no recognised argument."; }
        ;;
esac

Это условное определение действует как фабрика функций. Файл, полученный из другого источника, устанавливает туда функцию f. Весь этот код может быть включен в другую функцию, и в его нынешнем виде разница будет невелика. Но как только генератор функций становится достаточно большим, чтобы стать самостоятельным объектом, этот подход объединяет лучшее из двух :функцию и исходный файл.


См. также

На самом деле Bash допускает аналогичное определение функции :f () (...;). Определенная таким образом функция fбудет выполняться в собственной подоболочке.

0
27.01.2020, 22:02

Я делаю и то, и другое в зависимости от обстоятельств. В большинстве случаев я буду объявлять функции в том же скрипте, который будет их использовать, однако у меня есть «инструментарий» скриптов, в котором есть файл переменных и функций, которые будут общими для всех скриптов.

Функционировать или не функционировать

Основная цель функции — СУХОЙ (Не повторяйтесь ). Если у вас есть код, который будет использоваться в вашем скрипте более одного раза, он должен быть в функции.

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

В Руководстве по стилю оболочки Google говорится, что если ваш код содержит хотя бы одну функцию, вы должны использовать "основную" функцию в качестве оболочки для всего вашего кода. (По сути, ваш скрипт будет состоять только из серии объявлений функций, заканчивающихся одним вызовомmain)

Объявление функций (или написание кода )внутри одного скрипта

  • Простой (Любой, кто взглянет на код, сможет легко отследить, что делает каждая функция)
  • Повышает переносимость (Необходимо переместить только один файл из системы в систему)

Если вы пишете автономный сценарий для выполнения одной задачи, возможно, вам подойдет этот способ.

Объявление функций внутри отдельного файла

  • СУХОЙ (Не повторяйся)
  • Может быть проще управлять

Если вы создаете набор инструментов с множеством общих функций, скорее всего, вам подойдет этот способ.

В моем примере есть функции, которые используются всеми или, по крайней мере, большинством скриптов в наборе инструментов. Это включает в себя некоторые функции, которые запрашивают нашу систему управления запасами и возвращают информацию о серверах, такую ​​как IP-адрес,версия ОС и т. д. Эта информация полезна для многих инструментов, поэтому имеет смысл объявлять такие функции в одном файле, а не во всех файлах по отдельности. Кроме того, мы недавно внесли изменения в систему управления запасами, поэтому вместо изменения более 10 разных файлов мне нужно было изменить только общий файл для запроса новой системы, остальные файлы по-прежнему работают правильно без изменений.

Некоторыми недостатками этого метода является его сложность. Каждый файл имеет следующий оператор для источника этого общего файла:

if [[ -f "${0%/*}/lib/common.sh" ]]; then
   . "${0%/*}/lib/common.sh"
else
    echo "Error! lib/common.sh not found!"
    exit 1
fi

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

3
27.01.2020, 22:02

Теги

Похожие вопросы