script - Pasando parámetros a una función Bash
scripts bash ejemplos (7)
Estoy intentando buscar cómo pasar parámetros en una función Bash, pero lo que aparece es cómo pasar parámetros desde la línea de comandos.
Me gustaría pasar parámetros dentro de mi script. Lo intenté:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
Pero la sintaxis no es correcta, ¿cómo pasar un parámetro a mi función?
El conocimiento de lenguajes de programación de alto nivel (C / C ++ / Java / PHP / Python / Perl ...) sugeriría al laico que las funciones de bash deberían funcionar como lo hacen en esos otros lenguajes. En su lugar , las funciones de bash funcionan como comandos de shell y esperan que los argumentos se pasen a ellos de la misma manera en que uno podría pasar una opción a un comando de shell (ls -l). En efecto, los argumentos de la función en bash se tratan como parámetros posicionales ( $1, $2..$9, ${10}, ${11}
, etc.). Esto no es una sorpresa teniendo en cuenta cómo funciona getopts
. No se requieren paréntesis para llamar a una función en bash.
( Nota : estoy trabajando en Open Solaris en este momento).
# bash style declaration for all you PHP/JavaScript junkies. :-)
# $1 is the directory to archive
# $2 is the name of the tar and zipped file when all is done.
function backupWebRoot ()
{
tar -cvf - $1 | zip -n .jpg:.gif:.png $2 - 2>> $errorlog &&
echo -e "/nTarball created!/n"
}
# sh style declaration for the purist in you. ;-)
# $1 is the directory to archive
# $2 is the name of the tar and zipped file when all is done.
backupWebRoot ()
{
tar -cvf - $1 | zip -n .jpg:.gif:.png $2 - 2>> $errorlog &&
echo -e "/nTarball created!/n"
}
#In the actual shell script
#$0 $1 $2
backupWebRoot ~/public/www/ webSite.tar.zip
Espero que este ejemplo te pueda ayudar. Toma dos números del usuario, los alimenta a la función llamada add
(en la última línea del código), y los add
e imprimen.
#!/bin/bash
read -p "Enter the first value: " x
read -p "Enter the second value: " y
add(){
arg1=$1 #arg1 gets to be the first assigned argument (note there are no spaces)
arg2=$2 #arg2 gets to be the second assigned argument (note there are no spaces)
echo $(($arg1 + $arg2))
}
add x y #feeding the arguments
Hay dos formas típicas de declarar una función. Prefiero el segundo enfoque.
function function_name {
command...
}
o
function_name () {
command...
}
Para llamar a una función con argumentos:
function_name "$arg1" "$arg2"
La función se refiere a los argumentos pasados por su posición (no por su nombre), que es $ 1, $ 2, etc. $ 0 es el nombre del script en sí.
Ejemplo:
function_name () {
echo "Parameter #1 is $1"
}
Además, debe llamar a su función después de que se declara.
#!/usr/bin/env sh
foo 1 # this will fail because foo has not been declared yet.
foo() {
echo "Parameter #1 is $1"
}
foo 2 # this will work.
Salida:
./myScript.sh: line 2: foo: command not found
Parameter #1 is 2
Pensé en hablar con otra forma de pasar parámetros con nombre para golpear ... pasar por referencia. Esto es compatible a partir de bash 4.0
#!/bin/bash
function myBackupFunction(){ # directory options destination filename
local directory="$1" options="$2" destination="$3" filename="$4";
echo "tar cz ${!options} ${!directory} | ssh root@backupserver /"cat > /mnt/${!destination}/${!filename}.tgz/"";
}
declare -A backup=([directory]=".." [options]="..." [destination]="backups" [filename]="backup" );
myBackupFunction backup[directory] backup[options] backup[destination] backup[filename];
Una sintaxis alternativa para bash 4.3 es usar un nameref
Aunque el nameref es mucho más conveniente, ya que elimina las referencias a la perfección, algunas distribuciones soportadas más antiguas aún incluyen una versión más antigua, así que todavía no lo recomiendo.
Se pierden los parens y comas:
myBackupFunction ".." "..." "xx"
y la función debería verse así:
function myBackupFunction() {
# here $1 is the first parameter, $2 the second etc.
}
Si prefiere los parámetros con nombre, es posible (con algunos trucos) pasar los parámetros con nombre a las funciones (también hace posible pasar matrices y referencias).
El método que desarrollé le permite definir parámetros nombrados pasados a una función como esta:
function example { args : string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}
También puede anotar argumentos como @required o @readonly, crear ... descansos, crear matrices a partir de argumentos secuenciales (usando, por ejemplo, string[4]
) y, opcionalmente, listar los argumentos en varias líneas:
function example {
args
: @required string firstName
: string lastName
: integer age
: string[] ...favoriteHobbies
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
echo "My favorite hobbies include: ${favoriteHobbies[*]}"
}
En otras palabras, no solo puede llamar a sus parámetros por sus nombres (lo que compensa un núcleo más legible), sino que también puede pasar matrices (y referencias a variables, esta función solo funciona en bash 4.3). Además, las variables asignadas están todas en el ámbito local, al igual que $ 1 (y otros).
El código que hace que esto funcione es bastante ligero y funciona tanto en bash 3 como en bash 4 (estas son las únicas versiones con las que lo he probado). Si está interesado en más trucos como este que hacen que el desarrollo de bash sea mucho más fácil y sencillo, puede echar un vistazo a mi Bash Infinity Framework , el código a continuación está disponible como una de sus funcionalidades.
shopt -s expand_aliases
function assignTrap {
local evalString
local -i paramIndex=${__paramIndex-0}
local initialCommand="${1-}"
if [[ "$initialCommand" != ":" ]]
then
echo "trap - DEBUG; eval /"${__previousTrap}/"; unset __previousTrap; unset __paramIndex;"
return
fi
while [[ "${1-}" == "," || "${1-}" == "${initialCommand}" ]] || [[ "${#@}" -gt 0 && "$paramIndex" -eq 0 ]]
do
shift # first colon ":" or next parameter''s comma ","
paramIndex+=1
local -a decorators=()
while [[ "${1-}" == "@"* ]]
do
decorators+=( "$1" )
shift
done
local declaration=
local wrapLeft=''"''
local wrapRight=''"''
local nextType="$1"
local length=1
case ${nextType} in
string | boolean) declaration="local " ;;
integer) declaration="local -i" ;;
reference) declaration="local -n" ;;
arrayDeclaration) declaration="local -a"; wrapLeft= ; wrapRight= ;;
assocDeclaration) declaration="local -A"; wrapLeft= ; wrapRight= ;;
"string["*"]") declaration="local -a"; length="${nextType//[a-z/[/]]}" ;;
"integer["*"]") declaration="local -ai"; length="${nextType//[a-z/[/]]}" ;;
esac
if [[ "${declaration}" != "" ]]
then
shift
local nextName="$1"
for decorator in "${decorators[@]}"
do
case ${decorator} in
@readonly) declaration+="r" ;;
@required) evalString+="[[ ! -z /$${paramIndex} ]] || echo /"Parameter ''$nextName'' ($nextType) is marked as required by ''${FUNCNAME[1]}'' function./"; " >&2 ;;
@global) declaration+="g" ;;
esac
done
local paramRange="$paramIndex"
if [[ -z "$length" ]]
then
# ...rest
paramRange="{@:$paramIndex}"
# trim leading ...
nextName="${nextName///./}"
if [[ "${#@}" -gt 1 ]]
then
echo "Unexpected arguments after a rest array ($nextName) in ''${FUNCNAME[1]}'' function." >&2
fi
elif [[ "$length" -gt 1 ]]
then
paramRange="{@:$paramIndex:$length}"
paramIndex+=$((length - 1))
fi
evalString+="${declaration} ${nextName}=${wrapLeft}/$${paramRange}${wrapRight}; "
# continue to the next param:
shift
fi
done
echo "${evalString} local -i __paramIndex=${paramIndex};"
}
alias args=''local __previousTrap=$(trap -p DEBUG); trap "eval /"/$(assignTrap /$BASH_COMMAND)/";" DEBUG;''
Un ejemplo simple que se borrará durante la ejecución del script o dentro del script al llamar a una función.
#!/bin/bash
echo "parameterized function example"
function print_param_value(){
value1="${1}" # $1 represent first argument
value2="${2}" # $2 represent second argument
echo "param 1 is ${value1}" #as string
echo "param 2 is ${value2}"
sum=$(($value1+$value2)) #process them as number
echo "The sum of two value is ${sum}"
}
print_param_value "6" "4" #space sparted value
#you can also pass paramter durign executing script
print_param_value "$1" "$2" #parameter $1 and $2 during executing
#suppose our script name is param_example
# call like this
# ./param_example 5 5
# now the param will be $1=5 and $2=5