我试图搜索如何在Bash函数中传递参数,但出现的总是如何从命令行传递参数。
我想在脚本中传递参数。我试着:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
但是语法不正确。如何将参数传递给函数?
我试图搜索如何在Bash函数中传递参数,但出现的总是如何从命令行传递参数。
我想在脚本中传递参数。我试着:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
但是语法不正确。如何将参数传递给函数?
当前回答
对高级编程语言(C/ c++, Java, PHP, Python, Perl等)的了解会向外行建议,Shell (Bash)函数应该像在其他语言中那样工作。
相反,Bash函数的工作方式类似于shell命令,并且期望将参数传递给它们的方式与传递选项给shell命令的方式相同(例如ls -l)。实际上,Bash中的函数参数被视为位置参数($1,$2..$9, ${10}, ${11},等等)。考虑到getopts的工作方式,这并不奇怪。在Bash中,不要使用圆括号来调用函数。
(注:我现在正好在OpenSolaris上工作。)
# 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
想要为变量使用名称?做点这样的事。
local filename=$1 # The keyword declare can be used, but local is semantically more specific.
不过要小心。如果函数的参数中有空格,您可能想要这样做!否则,1美元可能不是你想的那样。
local filename="$1" # Just to be on the safe side. Although, if $1 was an integer, then what? Is that even possible? Humm.
想通过值将数组传递给函数?
callingSomeFunction "${someArray[@]}" # Expands to all array elements.
在函数内部,像这样处理参数。
function callingSomeFunction ()
{
for value in "$@" # You want to use "$@" here, not "$*" !!!!!
do
:
done
}
需要传递一个值和一个数组,但仍然使用“$@”内部的函数?
function linearSearch ()
{
local 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[@]}"
在Bash 4.3及以上版本中,通过使用-n选项定义函数的形参,可以通过引用将数组传递给函数。
function callingSomeFunction ()
{
local -n someArray=$1 # also ${1:?} to make the parameter mandatory.
for value in "${someArray[@]}" # Nice!
do
:
done
}
callingSomeFunction myArray # No $ in front of the argument. You pass by name, not expansion / value.
其他回答
另一种向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无缝地取消了引用,因此更加方便,但一些较旧的受支持发行版仍然发布了较旧的版本,因此我暂时不推荐使用它。
对高级编程语言(C/ c++, Java, PHP, Python, Perl等)的了解会向外行建议,Shell (Bash)函数应该像在其他语言中那样工作。
相反,Bash函数的工作方式类似于shell命令,并且期望将参数传递给它们的方式与传递选项给shell命令的方式相同(例如ls -l)。实际上,Bash中的函数参数被视为位置参数($1,$2..$9, ${10}, ${11},等等)。考虑到getopts的工作方式,这并不奇怪。在Bash中,不要使用圆括号来调用函数。
(注:我现在正好在OpenSolaris上工作。)
# 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
想要为变量使用名称?做点这样的事。
local filename=$1 # The keyword declare can be used, but local is semantically more specific.
不过要小心。如果函数的参数中有空格,您可能想要这样做!否则,1美元可能不是你想的那样。
local filename="$1" # Just to be on the safe side. Although, if $1 was an integer, then what? Is that even possible? Humm.
想通过值将数组传递给函数?
callingSomeFunction "${someArray[@]}" # Expands to all array elements.
在函数内部,像这样处理参数。
function callingSomeFunction ()
{
for value in "$@" # You want to use "$@" here, not "$*" !!!!!
do
:
done
}
需要传递一个值和一个数组,但仍然使用“$@”内部的函数?
function linearSearch ()
{
local 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[@]}"
在Bash 4.3及以上版本中,通过使用-n选项定义函数的形参,可以通过引用将数组传递给函数。
function callingSomeFunction ()
{
local -n someArray=$1 # also ${1:?} to make the parameter mandatory.
for value in "${someArray[@]}" # Nice!
do
:
done
}
callingSomeFunction myArray # No $ in front of the argument. You pass by name, not expansion / value.
一个简单的例子,将在执行脚本或调用函数时在脚本内部清除。
#!/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脚本编写指南。
去掉括号和逗号:
myBackupFunction ".." "..." "xx"
函数应该是这样的:
function myBackupFunction() {
# Here $1 is the first parameter, $2 the second, etc.
}