FatalKeystroke
FatalKeystroke

Reputation: 3042

Boolean switch refuses to operate as intended

I have this code that I've been working on for hours now, I follow it manually and it SHOULD print:

Missing Dependency: notacommand

Except it refuses to work properly and I cannot figure out why. What am I doing wrong?

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir wget notacommand)
for d in ${__DEPENDENCIES[@]}; do
  for i in $(echo ${PATH} | tr ":" " "); do
    if [ -e "${i}/${d}" ] ; then
      v=true
      break
    else
      v=false
    fi
  done
  if [ v = false ] ; then
    echo "Missing dependency: ${d}"
    exit 1
  fi
done

I apologize as I understand it's bad form to just post code asking for help, but I don't actually know what's wrong with my code in the first place so I'm not even sure what to ask or how to ask it.

Upvotes: 0

Views: 54

Answers (4)

chepner
chepner

Reputation: 531325

You are just reimplementing command -v.

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir wget notacommand)
for d in "${__DEPENDENCIES[@]}"; do
  if ! command -v "$d" > /dev/null; then
    echo "Missing dependency: ${d}"
    exit 1
  fi
done

Well, perhaps not. command will still find shell functions, aliases, etc, which you may want to ignore.

Upvotes: 0

PM 2Ring
PM 2Ring

Reputation: 55479

Although your question has been answered, I have a couple of suggestions.

You are doing $(echo ${PATH} | tr ":" " ") inside a loop, which is a bit inefficient. And there's actually a nicer way to split your path. The script below puts the path elements into an array. The trick is to temporarily set the bash Internal Field Separator to :.

I've also modified your file existence check so that it uses an empty string for false and the found path element string for true. And I've used the modern [[ style tests which are more user-friendly than the old [ style, eg they are more forgiving over missing " quote marks; FWIW, the script below copes with crazy file names that contain unpleasant characters like spaces or quote marks. OTOH, [[ is a bash-ism, not all shells support it.

#!/bin/bash

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir zorg wget notacommand)
IFS=':' paths=($PATH)
# for d in "${paths[@]}"; do echo "[$d]"; done

for d in "${__DEPENDENCIES[@]}"
do
    for i in "${paths[@]}"
    do
        v=''
        if [[ -e $i/$d ]]
            then v=$i; break
        fi
    done

    if [[ -z $v ]]
        then echo "Missing dependency: $d"
        else echo "$d is in $i"
    fi
done

Here's an alternate approach, which only finds a dependency if it is actually executable.

#!/bin/bash

__DEPENDENCIES=(touch clear sleep ln pacman sed mkdir zorg wget notacommand)

for f in "${__DEPENDENCIES[@]}"
do 
    echo -n "$f : "
    which "$f" || echo "NOT found!"
done

Upvotes: 1

anhlc
anhlc

Reputation: 14449

Bash test doesn't support boolean, so v is a string variable. Use this:

if [ "$v" = "false" ]; then
    echo "Missing dependency: ${d}"
    exit 1
fi

Upvotes: 1

Travis
Travis

Reputation: 2767

You're forgetting a dollar sign ;)

The line if [ v = false ] should read if [ $v = false ]

Although your script only gives me "Missing dependency: pacman", when I should get notacommand as well.

Upvotes: 2

Related Questions