我正在尝试搜索如何在Bash函数中传递参数,但是出现的总是总是如何从命令行传递参数。
我想在脚本中传递参数。我试过了:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
但是语法不正确,如何将参数传递给我的函数?
我正在尝试搜索如何在Bash函数中传递参数,但是出现的总是总是如何从命令行传递参数。
我想在脚本中传递参数。我试过了:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
但是语法不正确,如何将参数传递给我的函数?
Answers:
声明函数有两种典型的方法。我更喜欢第二种方法。
function function_name {
command...
}
要么
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
function name() {}
。也许之前有一个“ enter”{}
function
关键字和的()
。我的目标(在文件中,而不是在命令行中)是提高清晰度,而不是减少键入的字符数,即function myBackupFunction() compound-statement
。
function
关键字版本是扩展名;另一种形式适用于所有POSIX兼容shell。
function
关键字在引入它的旧的ksh-family shell中也保证了现代bash不兑现(在此类shell中,function
默认情况下将变量设置为local;在bash中, 它不是)。这样,它的使用会降低对ksh行为了解并可能期望的人的清晰度。参见wiki.bash-hackers.org/scripting/obsolete
熟悉高级编程语言(C / C ++ / Java / PHP / Python / Perl ...)会向外行暗示,bash函数应该像在其他语言中一样工作。相反,bash函数的工作方式类似于shell命令,并且期望将参数传递给它们的方式与可能将选项传递给shell命令的方式相同(例如ls -l
)。实际上,bash中的函数参数被视为位置参数($1, $2..$9, ${10}, ${11}
,依此类推)。考虑到getopts
工作原理,这不足为奇。不要使用括号在bash中调用函数。
(注意:目前,我碰巧正在使用Open Solaris。)
# 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
想要使用变量名称。就是这样
declare filename=$1 # declare gives you more options and limits variable scope
想要将数组传递给函数吗?
callingSomeFunction "${someArray[@]}" # Expands to all array elements.
在函数内部,像这样处理参数。
function callingSomeFunction ()
{
for value in "$@" # You want to use "$@" here, not "$*" !!!!!
do
:
done
}
需要传递值和数组,但仍在函数内部使用“ $ @”吗?
function linearSearch ()
{
declare myVar="$1"
shift 1 # removes $1 from the parameter list
for value in "$@" # Represents the remaining parameters.
do
if [[ $value == $myVar ]]
then
echo -e "Found it!\t... after a while."
return 0
fi
done
return 1
}
linearSearch $someStringValue "${someArray[@]}"
如果您更喜欢命名参数,则可以(通过一些技巧)将命名参数实际传递给函数(也可以传递数组和引用)。
我开发的方法允许您定义传递给函数的命名参数,如下所示:
function example { args : string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}
您还可以将参数注释为@required或@readonly,创建... rest参数,根据顺序参数创建数组(使用eg string[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 param:
shift
fi
done
echo "${evalString} local -i __paramIndex=${paramIndex};"
}
alias args='local __previousTrap=$(trap -p DEBUG); trap "eval \"\$(assignTrap \$BASH_COMMAND)\";" DEBUG;'
@var
,@reference
,@params
变量?我应该在互联网上查找哪些内容以了解更多信息?
ucommon
和我的代码之间没有关系。您可能安装了一些导致您提到的问题的工具,不知道会是什么。
错过括号和逗号:
myBackupFunction ".." "..." "xx"
该函数应如下所示:
function myBackupFunction() {
# here $1 is the first parameter, $2 the second etc.
}
我希望这个例子能对您有所帮助。它从用户那里获得两个数字,并将它们提供给所调用的函数add
(在代码的最后一行),然后add
将它们求和并打印出来。
#!/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
一个简单的示例,它将在执行脚本期间或在调用函数时在脚本内部清除。
#!/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
以为我会提到另一种将命名参数传递给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