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.
如前所述,我必须编写一个BASH脚本,以确定可执行文件是否在用户路径中。
such that if you type
./findcmd ping it returns /bin/ping
这样,如果您输入。/findcmd ping,它将返回/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.)
我已经编写了一些代码,但是它不能正常工作,我希望有人能帮助我排除故障。当我输入。/findcmd ping时,它会返回我的文件不存在。(还有其他文件,我也知道是存在的。)
#!/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
#
#
2 个解决方案
#1
3
No need to use a bash array, tr
'ing the ':'
with ' '
will work just fine in a for loop.
不需要使用bash数组,tr':' with '将在for循环中正常工作。
#!/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:~$
#2
-1
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.
基本上,它在这个问题中使用一个解决方案将$PATH变量分割成一个数组,然后循环遍历它,应用你在while语句中所包含的逻辑。
#1
3
No need to use a bash array, tr
'ing the ':'
with ' '
will work just fine in a for loop.
不需要使用bash数组,tr':' with '将在for循环中正常工作。
#!/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:~$
#2
-1
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.
基本上,它在这个问题中使用一个解决方案将$PATH变量分割成一个数组,然后循环遍历它,应用你在while语句中所包含的逻辑。