Ответ 1
Вы можете использовать eval
:
eval "someprefix_${bname}() { echo test; }"
Bash даже позволяет "."
в именах функций:)
Как создать функцию с именем из переменной? Я хочу написать шаблон script, который определяет функцию, названную после имени файла script. Что-то вроде этого (что, конечно, не работает):
#!/bin/bash
bname="$(basename $0)" # filename of the script itself
someprefix_${bname}() { # function name created from $bname variable
echo test
}
Итак, если имя файла script равно foo.sh
, тогда он должен определить функцию с именем someprefix_foo
, которая будет эхо-тест.
Вы можете использовать eval
:
eval "someprefix_${bname}() { echo test; }"
Bash даже позволяет "."
в именах функций:)
В самом деле, поучительно, что вышеупомянутая конструкция сводит на нет возможность наличия встроенных кавычек внутри и, следовательно, потенциально связана с ошибками. Однако следующая конструкция обеспечивает аналогичную функциональность, не имея ограничений на прежний ответ.
Для вашего обзора:
source /dev/stdin <<EOF
function someprefix_${bname}()
{
echo "test";
};
EOF
Решения "eval и" source "работают в IFF, у вас нет ничего в функции, которую можно было бы оценить при создании времени, когда вы на самом деле хотите отложить до времени выполнения.
source /dev/stdin << EOF
badfunc ()
{
echo $(date)
}
EOF
$ date;badfunc;sleep 10;date;badfunc
Tue Dec 1 12:34:26 EST 2015 ## badfunc output not current
Tue Dec 1 12:23:51 EST 2015
Tue Dec 1 12:34:36 EST 2015 ## and not changing
Tue Dec 1 12:23:51 EST 2015
Да, это надуманный пример (просто назовите дату и не эхо вызовите его подзаголовком), но используя исходные ответы, я попробовал что-то более сложное, что потребовало оценки времени выполнения и получило аналогичные результаты - оценка на "компилировать" время, а не время выполнения.
То, как я решил проблему, заключалось в создании временного файла с функцией, а затем источника. Благодаря разумному использованию одиночных и двойных кавычек, окружающих тест, я печатаю в файл, я могу полностью контролировать, что получает оценку и когда.
tmpsh=$(mktemp)
echo "goodfunc ()" > $tmpsh
echo '{' >> $tmpsh
echo 'echo $(date)' >> $tmpsh
echo '}' >> $tmpsh
. $tmpsh
rm -f $tmpsh
а затем
$ date;goodfunc;sleep 10;date;goodfunc
Tue Dec 1 12:36:42 EST 2015 ## current
Tue Dec 1 12:36:42 EST 2015
Tue Dec 1 12:36:52 EST 2015 ## and advancing
Tue Dec 1 12:36:52 EST 2015
Надеюсь, это будет более полезным для людей. Наслаждайтесь.
Я использую следующий синтаксис, который позволяет избежать /dev/stdin
, но все же позволяет использовать heredocs:
eval "$(cat <<EOF
$function_name() {
commands go here
but "\$you \$have \$to \$escape $variables"
}
EOF
)"