Eu posso definir bash
funções usando ou omitindo a function
palavra - chave. Existe alguma diferença?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Ambas chamam para funções foo
e são bar
bem - sucedidas e não vejo diferença. Então, eu estou querendo saber se é apenas para melhorar a legibilidade, ou há algo que estou perdendo ...
BTW em outros shells como dash
( /bin/sh
está simbolizado dash
no debian / ubuntu) falha ao usar a function
palavra - chave.
function baz { echo "baz"; }
. Veja Bashism no wiki de GreyCat.Respostas:
Não há diferença AFAIK, exceto o fato de que a segunda versão é mais portátil.
fonte
tar cf - /some/thing | ssh user@desthost "cd destinationdir && tar xf - "
sem avisar que verifique primeiro se a versão do tar no desthost se livrará do "/" poderia levar a desastres em alguns casos ...). Por ex: se o uso de umfunction tar { #a safe tar with safety checks ... }
esh
ignora-lo, ...sh
reconhecer afunction
palavra-chave - e, em geral, que assumem recursos comuns, mas não padronizados, que os shells gostamksh
ebash
oferecem - também geralmente não funcionam em sistemas de produção mais novos, mesmo se eles trabalharem em versões mais antigas do o mesmo sistema operacional.bash
ainda fornecesh
muitos sistemas GNU / Linux, mas algumas distribuições populares passaram a tersh
um link simbólico paradash
(o Debian Almquist SHell) para melhorar o desempenho. Isso inclui o Debian e o Ubuntu .A
function
palavra-chave foi introduzida no ksh . O shell Bourne tradicional tinha apenas afoo ()
sintaxe e o POSIX padroniza apenas afoo ()
sintaxe.No ATT ksh (mas não no pdksh), existem algumas diferenças entre funções definidas por
function
e funções definidas com a sintaxe Bourne / POSIX. Nas funções definidas porfunction
, atypeset
palavra - chave declara uma variável local: uma vez que a função é encerrada, o valor da variável é redefinido para o que era antes de entrar na função. Com a sintaxe clássica, as variáveis têm um escopo global, independentemente de você usartypeset
ou não.Outra diferença no ksh é que as funções definidas com a
function
palavra - chave têm seu próprio contexto de interceptação. Os desvios definidos fora da função são ignorados durante a execução da função e os erros fatais dentro da função saem apenas da função e não de todo o script. Além disso,$0
é o nome da função em uma função definida por,function
mas o nome do script em uma função definida com()
.O Pdksh não emula o ATT ksh. No pdksh,
typeset
cria variáveis com escopo local, independentemente da função, e não há traps locais (embora o usofunction
faça algumas pequenas diferenças - consulte a página de manual para obter detalhes).Bash e zsh introduziram a
function
palavra - chave para compatibilidade com o ksh. No entanto, nessas conchasfunction foo { … }
efoo () { … }
são estritamente idênticas, como é a extensão bash e zshfunction foo () { … }
. Atypeset
palavra-chave sempre declara variáveis locais (exceto-g
naturalmente) e os traps não são locais (você pode obter traps locais no zsh configurando alocal_traps
opção).fonte
foo() command
sintaxe, e a sintaxe Bourne foi adicionada posteriormente ao shell Korn para compatibilidade.function { ... }; f;
omitaf
após afunction
palavra - chave?é a sintaxe Bourne suportada por qualquer shell semelhante ao Bourne
bash
,yash
e versões recentesposh
(que suportam apenas comandos compostos). (as implementações Bourne shell e AT&T deksh
não suportam, afoo() any-command > redirections
menos queany-command
seja um comando composto).(exemplos de composto de comandos:
{ cmd; }
,for i do echo "$i"; done
,(cmd)
... a ser mais utilizada{ ...; }
)é a sintaxe do POSIX suportada por qualquer shell semelhante ao Bourne e a que você geralmente deseja usar.
é a sintaxe do shell Korn, que antecede a sintaxe Bourne. Use este apenas se estiver escrevendo especificamente para a implementação da shell Korn da AT&T e precisar do tratamento específico recebido nele. Essa sintaxe não é POSIX, mas é suportada por
bash
,yash
ezsh
para compatibilidade com o shell Korn, embora esses shells (e aspdksh
variantes baseadas no shell Korn) não o tratem de forma diferente da sintaxe padrão.é a sintaxe de nenhum shell e não deve ser usada . Isso só acontece de ser apoiado por acidente por
bash
,yash
,zsh
e aspdksh
variantes com base do shell Korn. Aliás, também é aawk
sintaxe da função.Se continuarmos descendo a lista esotérica,
(como
function foo() (subshell)
oufunction foo() for i do; ... done
) é ainda pior. É suportado porbash
,yash
ezsh
, mas não por ksh, até pelaspdksh
variantes baseadas em.Enquanto:
é suportado apenas por
zsh
.fonte
function
palavra - chave e os parênteses está documentada no Bash. O manual do Bash 4.2 e posterior diz que as funções são declaradas pela sintaxename () compound-command [ redirections ]
oufunction name [()] compound-command [ redirections ]
. No Bash 4.1.11, até pelo menos 3.0-beta, que era apenas a única linha[ function ] name () compound-command [redirection]
que, erroneamente, não cobre a sintaxe que inclui afunction
palavra - chave, mas não os parênteses, mas ainda cobre a sintaxe que inclui afunction
palavra - chave e os parênteses.bash
reconhecefunction foo {
, alémfoo() {
de compatibilidade com o shell Korn (e sempre tem) para que ele possa interpretar scripts escritos para o shell Korn. Ele também suportafunction foo () {
, mas não há boas razões para usá-lo.function f() {
. Ou seja, em termos de legibilidade, será reconhecido como uma função por qualquer pessoa que saiba inglês e qualquer pessoa que conheça C, em comparação a apenas um desses conjuntos.You should never combine the keyword function with the parentheses () when defining a function.
Semanticamente, essas duas formas são equivalentes no Bash.
Na página do manual:
EDIT: Acabei de perceber que esta pergunta está marcada
posix
. No POSIXsh
, afunction
palavra-chave não é usada (embora seja reservada).fonte
Vários outros já responderam corretamente até agora, mas aqui está minha sinopse concisa:
A segunda versão é portátil e provavelmente funcionará com muitos shells padrão (particularmente POSIX).
A primeira versão funcionará apenas com o bash, mas você pode omitir os parênteses após o nome da função.
Caso contrário, eles representam entidades idênticas depois que o bash as interpreta.
fonte
()
e afunction
palavra-chave do shell se comporta como se você acabou de fazerfoo(){ ...; }
de qualquer maneira, exceto, é claro, por uma concha em que é sintaxe inválida. e assim você deve fazerfunction foo { ...; }
se for necessário oufoo(){ ...; }
não.