Saya mencoba untuk mencari cara untuk melewati parameter dalam Bash fungsi, tapi apa yang muncul adalah selalu cara untuk melewatkan parameter dari baris perintah.
Saya ingin melewati parameter dalam naskah saya. Saya mencoba:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
Tapi sintaks adalah tidak benar, bagaimana untuk melewati parameter untuk fungsi saya?
Ada dua cara umum untuk mendeklarasikan sebuah fungsi. Saya lebih suka pendekatan yang kedua.
function function_name {
command...
}
atau
function_name () {
command...
}
Untuk memanggil fungsi dengan argumen:
function_name "$arg1" "$arg2"
Fungsi mengacu berlalu argumen dengan posisi mereka (bukan nama), yang adalah $1, $2, dan sebagainya. $0 adalah nama dari script itu sendiri.
Contoh:
function_name () {
echo "Parameter #1 is $1"
}
Juga, anda perlu untuk memanggil fungsi setelah itu dinyatakan.
#!/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.
Output:
./myScript.sh: line 2: foo: command not found
Parameter #1 is 2
Pengetahuan tingkat tinggi bahasa pemrograman (C/C++/Java/PHP/Python/Perl ...) akan menyarankan kepada orang awam bahwa bash fungsi harus bekerja seperti yang mereka lakukan dalam bahasa lain. Bukan, bash fungsi kerja seperti shell perintah dan mengharapkan argumen yang akan diberikan kepada mereka dengan cara yang sama yang mungkin melewati pilihan untuk perintah shell (ls -l). Pada dasarnya, fungsi argumen di bash diperlakukan sebagai parameter posisi ($1, $2..$9, ${10}, ${11}
, dan sebagainya). Ini tidak mengherankan mengingat betapa getopts
bekerja. Tanda kurung tidak diperlukan untuk memanggil fungsi di bash.
(Catatan: saya kebetulan bekerja di Open Solaris pada saat ini.)
# 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
Jika anda lebih memilih parameter bernama, it's mungkin (dengan beberapa trik) untuk benar-benar melewati bernama parameter untuk fungsi (juga memungkinkan untuk lulus array dan referensi).
Metode yang saya kembangkan memungkinkan anda untuk mendefinisikan parameter yang dilewatkan ke fungsi seperti ini:
function example { args : string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}
Anda juga dapat membubuhi keterangan argumen @diperlukan atau @readonly, membuat ...sisanya argumen, membuat array berurutan dari argumen (misalnya dengan menggunakan string[4]
) dan opsional daftar argumen dalam beberapa baris:
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[*]}"
}
Dengan kata lain, tidak hanya anda dapat menghubungi parameter dengan nama mereka (yang membuat untuk lebih mudah dibaca core), anda dapat benar-benar lulus array (dan referensi ke variabel - fitur ini hanya bekerja di bash 4.3 meskipun)! Plus, dipetakan variabel adalah semua dalam lingkup lokal, seperti $1 (dan lain-lain).
Kode yang membuat pekerjaan ini sangat ringan dan bekerja baik di bash 3 dan bash 4 (ini adalah satu-satunya versi I've diuji dengan). Jika anda're tertarik pada banyak trik seperti ini yang membuat berkembang dengan bash jauh lebih baik dan lebih mudah, anda dapat mengambil melihat saya Bash Infinity Framework, kode di bawah ini tersedia sebagai salah satu fungsi nya.
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;'
Saya berharap contoh ini dapat membantu anda. Dibutuhkan dua angka dari pengguna, feed mereka ke fungsi yang disebut add
(di baris terakhir dari kode), dan add
akan jumlah mereka dan mencetak mereka.
#!/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
Pikir saya'd pipa dalam dengan menyebutkan cara lain untuk lulus bernama parameter untuk bash... lewat referensi. Hal ini didukung dari 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];
Alternatif sintaks untuk bash 4.3 menggunakan nameref
Meskipun nameref jauh lebih mudah dalam hal itu mulus dereferences, beberapa lebih tua didukung distro masih kapal versi lama jadi saya tidak't merekomendasikan hal ini belum cukup.
Contoh sederhana yang akan jelas baik selama menjalankan script atau di dalam script saat memanggil fungsi.
#!/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