Então eu comecei a usar zsh
. Eu gosto disso tudo. Parece muito legal e liso, e o fato de o diretório de trabalho atual e a linha de comando real estarem em linhas diferentes é bom, mas ao mesmo tempo, percebo que isso zsh
pode ser um pouco mais lento do que bash
, especialmente ao imprimir texto no tela.
O que mais gostei foi o fato de zsh
ser "compatível com versões anteriores" de todas as funções que defini no meu .bashrc
.
Uma queixa embora. Todas as funções funcionam perfeitamente, mas não consigo descobrir como o sistema de exportação funciona.
Eu tive algumas dessas .bashrc
funções exportadas para poder usá-las em outros lugares, como scripts e programas externos export -f
.
No zsh, a exportação nem parece ser comentada. É carregamento automático? Essas duas coisas são iguais? Estou tendo muita dificuldade em descobrir isso.
fonte
Respostas:
Variáveis de ambiente que contêm funções são um hack do bash. Zsh não tem nada parecido. Você pode fazer algo semelhante com algumas linhas de código. Variáveis de ambiente contêm seqüências de caracteres; As versões mais antigas do bash, antes da descoberta do Shellshock , armazenavam o código da função em uma variável cujo nome é o da função e cujo valor é
() {
seguido pelo código da função seguido por}
. Você pode usar o código a seguir para importar variáveis com essa codificação e tentar executá-las com configurações do tipo bash. Observe que o zsh não pode emular todos os recursos do bash, tudo o que você pode fazer é se aproximar um pouco (por exemplo, para$foo
dividir o valor e expandir curingas e criar matrizes baseadas em 0).(Como observou Stéphane Chazelas , o descobridor original do Shellshock, uma versão anterior desta resposta poderia executar código arbitrário nesse momento se a definição da função estivesse malformada. Essa versão não funciona, mas é claro, assim que você executa qualquer comando, pode ser uma função importada do ambiente.)
As versões pós-Shellshock do bash codificam funções no ambiente usando nomes de variáveis inválidos (por exemplo
BASH_FUNC_myfunc%%
). Isso dificulta a análise confiável, pois o zsh não fornece uma interface para extrair esses nomes de variáveis do ambiente.Eu não recomendo fazer isso. Confiar nas funções exportadas dos scripts é uma péssima idéia: cria uma dependência invisível no seu script. Se você executar seu script em um ambiente que não tem sua função (em outra máquina, em um trabalho cron, após alterar os arquivos de inicialização do shell, ...), seu script não funcionará mais. Em vez disso, armazene todas as suas funções em um ou mais arquivos separados (algo como
~/lib/shell/foo.sh
) e inicie seus scripts importando as funções que ele usa (. ~/lib/shell/foo.sh
). Dessa forma, se você modificarfoo.sh
, poderá pesquisar facilmente quais scripts contam com ele. Se você copiar um script, poderá descobrir facilmente quais arquivos auxiliares ele precisa.O Zsh (e o ksh antes dele) torna isso mais conveniente, fornecendo uma maneira de carregar automaticamente funções nos scripts em que são usadas. A restrição é que você pode colocar apenas uma função por arquivo. Declare a função como carregada automaticamente e coloque a definição da função em um arquivo cujo nome é o nome da função. Coloque esse arquivo em um diretório listado em
$fpath
(que você pode configurar através daFPATH
variável de ambiente). No seu script, declare funções carregadas automaticamente comautoload -U foo
.Além disso, o zsh pode compilar scripts, para economizar tempo de análise. Ligue
zcompile
para compilar um script. Isso cria um arquivo com a.zwc
extensão Se esse arquivo estiver presente,autoload
será carregado o arquivo compilado em vez do código-fonte. Você pode usar azrecompile
função para (re) compilar todas as definições de função em um diretório.fonte
bash
(não verifica se o conteúdo da variável é apenas uma definição de função e processa qualquer nome de variável comoHTTP_HOST
ouLC_X
). Boa resposta caso contrário.zsh -c 'functions[f]=$VAR'
é analisado, mesmo que af
função nunca seja chamada). A solução é considerar apenas variáveis cujo nome segue um modelo reservado como esse$BASH_FUNC_x%%
, mas, como você diz,zsh
não possui API para listar ou recuperar esses. Você precisaria ligar,perl
por exemplo.Se você colocar sua declaração de função em .zshenv , sua função será utilizável a partir de um script sem nenhum esforço.
fonte
.zshenv
e diminui a velocidade de toda chamada do zsh, analisando muito código que nunca é usado. Além disso, não é o mesmo que exportar uma função, assim como uma variável exportada, uma função exportada está disponível apenas para processos filhos. Considerando que o material que você coloca.zshenv
está disponível para todos os zsh..zshenv
, todos os seus scripts serão totalmente não portáveis. Normalmente, os scripts podem depender um do outro, o que é bom, você os distribui juntos. Mas se eles dependem de ter funções especiais.zshenv
, ninguém vai querer usá-las, ou eles teriam que ser chamados com um especialZDOTDIR
, impedindo que o seu próprio.zshenv
seja executado. Seria uma dor.