Reputation: 3042
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
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
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
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
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