Entonces empecé a usar zsh
. Me gusta todo bien. Parece genial y resbaladizo, y el hecho de que el directorio de trabajo actual y la línea de comando real estén en diferentes líneas es agradable, pero al mismo tiempo, me doy cuenta de que zsh
puede ser un poco más lento que bash
, especialmente cuando se imprime texto en el pantalla.
Lo que más me gustó fue el hecho de que zsh
era 'compatible con versiones anteriores' con todas las funciones que definí en mi .bashrc
.
Sin embargo, una queja. Todas las funciones funcionan perfectamente, pero no puedo entender cómo funciona el sistema de exportación.
Exporté algunas de esas .bashrc
funciones para poder usarlas en otros lugares, como scripts y programas externos, con export -f
.
En zsh, parece que ni siquiera se habla de exportar. ¿Es de carga automática? ¿Son esas dos cosas iguales? Me está costando mucho trabajo descubrirlo.
fuente
Respuestas:
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).(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 modificafoo.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 laFPATH
variable de entorno). En su script, declare funciones cargadas automáticamente conautoload -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á presenteautoload
, cargará el archivo compilado en lugar del código fuente. Puede usar lazrecompile
función para (re) compilar todas las definiciones de funciones en un directorio.fuente
bash
(no verifica que el contenido de la variable es solo una definición de función y procesa cualquier nombre de variable comoHTTP_HOST
oLC_X
). Buena respuesta de lo contrario.zsh -c 'functions[f]=$VAR'
se analiza incluso si laf
función nunca se llama). La solución es considerar solo las variables cuyo nombre sigue una plantilla reservada como esas$BASH_FUNC_x%%
, pero como usted dice,zsh
no tiene API para enumerarlas o recuperarlas. Tendría que llamarperl
por ejemplo.Si coloca su declaración de función en .zshenv , podrá utilizar su función desde un script sin ningún esfuerzo.
fuente
.zshenv
y ralentiza cada invocación de zsh al analizar una gran cantidad de código que nunca se usa. Además, no es lo mismo que exportar una función, al igual que una variable exportada, una función exportada solo está disponible para procesos secundarios. Mientras que las cosas que pones.zshenv
están disponibles para todos los zsh..zshenv
, entonces todos sus scripts serán totalmente no portables. Normalmente los scripts podrían depender unos de otros, lo cual está bien, los distribuyes juntos. Pero si dependen de tener funciones especiales.zshenv
, nadie querrá usarlas, o tendrían que ser invocadas con una especialZDOTDIR
, evitando que la suya.zshenv
sea ejecutada. Sería un dolor.