我试图搜索如何在Bash函数中传递参数,但出现的总是如何从命令行传递参数。
我想在脚本中传递参数。我试着:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
但是语法不正确。如何将参数传递给函数?
我试图搜索如何在Bash函数中传递参数,但出现的总是如何从命令行传递参数。
我想在脚本中传递参数。我试着:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
但是语法不正确。如何将参数传递给函数?
当前回答
一个简单的例子,将在执行脚本或调用函数时在脚本内部清除。
#!/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-separated value
# You can also pass parameters during executing the script
print_param_value "$1" "$2" # Parameter $1 and $2 during execution
# Suppose our script name is "param_example".
# Call it like this:
#
# ./param_example 5 5
#
# Now the parameters will be $1=5 and $2=5
其他回答
声明函数有两种典型的方法。我更喜欢第二种方法。
function function_name {
command...
}
or
function_name () {
command...
}
调用带参数的函数:
function_name "$arg1" "$arg2"
该函数根据参数的位置(而不是名称)引用传递的参数,即$1,$2,依此类推。$0是脚本本身的名称。
例子:
function_name () {
echo "Parameter #1 is $1"
}
此外,还需要在函数声明之后调用它。
#!/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.
输出:
./myScript.sh: line 2: foo: command not found
Parameter #1 is 2
参考:高级bash脚本编写指南。
一个简单的例子,将在执行脚本或调用函数时在脚本内部清除。
#!/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-separated value
# You can also pass parameters during executing the script
print_param_value "$1" "$2" # Parameter $1 and $2 during execution
# Suppose our script name is "param_example".
# Call it like this:
#
# ./param_example 5 5
#
# Now the parameters will be $1=5 and $2=5
如果您更喜欢命名形参,则可以(使用一些技巧)实际将命名形参传递给函数(也可以传递数组和引用)。
我开发的方法允许你像这样定义传递给函数的命名参数:
function example { args : string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}
你也可以注解参数为@required或@readonly, create…其余参数,从顺序参数创建数组(例如使用字符串[4]),并可选地在多行中列出参数:
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[*]}"
}
换句话说,您不仅可以通过名称调用参数(这使核心更具可读性),还可以实际传递数组(以及对变量的引用——该特性仅在Bash 4.3中有效)!另外,映射的变量都在局部作用域中,就像$1(和其他变量)一样。
实现这一功能的代码非常简单,并且可以在Bash 3和Bash 4中运行(这是我测试过的唯一版本)。如果您对更多这样的技巧感兴趣,可以让bash开发变得更好更简单,您可以看看我的bash Infinity Framework,下面的代码是它的功能之一。
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 parameter:
shift
fi
done
echo "${evalString} local -i __paramIndex=${paramIndex};"
}
alias args='local __previousTrap=$(trap -p DEBUG); trap "eval \"\$(assignTrap \$BASH_COMMAND)\";" DEBUG;'
另一种向Bash传递命名参数的方法…是通过引用传递的。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];
Bash 4.3的另一种语法是使用nameref。
尽管nameref无缝地取消了引用,因此更加方便,但一些较旧的受支持发行版仍然发布了较旧的版本,因此我暂时不推荐使用它。
去掉括号和逗号:
myBackupFunction ".." "..." "xx"
函数应该是这样的:
function myBackupFunction() {
# Here $1 is the first parameter, $2 the second, etc.
}