назначать и проверять метаданные функции bash

10

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

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

func1() {
# This function was generated for project: PROJECT1
echo "do my automation"
}

В идеале я бы мог видеть комментарий, когда я проверю определение:

$ type func1

func1 is a function
func1 () 
{
    # This function was generated for project: PROJECT1
    echo "do my automation"
}

Но почему-то bash игнорирует комментарии в момент загрузки функции, а не при ее выполнении. Таким образом, комментарии потеряны, и я получаю этот результат:

func1 is a function
func1 () 
{
    echo "do my automation"
}

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

yucer
источник
1
Не решение (отсюда и комментарий), но обходной путь, который я использую, - это проверить, если $1есть -h, а затем printf/ echoпомощь в одну строку / использование / что угодно.
Джон Н
2
См. Также: unix.stackexchange.com/questions/295022/…
Джефф Шаллер

Ответы:

13
function func_name()
{
  : '
  Invocation:   func_name $1 $2 ... $n
  Function:     Display the values of the supplied arguments, in double quotes.
  Exit status:  func_name always returns with exit status 0.
  ' :
  local i
  echo "func_name: $# arguments"
  for ((i = 1; i <= $#; ++i)); do
    echo "func_name [$i] \"$1\""
    shift
  done
  return 0
}
AlexP
источник
2
хммм, документы в Bash. Кто знал?
Брайан Минтон
Есть ли способ запросить этот комментарий? Я думаю о вспомогательной функции genery для всех команд.
Юсер
7

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

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

func1() {
    meta="This function was generated for project: PROJECT1"
    echo "do my automation"
}

Нет необходимости использовать эту переменную, но она появится при запросе функции с помощью type:

$ type func1
func1 is a function
func1 () 
{ 
    meta="This function was generated for project: PROJECT1";
    echo "do my automation"
}
Тердон
источник
2
Если вы хотите избежать сохранения переменной, вы можете использовать оператор nop ":" следующим образом: function func () {: "metadata" # do yours}
Luchostein
1
Я думаю, что одиночные кавычки здесь лучше, чем двойные кавычки, на всякий случай, если есть какие-либо нежелательные расширения, скрывающиеся в строке документации
Digital Trauma
6

Вы можете использовать встроенный NOP: . Кроме того, вам не нужно хранить его как переменную:

function f() {
  : your metadata here
  : "or here"
  # do yours
}

РЕДАКТИРОВАТЬ : Остерегайтесь специальных символов в ваших метаданных. Для чистого текста вы можете использовать:

: <<EOT
Your metadata text here.
EOT

РЕДАКТИРОВАТЬ : вместо этого вы можете использовать глобальный ассоциативный массив для хранения метаданных всех функций:

declare -A METADATA=()
METADATA[fun1]='foo bar'
function fun1() {
  echo I have some metadata: "${METADATA[$FUNCNAME]}"
}
METADATA[fun2]='baz you'
function fun2() {
  echo I have some other metadata: "${METADATA[$FUNCNAME]}"
}

Таким образом, вам не нужно анализировать declareили typeвыводить данные, а только запрашивать ключ массива.

Luchostein
источник
1
Будьте осторожны - your metadata hereмогут содержать расширения, которые имеют побочные эффекты. Лучше использовать одинарные кавычки, такие как ответ @ AlexP.
Цифровая травма
Да, но вы также должны быть осторожны внутри кавычек.
Лучостейн
3

Ты можешь это сделать.

$ f() { This function does nothing. 2> /dev/null; }
$ f
$ type f
f is a function
f () 
{ 
    This function does nothing. 2> /dev/null
}

источник
но функция должна делать свое дело после аннотирования. В примере, который я включил, эхо должно работать, когда я вызываю функцию нормально.
yucer
@yucer Это будет. Это всего лишь иллюстрация. Попытайся. Это имеет свои ограничения, хотя. Никакие специальные символы, такие как, не (могут быть использованы, и первое слово не должно быть допустимой командой.
ОК. Он считает, что это правильный ответ, хотя для его запуска требуется дополнительное время. Также может быть лучше включить эхо и метаданные, которые я использовал в моем примере.
юсер