Eu sunt încercarea de a căuta modul de a trece parametrii într-un Bash funcție, dar ceea ce vine de sus este întotdeauna cum să treacă parametru din linia de comandă.
Aș dori pentru a trece parametrii în scenariul meu. Am incercat:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
Dar sintaxa nu este corect, cum să treacă un parametru la functia mea?
Există două modalități tipice de a declara o funcție. Eu prefer cea de-a doua abordare.
function function_name {
command...
}
sau
function_name () {
command...
}
Pentru a apela o funcție cu argumente:
function_name "$arg1" "$arg2"
Funcția se referă la trecut argumente de poziția lor (nu le stiu numele), care este de $1, $2, și așa mai departe. $0 este numele de script-ul în sine.
Exemplu:
function_name () {
echo "Parameter #1 is $1"
}
De asemenea, aveți nevoie pentru a apela funcția după acesta este declarat.
#!/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.
Ieșire:
./myScript.sh: line 2: foo: command not found
Parameter #1 is 2
Cunoștințele de nivel înalt limbaje de programare (C/C++/Java/PHP/Python/Perl ...) ar sugera laic care bash funcții ar trebui să funcționeze ca în celelalte limbi. În loc de, bash funcții de lucru cu astfel de comenzi shell și aștept argumente pentru a fi trecut la ei în același mod s-ar putea trece o opțiune pentru o comanda de shell (ls-l). În efect, funcția de argumente în bash sunt tratate ca parametrii de poziție ($1, $2..$9, ${10}, ${11}
, și așa mai departe). Aceasta nu este o surpriză având în vedere cât de getopts
funcționează. Parantezele nu sunt necesare pentru a apela o funcție în bash.
(Notă: I se întâmplă să fie de lucru pe Open Solaris în momentul de față.)
# 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
Dacă preferați numit parametri, l's posibil (cu câteva trucuri) pentru a trece de fapt parametrii numiți la funcții (de asemenea, face posibilă pentru a trece tablouri și referințe).
Metoda pe care am dezvoltat-vă permite să definiți parametrii numiți trecut la o funcție de genul asta:
function example { args : string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}
De asemenea, puteți adnota argumente ca @este necesar sau @readonly, de a crea ...restul argumente, de a crea tablouri din secvențială argumente (utilizând, de exemplu, `string[4]) și, opțional, lista de argumente în mai multe linii:
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[*]}"
}
Cu alte cuvinte, nu numai că puteți apela parametrii de numele lor (ceea ce face pentru o mai ușor de citit de bază), puteți trece de fapt tablouri (și referințe la variabile - această caracteristică funcționează numai în bash 4.3 deși)! În Plus, mapate variabile sunt toate în domeniul de aplicare locală, doar ca $1 (și altele).
Codul care face acest lucru este destul de ușor și funcționează atât în bash 3 și bash 4 (acestea sunt doar versiuni I'am testat-o cu). Daca're interesat în mai multe trucuri de genul asta pe care le fac în curs de dezvoltare cu bash mult mai frumos și mai ușor, puteți lua o privire la meu Bash Infinity-Cadru, codul de mai jos este disponibil ca una dintre funcționalitățile sale.
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;'
Sper că acest exemplu poate ajuta. Este nevoie de două numere de la utilizator, le hrănește în funcție numită " add "(în ultima linie de cod), și " add " va rezuma-le și să le imprimați.
#!/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
Crezut că am'd țeavă cu mai vorbim de un alt mod de a transmite parametri numit bash... trece de referință. Acest lucru este susținut 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];
O sintaxă alternativă pentru bash 4.3 este folosind un nameref
Deși nameref este mult mai convenabil, în care se perfect dereferences, unele mai vechi acceptate distribuții încă o navă versiune mai veche deci am castigat't recomanda încă.
Un exemplu simplu, care va șterge atât în timpul de executare script sau în interiorul script-ul în timp ce de asteptare o funcție.
#!/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