我无法别名 def $?="type $? || echo 'varible not defined' "

我无法别名 def $?="type $? || echo 'varible not defined' "

我想创建一个名为 def 的别名,它接受一个变量并检查它是否已定义。如果没有,def 会打印“变量未定义”。

答案1

如果给定的变量名称为空或未定义,以下函数将打印错误消息:

def() { : "${!1:? "Variable not defined."}" ; }

例子:

$ def PATH
$ def NONESUCH
bash: !1:  Variable not defined.

此功能需要bash

解释:

函数主体由一个命令组成,该命令被赋予一个参数。命令是,其:作用类似于无操作。该命令的参数是"${!1:? "Variable not defined."}"。在bash,构造中${!1},返回由 给出名称的变量的值$1,该变量是函数的第一个参数。如果名称为 的变量$1已设置且不为空,则返回其值。由于是无操作,因此"${!1:? "Variable not defined."}"其值被忽略。如果具有该名称的变量未设置或为空,则由于参数扩展构造,将返回给定的错误消息。:::?

改进的输出格式

上述函数没有返回确切地您请求的消息。我们可以修复此问题:

$ def() { ( : "${!1:? "Variable  not defined."}" ) 2>&1 | sed 's/^bash: !1:  //'; }
$ def NONESUCH
Variable not defined.

或者,

$ def() { ( : "${!1:?}" ) 2>/dev/null || echo "Variable not defined"; }
$ def NONESUCH
Variable not defined

答案2

自 Ubuntu 12.04 LTS 以来(可能更早一些,但不是最早可追溯至 10.04 LTS)Ubuntu 中的版本bash至少为 4.2因此支持、和的运算-vtest[[[ 内置

如果你只学习一种方法来测试 bash 中变量是否定义,那么它可能应该是参数扩展John1024 的优秀答案中使用的技术。尽管使用 bash 4.1 及更早版本的 Ubuntu 系统越来越不常见,10.04 仍然提供有限的服务器支持,并且早期版本的 bash 在其他一些 GNU/Linux 系统(和其他类 Unix 操作系统)上更为常见。

但是如果你有 bash 4.2 或更高版本,那么来自John1024 的回答可以进一步简化为:

def() { [ -v "$1" ] || echo 'Variable not defined'; }

请注意,如果foo是您感兴趣的变量的名称,[ -v foo ]--不是 [ -v $foo ]--测试是否已定义。在本例中,我有,$1因为传递给的第一个位置参数def将包含要测试的变量的名称作为其价值。($在我的例子中,间接!通过${...}表达实现John1024 的示例

ek@Ilex:~$ def() { [ -v "$1" ] || echo 'Variable not defined'; }
ek@Ilex:~$ def PATH
ek@Ilex:~$ def NONESUCH
Variable not defined

我的和John1024的 def 实现将打印Variable not defined

  • 当不存在作为函数第一个参数传递的名称的变量时
  • 但是也当没有第一个参数传递给时def

那是:

ek@Ilex:~$ def
Variable not defined

def如果您希望在这种情况下收到单独的消息,则可以单独处理不接收任何参数的情况:

def() {
    if [ $# -eq 0 ]; then
        echo 'error: too few arguments' >&2
        return 1
    elif [ ! -v "$1" ]; then
        echo 'Variable not defined'
    fi
}

我写这篇文章是基于这样的想法:如果 的def第一个参数存在,无论它是否命名了定义的变量,都被视为正常操作,而不是错误。相反,不传递任何参数是def一个错误,我是这样处理的:

  • >&2 发送输出echo标准误差

  • return 1使def返回非零退出状态,表示失败。(这主要用于当出现调用def而不是复合语句或脚本时,尽管也可以使用检查最后一个命令的退出状态echo $?。)

    在其他情况下def将返回默认退出状态 0(当然,除非出现其他错误,例如echo无法Variable not defined写入标准输出)。

ek@Ilex:~/source$ def NONESUCH
Variable not defined
ek@Ilex:~/source$ def
error: too few arguments

答案3

根据高级 Bash 脚本指南

在脚本中,别名的用处非常有限。如果别名可以承担 C 预处理器的某些功能(例如宏扩展),那就太好了,但不幸的是,Bash 不会扩展别名主体内的参数。[117] 此外,脚本无法在“复合结构”(例如 if/then 语句、循环和函数)内扩展别名本身。另一个限制是别名不会递归扩展。几乎无一例外,我们希望别名执行的任何操作都可以用函数更有效地完成。

这就是为什么你应该关注 Eliah Kagan 或 John1024 的回答。

相关内容