2

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.

4

2 回答 2

1
#!/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
于 2011-07-19T18:25:45.450 回答
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将考虑退出状态。退出状态为零被认为是真,任何其他退出状态被认为是假。

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

于 2011-07-19T18:23:20.327 回答