Você está misturando scripts e funções.
Criando um script
Um script é um programa independente. Pode acontecer de ser escrito em zsh, mas você pode invocá-lo de qualquer lugar, não apenas de uma linha de comando zsh. Se acontecer de você executar um script escrito em zsh a partir de uma linha de comando zsh ou outro script zsh, isso é uma coincidência que não afeta o comportamento do script. O script é executado em seu próprio processo, não influencia seu pai (por exemplo, ele não pode alterar variáveis ou o diretório atual).
Seu código realiza uma tarefa independente que pode ser invocada de qualquer lugar e não precisa acessar o estado do shell que o executa, portanto, ele deve ser um script, não uma função.
Um script deve ser um arquivo executável: chmod +x /path/to/script
. Ele deve começar com uma linha shebang para permitir que o kernel saiba qual programa usar para interpretar o script. No seu caso, adicione esta linha ao topo do arquivo:
#!/usr/bin/env zsh
Coloque o arquivo em um diretório listado na variável $PATH
. Muitos sistemas configuram ~/bin
ou ~/.local/bin
no padrão PATH
de um usuário, para que você possa usá-los. Se você quiser adicionar outro diretório, consulte link
Quando você digita um nome de comando que não é um alias, uma função ou um incorporado, o shell procura por um arquivo executável com esse nome em $PATH
e o executa. Assim, você não precisa declarar o script para o shell, basta soltá-lo no lugar certo.
Fazendo uma função
Uma função é um código que é executado dentro de uma instância de shell existente. Ele tem acesso total a todo o estado do shell: variáveis, diretório atual, funções, histórico de comandos, etc. Você só pode invocar uma função em um shell compatível.
Seu código pode funcionar como uma função, mas você não ganha nada fazendo isso funcionar e perde a capacidade de invocá-lo de outro lugar (por exemplo, de um gerenciador de arquivos).
No zsh, você pode disponibilizar uma função para sessões interativas, incluindo sua definição em ~/.zshrc
. Como alternativa, para evitar a sobrecarga de .zshrc
com um número muito grande de funções, você pode usar o mecanismo de carregamento automático. O carregamento automático funciona em duas etapas:
- Declare o nome da função com
autoload -U myfunction
. - Quando
myfunction
é invocado pela primeira vez, zsh procura um arquivo chamadomyfunction
nos diretórios listados em$fpath
e usa o primeiro arquivo que encontra como a definição demyfunction
.
Todas as funções precisam ser definidas antes do uso. É por isso que não é suficiente colocar o arquivo em $fpath
. Declarar a função com autoload
na verdade cria uma definição de stub que diz "carregue essa função de $fpath
e tente novamente":
% autoload -U myfunction
% which myfunction
myfunction () {
# undefined
builtin autoload -XU
}
O Zsh tem um mecanismo para gerar esses stubs explorando $fpath
. Está incorporado no subsistema de conclusão.
- Coloque
#autoload
como a primeira linha do arquivo. - No seu
.zshrc
, certifique-se de ter definido totalmentefpath
antes de chamar a função de inicialização do sistema de conclusãocompinit
.
Note que o arquivo contendo uma definição de função deve conter a função corpo , não a definição da função, porque o que o zsh executa quando a função é chamada é o conteúdo do arquivo. Então, se você quisesse colocar seu código em uma função, você o colocaria em um arquivo chamado extract
que está em um dos diretórios em $fpath
, contendo
#autoload
if [ -f $1 ]; then
…
Se você deseja ter o código de inicialização que é executado quando a função é carregada, ou para definir funções auxiliares, você pode usar este idioma (usado na distribuição zsh). Coloque a definição da função no arquivo, além de todas as definições auxiliares e qualquer outro código de inicialização. No final, chame a função, passando os argumentos. Então myfunction
conteria:
#autoload
my_auxiliary_function () {
…
}
myfunction () {
…
}
myfunction "$@"
P.S.
7z x
funciona na maioria dos tipos de arquivo.