Linux 如何使用bash准确确定文件中是否未定义变量

Linux 如何使用bash准确确定文件中是否未定义变量,linux,bash,variables,Linux,Bash,Variables,具有以下包含ip_地址变量的文本文件。文件如下 $ cat file ip_address=10.78.1.0 filename=test.bin $ cat file filename=test.bin $ cat file ip_address= filename=test.bin 现在有了bash脚本,可以检查ip_地址是否已定义或可用 #!/bin/bash for list in $(cat file) do eval $list done ${ip_Ad

具有以下包含ip_地址变量的文本文件。文件如下

$ cat file
ip_address=10.78.1.0
filename=test.bin
$ cat file
  filename=test.bin
$ cat file
  ip_address=
  filename=test.bin
现在有了bash脚本,可以检查ip_地址是否已定义或可用

#!/bin/bash

for list in $(cat file)
do
    eval $list
done

${ip_Address:?Error \$IP_Address is not defined}

[ -z ${ip_Address:-""} ] && printf "No IPaddress\n" || echo "$ip_Address"
现在,若我的文件不包含ip_地址变量的行,那个么脚本在这里中断,但若在那个里,那个么它再次检查ip_地址是否包含not的任何值

但是如果变量不可用,我不想破坏我的脚本,而是想做些什么

在尝试使用-z标志后,实际上该标志检查变量是否为空,但不检查像这样的变量的可用性

if [ -z  $ip_Address ]
then
    #do something
else 
    #rest of code
fi
但它在以下条件下失败

案例1: 如果我的文件如下

$ cat file
ip_address=10.78.1.0
filename=test.bin
$ cat file
  filename=test.bin
$ cat file
  ip_address=
  filename=test.bin
那么如果。。块,所以这不是问题

案例2:

如果我的文件如下

$ cat file
ip_address=10.78.1.0
filename=test.bin
$ cat file
  filename=test.bin
$ cat file
  ip_address=
  filename=test.bin
那么它必须进入其他地方。。阻止,但它没有。所以这是个问题


那么,我如何区分bash中定义的变量和可用的变量呢?

对于我来说,以下几行可以完成这项工作:

#!/bin/bash

if test $# -ne 1;
then
    echo "Usage: check_for_ip.sh infile"
    exit
fi

. $1

test -z "${ip_address}" && echo "No IP address" || echo "IP address is: ${ip_address}"
测试文件:

$ cat file1 
ip_address=
filename=test.bin
$ cat file2 
ip_address=10.78.1.0
filename=test.bin
$ cat file3
filename=test.bin
测试结果:

$ bash check_for_ip.sh file1
No IP address
$ bash check_for_ip.sh file2
IP address is: 10.78.1.0
$ bash check_for_ip.sh file3
No IP address

我不确定我是否理解这个问题,因为这看起来很像你的解决方案;也许你只是错过了测试中的测试。

对我来说,以下几行就可以完成这项工作:

#!/bin/bash

if test $# -ne 1;
then
    echo "Usage: check_for_ip.sh infile"
    exit
fi

. $1

test -z "${ip_address}" && echo "No IP address" || echo "IP address is: ${ip_address}"
测试文件:

$ cat file1 
ip_address=
filename=test.bin
$ cat file2 
ip_address=10.78.1.0
filename=test.bin
$ cat file3
filename=test.bin
测试结果:

$ bash check_for_ip.sh file1
No IP address
$ bash check_for_ip.sh file2
IP address is: 10.78.1.0
$ bash check_for_ip.sh file3
No IP address
我不确定我是否理解这个问题,因为这看起来很像你的解决方案;可能您只是缺少测试中的标记。

使用测试的-n标记而不是-z

这将测试变量是否有内容,还将确定变量是否未设置

if [ -n "$ip_Address" ]
then
    # ip_address is set 
else 
    # ip_address is no content OR is not set
fi
使用测试的-n标志代替-z

这将测试变量是否有内容,还将确定变量是否未设置

if [ -n "$ip_Address" ]
then
    # ip_address is set 
else 
    # ip_address is no content OR is not set
fi

可以使用${var value}替换区分未设置、设置但为空和非空

