匹配命令输出中的子字符串

发布于 2024-11-24 17:39:37 字数 1116 浏览 1 评论 0原文

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

我有一个实用程序名称数组,这些实用程序名称可能安装在 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 似乎永远不会被准确地拾取。如果我在它周围 tweark ` 标记,则在 if 上会产生误报或漏报(例如:像 soodo 这样的程序在不存在时将被声称存在,而像 ssh 这样的程序将被报告为未安装,即使它已安装) 。

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

There are some close candidates for this question having already been answered, and I've tried several methods of trying to solve the issue. Specifically, my scenario is this:

I have an array of utility names that may or may NOT be installed on a linux machine (e.g.: ssh, sudo, etc.), so I am trying to check if the utility exists or not based on the result of trying to invoke the utilities in turn. I'm trying to do this in bash. Bash version is 4.1.5(1) running on Ubuntu 10.10 but planned to deploy on BusyBox.

If the utility doesn't exist, then usually you get a message saying "not found" or it includes that exact string. Otherwise you get a usage message. I have tried some regex expressions for the grep I use, but it hasn't made any difference, which leads me to believe there is something more fundamentally flawed with my code.

I am fully aware there are utilities that do this, but with the environment I am working in I do not have access to things like dpkg to check utilities/packages. In short, the environment I plan to deploy this on has NO PACKAGE MANAGEMENT.

What I have roughly goes like this:

#!/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.

My problem is that the if never seems to be accurately picked up. If I tweark ` marks around it either creates false positives or false negatives on the if (e.g.: a program like soodo will be claimed to exist when it doesn't, and something like ssh will be reported as not installed even though it is).

If you guys need any further clarification on what I'm trying to do or the like, please ask. It's the least I can provide back in exchange for some insight by others.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

老子叫无熙 2024-12-01 17:39:37
#!/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
#!/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
白龙吟 2024-12-01 17:39:37

对于 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 find” 不会向 stdout 打印任何
  • 内容,反引号将管道的输出(空行,始终是 grep -q 的输出)替换为if 命令,所以你会得到 if ; ;然后

你会得到与 if $(printf "\n"); 相同的结果然后回显 Y;否则回显N; fi 始终为真。

要执行您尝试的操作,您必须编写:

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

这将执行管道,然后 if 将考虑退出状态。退出状态零被视为 true,任何其他退出状态都被视为 false。

但是,不要这样做来查明程序是否存在。

For bash, type is the way to determine if a command is a program in your PATH, or a function or an alias.

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

The errors in what you're doing:

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

What's happening there:

  • first, echo ${TOOLS[@]} -222222 prints "ssh -222222" to stdout
  • that pipes into grep -q "not found" which prints nothing to stdout
  • the backticks substitute the output from the pipeline (a blank line, which is always the output from grep -q) into the if command, so you get if <a newline> ; then

You'll get the same result as if $(printf "\n"); then echo Y; else echo N; fi which is always true.

To do what you're attempting, you'd have to write:

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

That will execute the pipeline and then if will consider the exit status. Exit status zero is considered true, any other exit status is considered false.

However, don't do this to find out if a program exists.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文