且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何编写一个 Bash 函数来测试执行命令的输出?

更新时间:2023-11-23 22:47:46

试图以单个字符串的形式提供整个命令需要以各种不方便的方式引用.我建议您尝试一种稍微不同的方法,不需要这样做.

Trying to provide entire commands as a single string requires quoting in all kinds of inconvenient ways. I would suggest you try a slightly different approach that does not require that.

#!/bin/bash
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`

psa_test()
{
  local needle="$1"
  local name="$2"
  local -a command=("${@:3}")
  local result ; result=$("${command[@]}" 2>&1)
  echo "Result: $result"
  if
    [[ $result == *$needle* ]]
  then
    echo "[$green OK  $reset] $name"
  else
    echo "[$red ERROR $reset] $name"
  fi
  echo "        Command: ${command[@]} | Needle: $needle | Name: $name"
}

然后您可以通过将您的命令作为不带引号的字符串传递来调用您的函数,就像您在交互式 shell 中调用它一样,但将前两个参数放在前面.

Then you can call your function by passing your command as an unquoted string, exactly like you would call it in an interactive shell, but putting the first two arguments before.

psa_test "HTTP/1.1" "Testing google.com" curl -v google.com

一些注意事项:

  • 命令存储在一个数组中,并通过扩展其所有元素来执行,单独引用以防止分词(这就是 "${command[@]}" 所做的).

数组展开周围的双引号非常重要,因为它们告诉shell每个数组元素将数组展开一个字,并防止每个数组元素内部发生分词(允许数组元素包含空格,例如).

The double quotes around the array expansion are very important, because they tell the shell to expand the array one word per array element, and prevent word splitting from occurring inside each array element (to allow for array elements containing spaces, for instance).

你应该在函数内部声明你的局部变量.这不是绝对必要的,但是当您有多个具有同名变量的函数时,它会使脚本更容易调试并且更不容易出现令人讨厌的故障模式.

You should declare your variables local inside functions. It is not strictly necessary, but it will make scripts easier to debug and less prone to nasty failure modes when you have several functions with variables of the same name.

我认为HTTP/1.1"是你想要的搜索字符串

I think "HTTP/1.1" is the search string you want

如果性能是一个问题,您应该尝试不同的文本匹配方法(即 Bash 正则表达式 =~grep),看看哪种方法最适合您数据.

If performance is a concern, you should try different approaches to text matching (i.e. Bash regexes =~, grep) to see which is best for your data.

请注意,上面的脚本可以简化为:

Please note that the script above could be simplified by :

  • shift 2
  • 替换local -a command=("${@:3}")
  • 在任何使用它的地方用 "$@" 替换 "${command[@]}"

在这种情况下,这是有道理的,但我利用这个机会来说明如何将命令构建为数组,因为它通常在脚本中很有用,但在简单的情况下,使用位置参数却能很好地工作并提高可读性.

In this case it would make sense, but I used this opportunity to illustrate how building commands as arrays works, as it is often useful in scripts, but in simple cases using positional arguments instead works very well and improves readability.