2017-03-09 69 views
0

我想知道如何声明一个变量而不向它赋值。据bash的文档,这应该是确定:bash - 声明一个变量而不指定值

声明[-aAfFgilnrtux] [-p] [名称[=值] ...]

声明变量和/或给他们的属性。

“= value”位是可选的,但使用“declare var”没有赋值似乎没有任何作用。

#!/bin/bash 

function check_toto_set() { 
    if [ -z "${toto+x}" ] ; then 
    echo toto not defined! 
    else 
    echo toto=$toto 
    echo toto defined, unsetting 
    unset toto 
    fi 
} 

function set_toto() { 
    declare -g toto 
} 

function set_toto_with_value() { 
    declare -g toto=somevalue 
} 

check_toto_set 
toto=something 
check_toto_set 
declare toto 
check_toto_set 
set_toto 
check_toto_set 
set_toto_with_value 
check_toto_set 

基本上我会期望有“toto not defined!”只为先“check_toto_set”,和所有其它的应该找到TOTO正在申报,即便是空的,但输出继电器是:

toto not defined! 
toto=something 
toto defined, unsetting 
toto not defined! 
toto not defined! 
toto=somevalue 
toto defined, unsetting 

我使用Ubuntu的

echo $BASH_VERSION 
4.3.46(1)-release 

庆典46年3月4日所以我误解了一些关于声明的内容,或者我测试了一个变量是否被设置为错误的方式? (我使用的信息来自How to check if a variable is set in Bash?

+0

顺便说一句,'unset'有效undeclares的变量;它不只是删除价值。 –

回答

3

您正在测试变量是否为设置为(甚至为空值)。这与它是否被宣布不同。

以确定它是否已经申报,您可以使用declare -p

varstat() { 
    if declare -p "$1" >/dev/null 2>&1; then 
    if [[ ${!1+x} ]]; then 
     echo "set" 
    else 
     echo "declared but unset" 
    fi 
    else 
    echo "undeclared" 
    fi 
} 

export -f varstat 

bash -c 'varstat toto'     # output: "undeclared" 
bash -c 'declare toto; varstat toto' # output: "declared but unset" 
bash -c 'declare toto=; varstat toto' # output: "set" 
+0

这应该工作,但不知何故,当我尝试它在BASH 3中工作,但不是BASH4 – XSen

+0

@XSen,导出的函数不能跨越版本边界工作(当然,不是*特定的*版本边界;格式因shellshock而重新编译)。因此,运行'export -f varstat'的shell需要与'bash -c'调用的版本相同。 –

+0

我只是在shell中测试“declare toto; declare -p toto”,没有任何功能。不知何故,这不适用于4.3.46(1) - 与Ubuntu LTS 16.04一起发布。但我已经从gnu.org下载了bash 4.4.0的源代码,构建它并在其中尝试了它,并且它可以正常工作....所以有一些有趣的东西与打包的版本一起进行(没有工作在Redhat 4.1.x上工作...) – XSen