Как вызвать функцию в bash-скрипте

Вопрос или проблема

Мне просто интересно различие между вызовом функции $(one_function) и one_function в bash shell script.

Когда я устанавливаю переменную PS1 в ~/.bashrc, я не могу вызвать функцию с помощью one_func
например:

export PS1="\n\[\e[31m\] \$(one_func)  # это работает 

export PS1="\n\[\e[31m\] one_func      # это не работает

В отличие от доступа к переменным, функции вызываются по имени без использования ‘$‘ перед именем.

Возможно, вы запутались, как в командной строке вы можете определить функцию и вызвать ее по имени, но в вашем PS1 вы должны были поместить команду в скобки, предварив ее ‘\$‘. Заключение имени функции в ‘$(‘ и ‘)‘ вызывает замену всей ‘$(function)’ на стандартный вывод этой функции. Добавление обратной косой черты перед этим вызывает выполнение/запуск функции каждый раз, когда оболочка хочет вывести $PS1. Если бы вы не добавили обратную косую черту, функция была бы вызвана только один раз, при первом определении PS1, и какой бы ни был вывод функции в этот первый раз, он навсегда оставался бы в вашем приглашении PS1.

Когда вы вызываете $(one_func), это исполнит функцию и вернет вывод. Так, если вы скажете, например:

var=$(ls)

это сохранит вывод команды ls (т.е. список файлов в текущем каталоге) в переменную $var. В то время как команда:

var=ls

просто установит значение $var равным “ls”.

Кстати, вызов функции в bash происходит так же, как выполнение команды.

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

PS1="# \e[1;30m\u\e[0;37m@\h: \e[1;31m\w\e[31m >\e[1;30m  \t \e[1;33m [ \$(kmg \$(totalfilesize.sh)) ]\e[m\n"

“kmg” — это функция bash, которую я определил, и с помощью этого синтаксиса ей передается аргумент из вывода скрипта “totalfilesize.sh”

\$(kmg \$(totalfilesize.sh))

Если вам интересно, totalfilesize вычисляет размер файлов в текущем каталоге, а kmg преобразует строку (в байтах) в удобочитаемые b, MB, gB и т.д.

Ответ или решение

Чтобы понять, как вызвать функцию в bash-скрипте, необходимо углубиться в отличия между различными способами вызова и их применимостями в различных сценариях. В вашем вопросе упоминается различие между $(one_function) и one_function в контексте bash-скриптов, особенно в случае настройки переменной PS1.

Теория

В bash-скриптах функции определяются и вызываются поимённо, без необходимости использовать символ $. Однако, когда мы хотим получить текстовое значение, генерируемое функцией, часто применяются команды подстановки $() или обратные кавычки `. Эти конструкции запускают команду, указанную внутри них, и заменяют их вызов выводом этой команды.

Так, $(one_func) выполнит функцию one_func, захватит её стандартный вывод и подставит на место вызова. Применение команды подстановки полезно, когда требуется динамически обновлять значение переменной, как это бывает в PS1. В отличие от этого, просто one_func вызовет функцию, но её вывод не будет подставлен в строку.

Пример

В bash, если вы объявляете функцию, например:

one_func() {
    echo "Hello, World!"
}

вы можете вызвать функцию напрямую в скрипте:

one_func  # Эта команда выведет "Hello, World!" в терминале.

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

var=$(one_func)
echo $var  # Эта команда также выведет "Hello, World!", но сначала её значение будет сохранено в переменной `var`.

В контексте настройки переменной PS1, эта разница становится критически важной. Если просто использовать имя функции в PS1, например:

export PS1="\n\[\e[31m\] one_func"

То bash трактует one_func как просто текст, поэтому вызова функции на самом деле не происходит. Однако конструкция:

export PS1="\n\[\e[31m\] \$(one_func)"

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

Применение

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

Пример применения более сложной настройки:

PS1="[\u@\h \W]\$(my_prompt_function) > "

Здесь my_prompt_function может быть функцией, которая возвращает специфическую информацию, например, текущий git branch или статус системы, и её вывод будет интегрирован в вашу командную строку.

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

PS1="# \e[1;30m\u\e[0;37m@\h: \e[1;31m\w\e[31m >\e[1;30m  \t \e[1;33m [\$(kmg \$(totalfilesize.sh))]\e[m\n"

Здесь kmg — это функция bash, которая принимает аргументом вывод другого скрипта totalfilesize.sh, что позволяет динамично выводить размер файлов в удобочитаемом формате.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...