我试图搜索如何在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.
}