Las variables de entorno que contienen funciones son un hack bash. Zsh no tiene nada similar. Puede hacer algo similar con unas pocas líneas de código. Las variables de entorno contienen cadenas; versiones anteriores de bash, antes de que se descubriera Shellshock , almacenaban el código de la función en una variable cuyo nombre es el de la función y cuyo valor es () {
seguido por el código de la función seguido de }
. Puede usar el siguiente código para importar variables con esta codificación e intentar ejecutarlas con configuraciones similares a bash. Tenga en cuenta que zsh no puede emular todas las funciones de bash, todo lo que puede hacer es acercarse un poco (por ejemplo, para $foo
dividir el valor y expandir los comodines, y hacer matrices basadas en 0).
bash_function_preamble='
emulate -LR ksh
'
for name in ${(k)parameters}; do
[[ "-$parameters[name]-" = *-export-* ]] || continue
[[ ${(P)name} = '() {'*'}' ]] || continue
((! $+builtins[$name])) || continue
functions[$name]=$bash_function_preamble${${${(P)name}#"() {"}%"}"}
done
(Como señaló Stéphane Chazelas , el descubridor original de Shellshock, una versión anterior de esta respuesta podría ejecutar un código arbitrario en este punto si la definición de la función estaba mal formada. Esta versión no lo hace, pero, por supuesto, tan pronto como ejecute cualquier comando, podría ser una función importada del entorno).
Las versiones posteriores al shellshock de bash codifican funciones en el entorno utilizando nombres de variables no válidos (por ejemplo BASH_FUNC_myfunc%%
). Esto los hace más difíciles de analizar de manera confiable ya que zsh no proporciona una interfaz para extraer dichos nombres de variables del entorno.
No recomiendo hacer esto. Confiar en las funciones exportadas en los scripts es una mala idea: crea una dependencia invisible en su script. Si alguna vez ejecuta su script en un entorno que no tiene su función (en otra máquina, en un trabajo cron, después de cambiar sus archivos de inicialización de shell, ...), su script ya no funcionará. En su lugar, almacene todas sus funciones en uno o más archivos separados (algo así como ~/lib/shell/foo.sh
) e inicie sus scripts importando las funciones que usa ( . ~/lib/shell/foo.sh
). De esta manera, si modifica foo.sh
, puede buscar fácilmente qué scripts dependen de él. Si copia una secuencia de comandos, puede averiguar fácilmente qué archivos auxiliares necesita.
Zsh (y ksh antes) lo hace más conveniente al proporcionar una forma de cargar automáticamente las funciones en los scripts donde se usan. La restricción es que solo puede poner una función por archivo. Declare la función como autocargada y coloque la definición de la función en un archivo cuyo nombre sea el nombre de la función. Coloque este archivo en un directorio listado $fpath
(que puede configurar a través de la FPATH
variable de entorno). En su script, declare funciones cargadas automáticamente con autoload -U foo
.
Además, zsh puede compilar scripts para ahorrar tiempo de análisis. Llame zcompile
para compilar un guión. Esto crea un archivo con la .zwc
extensión. Si este archivo está presente autoload
, cargará el archivo compilado en lugar del código fuente. Puede usar la zrecompile
función para (re) compilar todas las definiciones de funciones en un directorio.