如何从函数中捕获变量并将其作为参数发送给另一个函数?

时间:2016-03-20 16:29:19

标签: linux bash

我在函数中使用了另一个函数中定义的变量,来自同一个脚本,但是我收到错误。

  testare()
{
        find "$Home" -name "$({!i})"
        rez=$?
        test -d "$rez"
        t1=$?
        test -f "$rez"
        t2=$?

        if [ "$t1" -eq 0 ]
        then
                return 0
        elif [ "$t2" -eq 0 ]
        then
                return 1
        else
                return 2
        fi
}

menu ()
{
        if [ "$#" -lt 2 ] || [ "$#" -gt 9 ]
        then
                echo "Error!"
                return
        fi

        for (( i=2; i <= "$#"; ++i ))
        do
                testare "$({!i})"
                rez=$?

                if [ "$rez" -eq 0 ]
                then
                        echo "Director with the same name exists!"
                fi

                if [ "$rez" -eq 1 ]
                then
                        echo "File with the same name already exists!"
                fi

                if [ "$rez" -eq 2 ]
                then
                        touch "$({!i})"
                fi
        done
}

menu $@

我的代码应该做什么:我用最多9个参数调用我的脚本,第一个指示我必须使用其他参数的名称创建文件的位置。首先,我必须检查我的光盘上是否已存在这些名称。 FOR的使用是强制性的。

由于i变量,错误显示在****行上。我认为“我”当时不可用。我怎么能做这个工作? :(

我还尝试在另一个文件中写入该函数并将其源于菜单,结果相同..

2 个答案:

答案 0 :(得分:2)

您可以尝试此操作(脚本中的注释和建议):

 `notificationmanager.notify(NOTIFY_ID, notification);
  startForeground(NOTIFY_ID, notification);`

答案 1 :(得分:2)

您可以删除testare并在一个例程中执行脚本功能,如下所示:

#!/bin/bash

menu() {
    if [ "$#" -lt 2 ] || [ "$#" -gt 9 ]; then
        echo "Error!"
        exit 1
    fi
    for (( i = 2; i <= "$#"; i++ )); do
        if [ -d "$1/${!i}" ]; then
            printf "Directory '%s' already exists! \n" "${!i}"
        elif [ -f "$1/${!i}" ]; then
            printf "File '%s' already exists! \n" "${!i}"
        else 
            touch "$1/${!i}"
        fi
    done
    exit 0
}

menu "$@"

但是如果你想按原样使用这两个例程,那么你可以按如下方式修改你的脚本:

testare() {
    test -d "$1/$2"
    t1="$?"
    test -f "$1/$2"
    t2="$?"

    if [ "$t1" -eq 0 ]; then
        return 0
    elif [ "$t2" -eq 0 ]; then
        return 1
    else
        return 2
    fi
}

menu() {
    if [ "$#" -lt 2 ] || [ "$#" -gt 9 ]; then
        echo "Error!"
        exit 1
    fi
    for (( i = 2; i <= "$#"; i++ )); do
        testare "$1" "${!i}"
        rez="$?"

        if [ "$rez" -eq 0 ]; then
            printf "Directory '%s' already exists! \n" "${!i}"
        elif [ "$rez" -eq 1 ]; then
            printf "File '%s' already exists! \n" "${!i}"
        else
            touch "$1/${!i}"
        fi
    done
    exit 0
}

menu "$@"

记住:当您将任何变量作为参数传递时,$i访问该例程的参数,其中i被任意数字{{1}替换从左到右引用论证的位置。

例如,在您的脚本中,您在>=0内有$({!i}),但变量testare仅在i例程中定义,因此在menu例程中使用该变量{1}}会导致错误。为了访问传递给testare的参数,您应该直接访问它们,即。 testare$1等等,或者您应该定义一个变量(例如,在循环中),并使用该变量作为$2来访问某些变量${!j}

修改 - 对第一条评论的问题的解释:

例如,考虑您当前工作目录中有一个名为j的空文件夹。现在,您要在dir文件夹中创建文件onetwothree。因此,您将其传递给脚本:

dir

因此,$ ./script dir one two three "$1"=dir等。"$2"=one行测试test -d "$1/$2"是否为$2文件夹中的目录,即。{是否存在$1并且是目录。这是必要的,因为所有文件都需要在指定目录中进行测试和创建,该目录始终作为脚本的第一个参数(如您所述)。

在您的脚本中,由于dir/one正在测试是否存在命名文件/目录,testare将需要访问testare目录,因此传递了2个参数的原因行dir中的testare,其中第一个参数是testare "$1" "${!i}"目录,第二个参数是要测试的文件。

至于你应该调用一个方法的参数的问题,你应该根据需要传递尽可能多的参数,以使例程按照预期的那样进行。例如,例程dir需要具有testare目录和一些指定文件,以便它可以检查该文件是否存在于dir中。因此,使用dir调用testare dir somefile

另一方面,testare "$1" "${!i}"中的%s是&#34; string&#34;的占位符,其值在末尾提供。例如,

printf

编辑2 :如果要递归搜索$ printf "This is not a placeholder for %s \n" "numbers" This is not a placeholder for numbers $ printf "The placeholder for numbers is %s \n" "%d" The placeholder for numbers is %d $ printf "pi as a whole number equals %d\n" 3 pi as a whole number equals 3 目录以检查/home是否存在,您可以执行以下操作:

somefile