如何判断字符串是否未在 Bash shell 脚本中定义 [英] How to tell if a string is not defined in a Bash shell script

查看:27
本文介绍了如何判断字符串是否未在 Bash shell 脚本中定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我想检查空字符串,我会这样做

[ -z $mystr ]

但是如果我想检查变量是否已经定义了怎么办?还是 Bash 脚本没有区别?

解决方案

我认为 Vinko答案,虽然没有简单地说明.区分VAR是否设置但为空或未设置,可以使用:

if [ -z "${VAR+xxx}";];然后回显根本没有设置VAR";菲if [ -z "$VAR";] &&[ "${VAR+xxx}"=xxx"];然后回显VAR被设置但为空";菲

您可能可以将第二行的两个测试合并为一个:

if [ -z "$VAR";-a "${VAR+xxx}";=xxx"];然后回显VAR被设置但为空";菲

但是,如果您阅读 Autoconf 的文档,您会发现他们不建议将术语与 '-a' 结合使用,而是建议使用单独的简单测试与 & 结合使用.&.我没有遇到过有问题的系统;这并不意味着它们曾经不存在(但它们现在可能非常罕见,即使它们在遥远的过去并不那么罕见).

你可以找到这些的细节,以及其他相关的shell 参数扩展test[ 命令和 Bash 手册中的条件表达式.

<小时>

最近有人通过电子邮件向我询问了这个问题的答案:

<块引用>

你用了两个测试,我理解第二个,但不是第一个.更准确地说,我不明白变量扩展的必要性

if [ -z "${VAR+xxx}";];然后回显根本没有设置VAR";菲

这不会达到同样的效果吗?

if [ -z "${VAR}";];然后回显根本没有设置VAR";菲

公平的问题 - 答案是不,您的更简单的替代方案不会做同样的事情".

假设我在你测试之前写了这个:

VAR=

您的测试会说根本没有设置 VAR",但我的会说(暗示因为它没有回显)设置了 VAR,但它的值可能为空".试试这个脚本:

<代码>(取消设置 VARif [ -z "${VAR+xxx}";];然后回声JL:1 VAR根本没有设置";菲if [ -z "${VAR}";];然后回显MP:1 VAR 根本没有设置";菲VAR=if [ -z "${VAR+xxx}";];然后回声JL:2 VAR根本没有设置";菲if [ -z "${VAR}";];然后回显MP:2 VAR 根本没有设置";菲)

输出为:

<前>JL:1 VAR 根本没有设置MP:1 VAR 根本没有设置MP:2 VAR 根本没有设置

在第二对测试中,设置了变量,但设置为空值.这是 ${VAR=value}${VAR:=value} 符号的区别.${VAR-value}${VAR:-value}${VAR+value}$ 同上{VAR:+value},依此类推.

<小时>

正如 Gili 在他的 answer,如果您使用 set -o nounset 选项运行 bash,那么上面的基本答案将因 未绑定变量 而失败.很容易补救:

if [ -z "${VAR+xxx}";];然后回显根本没有设置VAR";菲如果 [ -z "${VAR-}";] &&[ "${VAR+xxx}"=xxx"];然后回显VAR被设置但为空";菲

或者你可以用 set +u 取消 set -o nounset 选项(set -u 等价于 set -o 名词集).

If I want to check for the null string I would do

[ -z $mystr ]

but what if I want to check whether the variable has been defined at all? Or is there no distinction in Bash scripting?

解决方案

I think the answer you are after is implied (if not stated) by Vinko's answer, though it is not spelled out simply. To distinguish whether VAR is set but empty or not set, you can use:

if [ -z "${VAR+xxx}" ]; then echo "VAR is not set at all"; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo "VAR is set but empty"; fi

You probably can combine the two tests on the second line into one with:

if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo "VAR is set but empty"; fi

However, if you read the documentation for Autoconf, you'll find that they do not recommend combining terms with '-a' and do recommend using separate simple tests combined with &&. I've not encountered a system where there is a problem; that doesn't mean they didn't used to exist (but they are probably extremely rare these days, even if they weren't as rare in the distant past).

You can find the details of these, and other related shell parameter expansions, the test or [ command and conditional expressions in the Bash manual.


I was recently asked by email about this answer with the question:

You use two tests, and I understand the second one well, but not the first one. More precisely I don't understand the need for variable expansion

if [ -z "${VAR+xxx}" ]; then echo "VAR is not set at all"; fi

Wouldn't this accomplish the same?

if [ -z "${VAR}" ]; then echo "VAR is not set at all"; fi

Fair question - the answer is 'No, your simpler alternative does not do the same thing'.

Suppose I write this before your test:

VAR=

Your test will say "VAR is not set at all", but mine will say (by implication because it echoes nothing) "VAR is set but its value might be empty". Try this script:

(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo "JL:1 VAR is not set at all"; fi
if [ -z "${VAR}" ];     then echo "MP:1 VAR is not set at all"; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo "JL:2 VAR is not set at all"; fi
if [ -z "${VAR}" ];     then echo "MP:2 VAR is not set at all"; fi
)

The output is:

JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all

In the second pair of tests, the variable is set, but it is set to the empty value. This is the distinction that the ${VAR=value} and ${VAR:=value} notations make. Ditto for ${VAR-value} and ${VAR:-value}, and ${VAR+value} and ${VAR:+value}, and so on.


As Gili points out in his answer, if you run bash with the set -o nounset option, then the basic answer above fails with unbound variable. It is easily remedied:

if [ -z "${VAR+xxx}" ]; then echo "VAR is not set at all"; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo "VAR is set but empty"; fi

Or you could cancel the set -o nounset option with set +u (set -u being equivalent to set -o nounset).

这篇关于如何判断字符串是否未在 Bash shell 脚本中定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