case ${ip_address-UNSET} in UNSET) echo "It's unset." ;; esac
case ${ip_address:-EMPTY} in EMPTY) echo "It's set, but empty." ;; esac
case ${ip_address:+SET} in SET) echo "It's set and nonempty." ;; esac
这只是为了示范;你的逻辑可能会完全不同


另请参见

您可以使用${var value}替换区分未设置、设置但为空和非空

case ${ip_address-UNSET} in UNSET) echo "It's unset." ;; esac
case ${ip_address:-EMPTY} in EMPTY) echo "It's set, but empty." ;; esac
case ${ip_address:+SET} in SET) echo "It's set and nonempty." ;; esac
这只是为了示范;你的逻辑可能会完全不同

另请参见

如果您使用的是最新的bash 4.2,尽管4.3很快就会发布…,但是您可以使用-v条件运算符来测试是否设置了变量

if [[ -v ip_Address ]]; then
    printf "ip_Address is set\n";
fi
请注意,-v的参数是您正在测试的变量的名称,因此您不会在它前面加$。

如果您使用的是最新的bash 4.2,尽管4.3很快就会发布…,但是您可以使用-v条件运算符来测试是否设置了变量

if [[ -v ip_Address ]]; then
    printf "ip_Address is set\n";
fi

请注意,-v的参数是您正在测试的变量的名称,因此您不会在它前面加$。

此文件也是一个shell脚本吗?不,它是一个简单的文本文件。靠近开头的eval循环看起来既尴尬又危险。如果文件是可执行代码,为什么不简单地使用源文件?@tripleee您是对的,但源文件似乎不适合简单的文本文件,对吗?为什么不?如果你能评估它,你当然也能找到它的来源。这个文件也是一个shell脚本吗?不,它是一个像文本文件一样简单的文件。靠近开头的评估循环看起来既尴尬又危险。如果文件是可执行代码,为什么不简单地使用源文件?@tripleee您是对的,但源文件似乎不适合简单的文本文件,对吗?为什么不?如果你能计算它,你当然也能找到它的来源。根据你的结果,案例1和案例3看起来是一样的,我不想要这意味着案例1中有变量,但没有值,所以它是可以的,但案例3中变量不可用。所以需要区分这一点。根据您的结果,案例1和案例3看起来完全相同,我不想这样,这意味着案例1中有变量,但没有值,所以可以,但案例3中的变量不可用。所以需要区分这一点。这太棒了——当然我一直在问自己为什么Bash没有定义的函数。这是在哪里记录的?我有BashV4.3,我检查过:ManBash,ManTest,神话般的google。。。还在看。我自己也做了一些测试-v ip_地址,仅使用一个括号对[…]。此外,它还处理一个已定义的变量,该变量未使用未设置的ip_地址定义。这对我来说非常方便,因为我希望使用此功能像电灯开关一样打开/关闭单元测试;在过去,这些参数和变量大多被称为开关es,就像电灯开关一样。如果a是未定义的;它将只是处于:OFF的状态,就像:false,00,NULL,invalid,等等。合适的nothing也可以在这里看到。它在4.3的手册页中,至少我没有一个4.2便于检查,但它不是按照字母顺序与条件表达式的其余操作符一起。它位于列表的底部,就在字符串比较运算符前面,如==等。Found:和通过grep在手册页上。好的,谢谢。这太棒了——当然我一直在问自己为什么Bash没有定义的函数。这是在哪里记录的?我有bashv4.3an
我查过了:男人狂欢,男人测试,神话般的谷歌。。。还在看。我自己也做了一些测试-v ip_地址,仅使用一个括号对[…]。此外,它还处理一个已定义的变量,该变量未使用未设置的ip_地址定义。这对我来说非常方便,因为我希望使用此功能像电灯开关一样打开/关闭单元测试;在过去,这些参数和变量大多被称为开关es,就像电灯开关一样。如果a是未定义的;它将只是处于:OFF的状态,就像:false,00,NULL,invalid,等等。合适的nothing也可以在这里看到。它在4.3的手册页中,至少我没有一个4.2便于检查,但它不是按照字母顺序与条件表达式的其余操作符一起。它位于列表的底部,就在字符串比较运算符前面,如==等。Found:和通过grep在手册页上。好的,谢谢。