【问题标题】:Match Substring from Command Output匹配来自命令输出的子字符串
【发布时间】:2011-10-08 18:04:13
【问题描述】:

已经回答了这个问题的一些密切候选者,我已经尝试了几种方法来尝试解决这个问题。具体来说,我的场景是这样的:

我有一组实用程序名称,它们可能会或可能不会安装在 linux 机器上(例如:ssh、sudo 等),所以我试图根据尝试的结果检查实用程序是否存在依次调用实用程序。我正在尝试在 bash 中执行此操作。 Bash 版本是 4.1.5(1),在 Ubuntu 10.10 上运行,但计划部署在 BusyBox 上。

如果该实用程序不存在,那么通常您会收到一条消息“未找到”,或者它包含该确切字符串。否则,您会收到一条使用消息。我已经为我使用的 grep 尝试了一些正则表达式,但没有任何区别,这让我相信我的代码存在更根本的缺陷。

我完全知道有一些实用程序可以执行此操作,但是在我工作的环境中,我无法访问 dpkg 之类的东西来检查实用程序/包。简而言之,我计划部署它的环境没有包管理。

我的大致是这样的:

#!/bin/bash
TOOLS=( 'ssh' 'soodo' 'dhclient' 'iperf')
#list of tools is abridged for convenience and added 'soodo' as a sure miss

#add a ridiculous option flag so don't accidentally trip any real flags
if `echo ${TOOLS[0]} -222222 | grep -q "not found"`; then
echo "${TOOLS[0]} is not installed."
else echo `${TOOLS[0]} --version`

#I am aware that --version is not applicable for all utilities, but this is just
#for sake of example.

我的问题是 if 似乎从未被准确地拾取。如果我在它周围加上 ` 标记,要么在 if 上产生误报或误报(例如:像 soodo 这样的程序在不存在时会被声称存在,而像 ssh 这样的程序会被报告为未安装,即使它是) .

如果你们需要进一步说明我正在尝试做什么或类似的事情,请询问。这是我能提供的最少的回报,以换取其他人的一些见解。

【问题讨论】:

  • 您应该使用which 而不是调用无效命令。解析错误消息是一个坏习惯,因为它旨在帮助用户使用其自然语言。例如,在法语系统上,您永远不会看到“未找到”字符串。
  • 不要那么肯定“-222222”是一个荒谬的选择。对于许多选项解析器,“-abcd”与“-a -b -c d”相同,因此“-222222”为“-2 -2 -2 -2 -2 -2”。 ssh 确实有一个有效的选项“-2”

标签: bash packages substring busybox


【解决方案1】:

对于 bash,type 是确定命令是 PATH 中的程序、函数还是别名的方法。

TOOLS=( 'ssh' 'soodo' 'dhclient' 'iperf')
for tool in "${TOOLS[@]}"; do
  if type -p "$tool" > /dev/null; then
    echo "$tool is installed"
  else
    echo "$tool is not installed"
  fi
done

你正在做的错误:

if `echo ${TOOLS[0]} -222222 | grep -q "not found"`; then

那里发生了什么:

  • 首先,echo ${TOOLS[@]} -222222 将“ssh -222222”打印到标准输出
  • 管道进入grep -q "not found",它不会向标准输出打印任何内容
  • 反引号将管道的输出(一个空行,始终是grep -q 的输出)替换为if 命令,因此您得到if <a newline> ; then

您将得到与if $(printf "\n"); then echo Y; else echo N; fi 相同的结果,这始终是正确的。

要做你想做的事,你必须写:

if "${TOOLS[0]}" -222222 2>&1 | grep -q "not found"; then ...

这将执行管道,然后if 将考虑退出状态。退出状态为零被认为是真,任何其他退出状态被认为是假。

但是,不要这样做来确定程序是否存在。

【讨论】:

    【解决方案2】:
    #!/bin/bash
    TOOLS=( 'ssh' 'soodo' 'dhclient' 'iperf')
    #list of tools is abridged for convenience and added 'soodo' as a sure miss
    
    for TOOL in ${TOOLS[@]}
    do
      which $TOOL > /dev/null
      RESULT=$?
      if [ $RESULT -eq 0 ]
      then
        echo $TOOL is available
      else
        echo $TOOL is not available
      fi
    done
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多