Exportando uma função em shell

87

Diga-me como exportar uma função no shell pai (bash, sh ou ksh) para que a função esteja disponível para todos os processos filho iniciados a partir do processo pai.

Sachin Chourasiya
fonte
1
unix.stackexchange.com/questions/22796/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respostas:

105

O export -frecurso é específico do Bash:

pai

#!/bin/bash
plus1 () { echo $(($1 + 1)); }
echo $(plus1 8)
export -f plus1
./child 14 21

criança

#!/bin/bash
echo $(plus1 $(($1 * $2)) )
Pausado até novo aviso.
fonte
2
a função exportada está disponível apenas para chamadas filhas? Como aplicá-lo à sessão bash atual? gosto de escrever .bashrc, mas apenas para a instância atual do bash ...
vp_arth
3
@vp_arth: Se você não precisa da função em chamadas filhas, não precisa exportá-la. Ele está disponível na sessão atual de qualquer maneira (observe que, se estiver definido em um arquivo, você precisará originar o arquivo em vez de executá-lo para torná-lo disponível na sessão atual).
Pausado até novo aviso.
3

Se você estiver usando ksh ou zsh:

Você pode usar a variável de ambiente FPATH, onde você pode colocar todas as suas funções.

Se FPATHfor definido em um interpretador interativo, e um comando ou função não for encontrado no ambiente shell atual ou no PATH, os diretórios listados lá são pesquisados ​​quanto à existência de um arquivo com o nome do comando ausente. Se um for encontrado, é originado no ambiente shell atual e espera-se que defina a função.

Assim, você pode colocar todas as suas funções em um local no FPATH, e os scripts filhos também poderão encontrá-lo.

Você pode usar o autoloadcomando em scripts de shell para carregar as funções de que precisa:

autoload fun_a fun_b

No zsh, autoloadé necessário para FPATHfuncionar. In kshe seus parentes próximos, acredito que ele simplesmente faz com que as funções definidas em FPATHsubstituam o comando regular em seu PATH, como fariam se fossem definidas diretamente.

Alguns detalhes sobre FPATHe autoload:

Venkataramesh Kommoju
fonte
2

Se você criar subshells com ( ), eles herdarão um instantâneo de todas as definições, parâmetros e variáveis ​​de shell.

Se você os executar como programas, poderá inserir as definições .bashrc.

Se você está tentando falsificar um script existente para executar um wrapper ou substituição para um comando PATH, então .bashrcfuncionará dependendo dos detalhes da execução. Caso contrário, você poderia executar um script de invólucro que simplesmente faz um .ou sourcede um arquivo de inclusão que define as funções e, em seguida, faz a mesma coisa com o script de shell com os comandos a serem substituídos.

O script de wrapper pode ser semelhante a:

script=$1
shift
. include.sh
. $script "$@"

A ideia é que o primeiro parâmetro seja o nome do script real e os parâmetros restantes sejam os args, então o script acima é executado.

DigitalRoss
fonte
2
Você poderia explicar isso com algum exemplo de codificação. Não quero colocar minha função em .bashrc
Sachin Chourasiya
1
declare -x -f NAME

Mais informações

-f restringir a ação ou exibir nomes e definições de funções
-x para fazer a exportação de NAMEs
Steven Penny
fonte
6
Observe que isso é específico parabash . ( ksh'S contrapartida declare, typeset, tem uma -xopção, mas só se aplica a variáveis , e não funções; idem para zsh).
mklement0
0

As funções não são exportáveis ​​por natureza. No entanto, você pode exportar strings, então tenho um pequeno truque aqui:

func="$(typeset -f funcname)"
export func

Para importar a função, redefina-a a partir da string exportada:

# in subshell
eval "$func"
iBug
fonte