script opciones length example bash function

opciones - bash: ¿Cómo creo una función desde una variable?



substr linux bash (5)

De hecho, es instructivo que la construcción antes mencionada haga descarrilar la posibilidad de tener comillas incrustadas en su interior y, por lo tanto, sea potencialmente rebelde. Sin embargo, la siguiente construcción ofrece una funcionalidad similar sin tener las limitaciones de la respuesta anterior.

Para su revisión:

source /dev/stdin <<EOF function someprefix_${bname}() { echo "test"; }; EOF

¿Cómo creo una función nombrada desde el contenido de una variable? Quiero escribir un script de plantilla que defina una función que lleva el nombre del archivo del script. Algo como esto (que por supuesto no funciona):

#!/bin/bash bname="$(basename $0)" # filename of the script itself someprefix_${bname}() { # function''s name created from $bname variable echo test }

Entonces, si el nombre de archivo del script es foo.sh , entonces debería definir una función llamada someprefix_foo que hará eco de "prueba".


Las soluciones ''eval y'' source ''funcionan si IFF no tiene nada en la función que pueda evaluarse en el momento de la creación y que realmente desee retrasar hasta el tiempo de ejecución.

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

Sí, es un ejemplo artificial (solo fecha de llamada y no se hace eco de una llamada subshell), pero al usar las respuestas originales, probé algo más elaborado que requería una evaluación de tiempo de ejecución y obtuve resultados similares: evaluación en "compilación" tiempo, no correr tiempo.

La forma en que resolví el problema fue construir un archivo temporal con la función y luego obtener esa fuente. Mediante el uso juicioso de comillas simples y dobles que rodean la prueba que imprimo en el archivo, puedo controlar completamente qué se evalúa y cuándo.

tmpsh=$(mktemp) echo "goodfunc ()" > $tmpsh echo ''{'' >> $tmpsh echo ''echo $(date)'' >> $tmpsh echo ''}'' >> $tmpsh . $tmpsh rm -f $tmpsh

y entonces

$ 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

Con suerte, esto será de mayor utilidad para las personas. Disfrutar.


Puede deshabilitar la expansión de un documento aquí de esa manera:

eval "$(cat <<EOF $function_name() { commands go here and "$you $do $not $have $to $escape variables" } EOF )"

Ver: Cómo hacer un gato << EOF >> un archivo que contiene código?

Manual de Bash: 3.6.6 Aquí Documentos / Documento Aquí

No se realiza expansión de parámetros y variables, sustitución de comandos, expansión aritmética o expansión de nombre de archivo en word. Si se cita alguna parte de la palabra, el delimitador es el resultado de la eliminación de comillas en la palabra, y las líneas en el documento aquí no se expanden. Si la palabra no tiene comillas, todas las líneas del documento aquí están sujetas a expansión de parámetros, sustitución de comandos y expansión aritmética, la secuencia de caracteres / newline se ignora, y / debe utilizarse para citar los caracteres / , $ y ` .


Puedes usar eval :

eval "someprefix_${bname}() { echo test; }"

Bash incluso permite "." s en nombres de funciones :)


Uso la siguiente sintaxis, que evita /dev/stdin pero aún te permite usar heredocs:

eval "$(cat <<EOF $function_name() { commands go here but "/$you /$have /$to /$escape $variables" } EOF )"