سؤال

EDIT: I KNOW THIS IS REDUNDANT, IT IS HOMEWORK, I HAVE WRITTEN MY OWN CODE AND NEED HELP TROUBLESHOOTING>

As stated, I must write a BASH script to determine whether an executable file is in the users path.

such that if you type
./findcmd ping it returns /bin/ping

I have some code written, But it does not properly work and I hope someone can help me troubleshoot. When I type ./findcmd ping it just returns my file does not exist.(with any other file I try as well that I know exists.)

#!/bin/bash
#
# Invoke as ./findcmd command
#
# Check for argument
if [[ $# -ne 1 ]]
 then
    echo 'useage: ./findcmd command'
    exit 1
fi
#
# Check for one argument
if [[ $# -eq 1 ]]
 then
     pathlist=`echo $PATH | tr ':' ' '`
     for d in $pathlist;
          do
             if [[ ! -d $d || ! -x $d || ! -r $d ]]
               then
                   echo 'You do not have read end execute
                          permissions!'
                   exit 2
              fi
              if [[ $(find $d -name $1 -print | wc -l) -ne 0 ]]
                   then
                         echo 'The file does not exist in the PATH!'
                          exit 0

             fi
        done
fi

exit 0
#
#
هل كانت مفيدة؟

المحلول

No need to use a bash array, tr'ing the ':' with ' ' will work just fine in a for loop.

#!/bin/bash
#
# Invoke as ./findcmd command
#
# Check for argument
if [[ $# -ne 1 ]]
 then
    echo 'usage: ./findcmd command'
    exit 1
fi

f=$1

# No need to check the $# again, there's at least one arg and other will be ignored..
# Otherwise you can wrap this in a loop and keep shift'ing args and checking one by one
pathlist=`echo $PATH | tr ':' '\n'`
for d in $pathlist;
    do
      #echo command is your friend
      #echo "Checking for $f in $d"
      path="$d/$f"
      if [[ -f "$path" && -x "$path" ]]; then
         # PATH is not recursive, therefore no need to use find command
         # Simply checking that the file exists and is executable should be enough
         echo "Found $f at '$path'"
         # Note the same filename may be present farther down the PATH 
         # Once the first executable is found, exit
         exit 0
      fi
done

# Getting here means file was not found
echo "$f could not be found"
exit 1

Here are the results:

rbanikaz@lightsaber:~$ ./which.sh grep
Found grep at '/usr/bin/grep'
rbanikaz@lightsaber:~$ ./which.sh foo
foo could not be found
rbanikaz@lightsaber:~$

نصائح أخرى

The which command already does this...

Techinically this is a solution...

#!/bin/bash
which $1

I probably wouldn't submit it for as assignment though...

Update

Messing around a bit and I think the following will code will get your past your current bug:

#!/bin/bash
#
# Invoke as ./findcmd command
#
# Check for argument
if [[ $# -ne 1 ]]
 then
    echo 'useage: ./findcmd command'
    exit 1
fi
#
# Check for one argument
if [[ $# -eq 1 ]]
 then
     d=$1
     pathlist=($(echo $PATH | tr ':' ' '))
     echo $pathlist

     i=0
    while read line; do
      a4[i++]=$line
    done < <(echo "$PATH" | tr ':' '\n')

    n=${#a4[@]}
    for ((i=0; i < n; i++)); do
       if [[ ! -d $d || ! -x $d || ! -r $d ]]
       then
          echo 'You do not have read end execute
                          permissions!'
          exit 2
       fi
       if [[ $(find $d -name $1 -print | wc -l) -ne 0 ]]
       then
          echo 'The file does not exist in the PATH!'
          exit 0

       fi
    done
fi

exit 0
#
#

Pretty much, it uses a solution in this SO question to split the $PATH variable into an array and then loops through it, applying the logic you had inside your while statement.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top