【问题标题】:ipv6 value assigned to a variable in bash script behaves wrong分配给 bash 脚本中变量的 ipv6 值行为错误
【发布时间】:2020-01-12 13:11:34
【问题描述】:

我遇到过一种情况,我用 ipv6 地址分配了一个变量,然后尝试通过将 ipv6 与方括号 [] 连接来执行操作。在其中一种情况下,bash 执行 [] 中存在的任何内容并将整个值替换为 1。

类似的东西

#!/bin/sh
llipv6=xxxx::xxxx:xxxx:xxxx:3a17%bond0
echo "/bin/bash -c "$REST_CLI serverlogs --url [$llipv6]""

当我运行脚本时,输出是

/bin/bash -c "abc.sh serverlogs --url 1

这里发生的另一件令人惊奇的事情是,如果我将 ipv6 地址的最后两位数更改为 19 以上,它会正确打印

llipv6=xxxx::xxxx:xxxx:xxxx:3a21%bond0
echo "/bin/bash -c "$REST_CLI serverlogs --url [$llipv6]""

输出是 /bin/bash -c "abc.sh serverlogs --url [xxxx::xxxx:xxxx:xxxx:3a21%bond0]

我不明白这里的问题。

我刚刚修改了连接 ipv6 的方式,如下所示,它似乎工作正常。

#!/bin/sh
llipv6=xxxx::xxxx:xxxx:xxxx:3a17%bond0
echo "/bin/bash -c "$REST_CLI serverlogs --url "[$llipv6]"""

请提出正确的方法。

提前致谢。

【问题讨论】:

  • 大多数示例都有错字:您设置了llipv6,但尝试回显llipv5

标签: bash shell echo posix


【解决方案1】:

为什么它不起作用

您在滥用 shell 引用。

你不能像你一样嵌套双引号 ("something1 "something2"")。

sh 看到时

echo "/bin/bash -c "$REST_CLI serverlogs --url [$llipv6]""

它会看到字符串/bin/bash -c $REST_CLIserverlogs--url[$llipv6](附加一个空字符串"",它什么都不做)。

现在,由于您滥用了 shell 引号,我将假设您分配 REST_CLI 的方式导致它具有值 "abc.sh(带有前导双引号)。

因此,shell 将/bin/bash -c $REST_CLI 解释为/bin/bash -c "abc.shserverlogs--url 的解释很好。但随后我们到达[$llipv6]

在 POSIX shell 中,语法 [some-letters] 是一个 glob 模式。就像* 指的是“所有以文件名结尾的东西”,[abc] 指的是“所有以a、b 或c 结尾的文件名”。

示例:

$ ls
aaa  bbb  ccc
$ echo [ab]*
aaa bbb

所以当shell看到[$llipv6]时,它会变成[llipv6=xxxx::xxxx:xxxx:xxxx:3a17%bond0],这是一个匹配每个文件的全局模式,如果它的名字是:%0137abdnox

因此,在您运行此脚本的目录中,您有一个名为 1 的文件,这就是为什么最后您得到的是 1 而不是 IPv6 地址,也是为什么当您超过 19,1 不再是全局字符。

然后 posix shell 的另一个神秘行为开始了。如果 glob 模式不匹配任何文件,那么它不会返回 0 个文件,而是返回模式,在“19 以上”的情况下 - [xxxx::xxxx:xxxx:xxxx:3a21%bond0] - 这就是它的原因工作正常。

还要注意你修改的方式:

echo "/bin/bash -c "$REST_CLI serverlogs --url "[$llipv6]"""

she shell 看到前 3 个字符串是一样的,只是现在它看到 "[$llipv6]" 被引用,当它被引用时,不应用通配符,这就是为什么这个版本也能正常工作的原因。

如何让它工作

关于嵌套的 shell 引用,在 "" 内,您可以使用 '' 进行引用(反之亦然):

#!/bin/sh
llipv6=xxxx::xxxx:xxxx:xxxx:3a17%bond0
echo "/bin/bash -c '$REST_CLI serverlogs --url [$llipv6]'"

在双引号字符串中,' 没有特殊含义。输出:

/bin/bash -c 'abc.sh serverlogs --url [xxxx::xxxx:xxxx:xxxx:3a17%bond0]'

如果您将输出作为命令运行,那么单引号 (') 将启动并正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多