Puedo definir bash
funciones usando u omitiendo la function
palabra clave. ¿Hay alguna diferencia?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Ambas llamadas a funciones foo
y bar
éxito y no puedo ver ninguna diferencia. Así que me pregunto si es solo para mejorar la legibilidad, o si hay algo que me falta ...
Por cierto, en otros shells como dash
( /bin/sh
está vinculado simbólicamente dash
en debian / ubuntu) falla cuando se usa la function
palabra clave.
function baz { echo "baz"; }
. Ver del bash en el wiki de GreyCat.Respuestas:
No hay diferencia AFAIK, aparte del hecho de que la segunda versión es más portátil.
fuente
tar cf - /some/thing | ssh user@desthost "cd destinationdir && tar xf - "
sin advertirle que primero verifique dos veces si la versión de alquitrán en desthost eliminará el "/" podría conducir a desastres en algunos casos ...). Por ejemplo: si el uso de unafunction tar { #a safe tar with safety checks ... }
ysh
lo ignora, ...sh
reconocen lafunction
palabra clave y, en general, que asumen características comunes pero no estándar que les gustanksh
ybash
ofrecen, a menudo tampoco funcionarán en sistemas de producción más nuevos , incluso si funcionaban en versiones anteriores de El mismo sistema operativo.bash
todavía se ofrecesh
en muchos sistemas GNU / Linux, pero algunas distribuciones populares han pasado a tenersh
como enlace simbólico adash
(Debian Almquist SHell) para mejorar el rendimiento. Esto incluye Debian y Ubuntu .La
function
palabra clave se introdujo en ksh . El shell Bourne tradicional solo tenía lafoo ()
sintaxis, y POSIX estandariza solo lafoo ()
sintaxis.En ATT ksh (pero no pdksh), existen algunas diferencias entre las funciones definidas por
function
y las funciones definidas con la sintaxis Bourne / POSIX. En las funciones definidas porfunction
, latypeset
palabra clave declara una variable local: una vez que la función sale, el valor de la variable se restablece a lo que era antes de ingresar a la función. Con la sintaxis clásica, las variables tienen un alcance global, se usetypeset
o no.Otra diferencia en ksh es que las funciones definidas con la
function
palabra clave tienen su propio contexto de trampa. Las trampas definidas fuera de la función se ignoran al ejecutar la función, y los errores fatales dentro de la función salen solo de la función y no del script completo. Además,$0
es el nombre de la función en una función definida porfunction
pero el nombre del script en una función definida con()
.Pdksh no emula ATT ksh. En pdksh,
typeset
crea variables de ámbito local independientemente de la función, y no hay trampas locales (aunque el usofunction
hace algunas diferencias menores; consulte la página del manual para obtener más detalles).Bash y zsh introdujeron la
function
palabra clave para compatibilidad con ksh. Sin embargo en estos shellsfunction foo { … }
yfoo () { … }
son estrictamente idénticos, como es la extensión bash y zshfunction foo () { … }
. Latypeset
palabra clave siempre declara variables locales (excepto con,-g
por supuesto), y las trampas no son locales (puede obtener trampas locales en zsh configurando lalocal_traps
opción).fuente
foo() command
sintaxis, y la sintaxis de Bourne se agregó más tarde al shell Korn por compatibilidad.function { ... }; f;
omitaf
después de lafunction
palabra clave?es la sintaxis Bourne apoyado por cualquier shell Bourne-como pero
bash
,yash
y las versiones recientes deposh
(que sólo apoyar comandos compuestos). (Las implementaciones de Bourne shell y AT&Tksh
no son compatibles afoo() any-command > redirections
menos queany-command
sea un comando compuesto).(ejemplos de compuesto comandos:
{ cmd; }
,for i do echo "$i"; done
,(cmd)
... el ser más utilizada{ ...; }
)es la sintaxis POSIX compatible con cualquier shell similar a Bourne y la que generalmente desea usar.
es la sintaxis de shell Korn, que es anterior a la sintaxis de Bourne. Use este solo si escribe específicamente para la implementación de AT&T del shell Korn y necesita el tratamiento específico que recibe allí. Esa sintaxis no es POSIX, pero es compatible con
bash
,yash
yzsh
para compatibilidad con el shell Korn, aunque esos shells (y laspdksh
variantes basadas en el shell Korn) no lo tratan de manera diferente a la sintaxis estándar.es la sintaxis de no shell y no debe usarse . Esto sólo ocurre con el apoyo de accidente por
bash
,yash
,zsh
y laspdksh
variantes basadas del shell Korn. Por cierto, también es laawk
sintaxis de la función.Si continuamos bajando por la lista esotérica,
(me gusta
function foo() (subshell)
ofunction foo() for i do; ... done
) es aún peor. Es compatible conbash
,yash
yzsh
, pero no ksh, incluso laspdksh
variantes basadas.Mientras:
solo es compatible con
zsh
.fuente
function
palabra clave como los paréntesis se documenta en Bash. El manual de Bash 4.2 y posterior dice que las funciones son declaradas por la sintaxisname () compound-command [ redirections ]
ofunction name [()] compound-command [ redirections ]
. En Bash 4.1.11 hasta al menos 3.0-beta que era solo la línea simple[ function ] name () compound-command [redirection]
que erróneamente no cubre la sintaxis que incluye lafunction
palabra clave pero no paréntesis, pero aún cubre la sintaxis que incluye tanto lafunction
palabra clave como los paréntesis.bash
reconocefunction foo {
ademásfoo() {
de la compatibilidad con el shell Korn (y siempre lo ha hecho) para que pueda interpretar los scripts escritos para el shell Korn. También es compatiblefunction foo () {
, pero no hay una buena razón para usarlo.function f() {
. Es decir, en términos de legibilidad, será reconocido como una función por cualquiera que sepa inglés y cualquiera que sepa C, en comparación con solo uno de estos conjuntos.You should never combine the keyword function with the parentheses () when defining a function.
Semánticamente, esas dos formas son equivalentes en Bash.
Desde la página del manual:
EDITAR: Acabo de notar que esta pregunta está etiquetada
posix
. En POSIXsh
, lafunction
palabra clave no se usa (aunque está reservada).fuente
Varios otros han respondido correctamente por ahora, pero aquí está mi sinopsis concisa:
La segunda versión es portátil y es probable que funcione con muchos shells estándar (particularmente POSIX).
La primera versión funcionará solo con bash, pero puede omitir los paréntesis que siguen al nombre de la función.
De lo contrario, representan entidades idénticas después de que bash las interpreta.
fuente
()
y lafunction
palabra clave de la cáscara se comporta como si usted acaba de hacerfoo(){ ...; }
de todos modos, excepto, por supuesto, de una concha en la que es una sintaxis no válida. y así debe hacerlofunction foo { ...; }
si es necesario, o de lofoo(){ ...; }
contrario.