Подтвердить что ты не робот

Анонимные функции в сценариях оболочки

Можно ли создать что-то аналогичное анонимной функции, чье значение может быть присвоено элементу массива и позже вызвано? Кажется, я не могу найти способ сделать это в bash script, но, возможно, это обходное решение.

4b9b3361

Ответ 1

Короткий ответ: Нет.

Длинный ответ: Nooooooooooooo.

Полный ответ: Функции в bash не являются объектами первого класса, поэтому в bash не может быть анонимной функции.

Ответ 2

Если вам действительно нужен массив для хранения функций, вы можете определить именованные функции и сохранить только их имена. Вы можете вызвать функцию как ${array[n]}. Или вы можете назвать их func1.. funcN, а затем просто вызвать func$n.

Ответ 3

Это возможно; Я написал библиотеку, чтобы сделать именно это, хотя это очень странный проект. Исходный код доступен в http://github.com/spencertipping/bash-lambda. Использование этой библиотеки:

$ my_array=()
$ my_array[0]=$(fn x 'echo $((x + 1))')
$ my_array[1]=$(fn x 'echo $((x + 2))')
$ ${my_array[0]} 5
6
$ ${my_array[1]} 5
7
$

Хитрость заключается в том, чтобы функция fn создала файл, содержащий тело функции, chmod +x, этот файл, а затем вернул его имя. Это заставляет скачкообразные файлы накапливаться, поэтому библиотека также реализует асинхронный сборщик мусора маркировки/развертки.

Ответ 4

Общим методом является условное назначение определений функций:

#!/bin/sh

case $1 in
a) foo() { echo case a; };;
b) foo() { echo case b; };;
*) foo() { echo default; } ;;
esac

foo

Ответ 5

Создайте файл fn в PATH

#!/bin/sh

printusage () {
        printf "Create anonymous function, for example\n"
        printf "fn 'echo "$1 $2"'"
        exit 1
}


[ "$#" = "1" ] || printusage
fun=$1
[ "$fun" = "" ] && printusage
fun_file="$(mktemp /tmp/fun_XXXXXX)"

echo "#!/bin/sh" > "$fun_file"
echo "" >> "$fun_file"
echo "$fun" >> "$fun_file"
chmod u+x "$fun_file"

echo "$fun_file"

Затем вы можете:

foo=$(fn 'echo $1')
${foo} "bar" 

Ответ 6

well bash завершается полным, soo вполне возможно;)

но в стороне от этого его не стоит рассматривать.

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

echo myval ; ( foocmd "$_" && barcmd "$_" )

но почему?!?