Bash
Funciones
Buscar..
Sintaxis
Defina una función con la palabra clave de
function
:function f {
}
Definir una función con
()
:f(){
}
Defina una función con la palabra clave de
function
y()
:function f(){
}
Función simple
En helloWorld.sh
#!/bin/bash
# Define a function greet
greet ()
{
echo "Hello World!"
}
# Call the function greet
greet
Al ejecutar el script, vemos nuestro mensaje.
$ bash helloWorld.sh
Hello World!
Tenga en cuenta que la obtención de un archivo con funciones los hace disponibles en su sesión de bash actual.
$ source helloWorld.sh # or, more portably, ". helloWorld.sh"
$ greet
Hello World!
Puede export
una función en algunos shells, para que esté expuesta a procesos secundarios.
bash -c 'greet' # fails
export -f greet # export function; note -f
bash -c 'greet' # success
Funciones con argumentos.
En helloJohn.sh
:
#!/bin/bash
greet() {
local name="$1"
echo "Hello, $name"
}
greet "John Doe"
# running above script
$ bash helloJohn.sh
Hello, John Doe
Si no modifica el argumento de ninguna manera, no es necesario copiarlo en una variable
local
, simplemente hagaecho "Hello, $1"
.Puede usar
$1
,$2
,$3
y así sucesivamente para acceder a los argumentos dentro de la función.Nota: para argumentos más de 9
$10
no funcionarán (bash lo leerá como $ 1 0), debe hacer${10}
,${11}
y así sucesivamente.$@
refiere a todos los argumentos de una función:#!/bin/bash foo() { echo "$@" } foo 1 2 3 # output => 1 2 3
Nota: Prácticamente siempre debe usar comillas dobles alrededor de
"$@"
, como aquí.Omitir las comillas hará que el shell amplíe los comodines (incluso cuando el usuario los haya citado específicamente para evitar eso) y, en general, introduzca comportamientos no deseados y posiblemente incluso problemas de seguridad.
foo "string with spaces;" '$HOME' "*" # output => string with spaces; $HOME *
para los argumentos predeterminados use
${1:-default_val}
. P.ej:#!/bin/bash foo() { local val=${1:-25} echo "$val" } foo # output => 25 foo 30 # output => 30
para requerir un argumento usa
${var:?error message}
foo() { local val=${1:?Must provide an argument} echo "$val" }
Valor de retorno de una función
La declaración de return
en Bash no devuelve un valor como las funciones C, sino que sale de la función con un estado de retorno. Puedes considerarlo como el estado de salida de esa función.
Si desea devolver un valor de la función, envíe el valor a stdout
así:
fun() {
local var="Sample value to be returned"
echo "$var"
#printf "%s\n" "$var"
}
Ahora, si lo haces:
var="$(fun)"
La salida de fun
será almacenada en $var
.
Manejo de banderas y parámetros opcionales.
La función incorporada getopts se puede usar dentro de las funciones para escribir funciones que se ajusten a indicadores y parámetros opcionales. Esto no presenta ninguna dificultad especial, pero uno tiene que manejar adecuadamente los valores tocados por los getopts . Como ejemplo, definimos una función de falla de fallos que escribe un mensaje en stderr y sale con el código 1 o un código arbitrario suministrado como parámetro a la opción -x
:
# failwith [-x STATUS] PRINTF-LIKE-ARGV
# Fail with the given diagnostic message
#
# The -x flag can be used to convey a custom exit status, instead of
# the value 1. A newline is automatically added to the output.
failwith()
{
local OPTIND OPTION OPTARG status
status=1
OPTIND=1
while getopts 'x:' OPTION; do
case ${OPTION} in
x) status="${OPTARG}";;
*) 1>&2 printf 'failwith: %s: Unsupported option.\n' "${OPTION}";;
esac
done
shift $(( OPTIND - 1 ))
{
printf 'Failure: '
printf "$@"
printf '\n'
} 1>&2
exit "${status}"
}
Esta función se puede utilizar de la siguiente manera:
failwith '%s: File not found.' "${filename}"
failwith -x 70 'General internal error.'
y así.
Tenga en cuenta que en cuanto a printf , las variables no deben usarse como primer argumento. Si el mensaje a imprimir consiste en el contenido de una variable, se debe usar el especificador %s
para imprimirlo, como en
failwith '%s' "${message}"
El código de salida de una función es el código de salida de su último comando.
Considere esta función de ejemplo para verificar si un host está activo:
is_alive() {
ping -c1 "$1" &> /dev/null
}
Esta función envía un solo ping al host especificado por el primer parámetro de la función. La salida y la salida de error de ping
se redirigen a /dev/null
, por lo que la función nunca generará nada. Pero el comando ping
tendrá el código de salida 0 en caso de éxito, y no cero en caso de error. Como este es el último (y en este ejemplo, el único) comando de la función, el código de salida de ping
se reutilizará para el código de salida de la función en sí.
Este hecho es muy útil en declaraciones condicionales.
Por ejemplo, si el host graucho
está activo, entonces conéctese con ssh
:
if is_alive graucho; then
ssh graucho
fi
Otro ejemplo: verifique repetidamente hasta que el host graucho
esté activo, y luego conéctese con ssh
:
while ! is_alive graucho; do
sleep 5
done
ssh graucho
Imprimir la definición de la función
getfunc() {
declare -f "$@"
}
function func(){
echo "I am a sample function"
}
funcd="$(getfunc func)"
getfunc func # or echo "$funcd"
Salida:
func ()
{
echo "I am a sample function"
}
Una función que acepta parámetros nombrados.
foo() {
while [[ "$#" -gt 0 ]]
do
case $1 in
-f|--follow)
local FOLLOW="following"
;;
-t|--tail)
local TAIL="tail=$2"
;;
esac
shift
done
echo "FOLLOW: $FOLLOW"
echo "TAIL: $TAIL"
}
Ejemplo de uso:
foo -f
foo -t 10
foo -f --tail 10
foo --follow --tail 10