为什么在Bash脚本中需要使用"declare -f"和"declare -a"?

22

抱歉问的问题很简单-我只是想弄明白...

例如,我有:

$ cat test.sh
#!/bin/bash
declare -f testfunct

testfunct () {
echo "I'm function"
}

testfunct

declare -a testarr

testarr=([1]=arr1 [2]=arr2 [3]=arr3)

echo ${testarr[@]}

当我运行它时,我得到:

$ ./test.sh
I'm function
arr1 arr2 arr3

那么问题来了 - 如果我必须(如果我必须...)在这里插入declare,为什么要这样做呢?

我可以理解例如declare -i vardeclare -r var。但是-f(声明函数)和-a(声明数组)是用来干什么的呢?


1
declare 最常见的用法是在函数内部,当没有给出标志时,它的行为与 local 相同。对于某些数据类型,例如关联数组,使用 declare -A 可能也是必要的。当想要明确告诉读者你有意在函数内部引用全局变量时,declare -g 是一个非常有用的特性,而不仅仅是忘记声明并隐式地将其设置为全局变量。 - Charles Duffy
3个回答

16

declare -f functionname 命令用于输出函数 functionname 的定义,如果它存在的话,并且绝不会声明 functionname 是/将是一个函数。请看下面的示例:

$ unset -f a # unsetting the function a, if it existed
$ declare -f a
$ # nothing output and look at the exit code:
$ echo $?
1
$ # that was an "error" because the function didn't exist
$ a() { echo 'Hello, world!'; }
$ declare -f a
a () 
{ 
    echo 'Hello, world!'
}
$ # ok? and look at the exit code:
$ echo $?
0
$ # cool :)

在您的情况下,declare -f testfunct 没有任何作用,除非 testfunct 存在,它会在标准输出上输出其定义。

7
据我所知,单独使用 -a 选项没有任何实际意义,但我认为在声明数组时对可读性有所帮助。当与其他选项结合使用以生成特定类型的数组时,它变得更加有趣。
例如:
# Declare an array of integers
declare -ai int_array

int_array=(1 2 3)

# Setting a string as array value fails
int_array[0]="I am a string"

# Convert array values to lower case (or upper case with -u)
declare -al lowercase_array

lowercase_array[0]="I AM A STRING"
lowercase_array[1]="ANOTHER STRING"

echo "${lowercase_array[0]}"
echo "${lowercase_array[1]}"

# Make a read only array
declare -ar readonly_array=(42 "A String")

# Setting a new value fails
readonly_array[0]=23

1
显然,-l-u仅适用于Bash 4+。 - Kevin

5

declare -f 命令可以列出所有定义的函数(或已引用的函数)及其内容。

使用示例:

[ ~]$ cat test.sh
#!/bin/bash

f(){
    echo "Hello world"
}

# print 0 if is defined (success)
# print 1 if isn't defined (failure)
isDefined(){
    declare -f "$1" >/dev/null && echo 0 || echo 1
}

isDefined f
isDefined g
[ ~]$ ./test.sh 
0
1
[ ~]$ declare -f
existFunction () 
{ 
    declare -f "$1" > /dev/null && echo 0 || echo 1
}
f () 
{ 
    echo "Hello world"
}

然而,就像下面的gniourf_gniourf聪明地说的那样:最好使用declare -F来测试函数是否存在。


4
要检查一个函数是否存在,最好使用 declare -F - gniourf_gniourf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接