【问题标题】:Bash pattern matching inside [[ test block[[ 测试块内的 Bash 模式匹配
【发布时间】:2016-10-07 18:05:38
【问题描述】:

我正在制作一个可以在多台机器上执行相同任务的脚本,如下所示:

#!/bin/bash
if [[ hostname = login.machine1 ]]; then
    #do things how they are done on machine1
    ...
elif [[ hostname = login.machine2 ]]; then
    #etc.
fi

问题:有些机器有多个登录节点,如login1.machine2login2.machine2等。我尝试过shell模式匹配和正则表达式,但它们都不起作用:

if [[ hostname = login?.machine2 ]]
if [[ hostname == login?.machine2 ]]
if [[ hostname =~ login[0-9].machine2 ]]
if [[ hostname =~ login[0-9]\.machine2 ]]

以及至少十几个类似的模式,带或不带引号等。如果 hostname = login1.machine2 OR login2.machine2 等,进行将返回 true 的测试的正确方法是什么?使用 [ 而不是 [[ 的东西的奖励积分。

【问题讨论】:

  • 我建议使用变量$HOSTNAME 或命令主机名的输出:$(hostname)
  • 不知道你用的是什么外壳。但在 bash if [[ $(hostname) = login?.machine2 ]] 中,这将检查主机名是否等于字符串“login?.machine2”

标签: regex bash shell pattern-matching


【解决方案1】:

您需要在主机名前加上 $ 才能使用该变量。

if [[ $hostname =~ login[0-9]\.machine2 ]]; then
   echo "ok"
fi

而对于单个[ (sh),正则表达式运算符=~ 是在bash 上添加的,因此应该不可能在本地使用sh。

【讨论】:

  • 这应该是命令hostname,而不是变量。一旦我用$(hostname) 替换它,我第一次尝试使用普通的shell 模式匹配就可以了,不需要正则表达式。成功!
【解决方案2】:

[[ hostname =~ ... ]] 应该调用命令hostname 还是你有一个名为hostname 的变量?使用$HOSTNAME 或命令替换$(hostname)

如果担心可移植性,可以使用 AWK,用老式命令替换:

if printf "%s\n" "`hostname`" | awk '!/login[[:digit:]]\.machine2/{exit 1}'; then
  printf "Matches...\n"
else
  printf "Doesn't match\n"
fi 

如果不是,我强烈推荐the answer by naab

【讨论】:

    【解决方案3】:

    命令hostname需要包装:

    if [[ $(hostname) = login?.machine2 ]]
    

    【讨论】:

      猜你喜欢
      • 2011-12-09
      • 2022-10-22
      • 2020-07-05
      • 2017-11-25
      • 1970-01-01
      • 2014-10-06
      • 1970-01-01
      • 2020-04-02
      • 1970-01-01
      相关资源
      最近更新 更多