ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm having some issue with a homework assignment on shell scripting. The instructor gave me this pseudo code:
Code:
BEGIN
set FINDALL to false
IF $1 equals -a THEN
set FINDALL to TRUE
dispose of $1
END-IF
FOR each Positional Parameter ($file) DO
IF $file is a pathname THEN
IF if $file is executable and not a directory THEN
echo $file
ELSE
echo $file is NOT Found
END-IF
ELSE
set FOUND to false
# Don't forget to handle the special cases of PATH
FOR P in PATH (: separated list) DO
IF $P/$file is executable and not a directory THEN
set FOUND to true
echo $P/$file
IF FINDALL is FALSE THEN
BREAK FROMTHE for LOOP
END-IF
ELSE
END-IF
IF FOUND is FALSE THEN
echo $file is NOT FOUND
END-IF
END-FOR
END-IF
END-FOR
END
I can't quite get my code to work. Like, I'll run it and get no echo. I also fear I am not commenting well or formatting well for general readability. If someone has some time and wants to relive their college freshmen days, can you point me in a good direction? Thank you.
Code:
#! /bin/sh
#set a flag to check if you should search all for all occurances
#by default, you will only find the first occurance
FINDALL=FALSE
case $1 in
-a)
FINDALL=TRUE
#throw away this argument
shift
;;
esac
for file
do
#if $file is a pathname
case $file in
*/*)
#if $file is executable and not a directory
if [ -x "$file" ]
then
if [ !-d "$file" ]
then
echo "$file"
else
echo "$file NOT FOUND"
fi
fi
;;
*) #no / in the filename
FOUND=FALSE
;;
esac
#handle special cases of PATH
for P in `echo $PATH | sed -e 's/^:/.:/' -e 's/::/:.:/' -e 's/:$/:./' -e 's/:/ /g'`
do #start the do loop through PATH
#test if $P/$file is a directory or executable
case $file in
*)
if [ -f "$P/$file" ]
then
if [ !-d "$P/$file" ]
then
FOUND=TRUE
echo "$P/$file"
else [ FINDALL=FALSE ]
break
fi
fi
;;
esac
done
if [$FOUND=FALSE]
then
echo "$file NOT FOUND"
fi
done
Last edited by boygenuis; 03-07-2014 at 12:20 PM.
Reason: incorrect code added
I'm assuming the purpose of this script is to find whether or not the file issued as an argument actually exists or not..?
You're close, I think.
As a general rule, it's a good idea to "protect" your variables. So instead of writing things like
Code:
$P/$file
it is considered safer to write it:
Code:
${P}/${file}
And finally, I would say it's a good idea to insert "echo" statements A LOT when initially testing stuff. For me, these act a little like debugging statements, and it helps me know where exactly what is going on as the programme runs.
For instance, before entering an 'if' statement, precede it with a simple
Code:
echo "DEBUG: an if statement to test if file is exec or not"
or something like that. This way, you see what tests have passed and failed, and that ought to help you debug your own logic.
Last edited by notKlaatu; 03-03-2014 at 12:12 AM.
Reason: accidentally hit submit in the middle of writing..
There are two unmatched fis and $file never has a value assigned to it.
Here's the script with indentation
Code:
#! /bin/sh
#set a flag to check if you should search all for all occurances
#by default, you will only find the first occurance
FINDALL=FALSE
case $1 in
-a)
FINDALL=TRUE
#throw away this argument
shift
;;
esac
for file
do
#if $file is a pathname
case $file in
*/*)
#if $file is executable and not a directory
if [ -x "$file" ]
then
if [ !-d "$file" ]
then
echo "$file"
else
echo "$file NOT FOUND"
fi
fi # << Unmatched fi
;;
*) #no / in the filename
FOUND=FALSE
;;
esac
#handle special cases of PATH
for P in `echo $PATH | sed -e 's/^:/.:/' -e 's/::/:.:/' -e 's/:$/:./' -e 's/:/ /g'`
do #start the do loop through PATH
#test if $P/$file is a directory or executable
case $file in
*)
if [ -f "$P/$file" ]
then
if [ !-d "$P/$file" ]
then
FOUND=TRUE
echo "$P/$file"
else [ FINDALL=FALSE ]
break
fi
fi # << Unmatched fi
;;
esac
done
if [$FOUND=FALSE]
then
echo "$file NOT FOUND"
fi
done
Thank you, all, for your help. I've tried to make my edits based on your recommendations and here's what I've got so far. Also, because I forgot to put it earlier, the objective for this program is, "Write a shell script to locate executable files. This script takes a list of file names from the command line and determines which would be executed had these names been given as commands."
Code:
#! /bin/sh -xv
#Student: boygenuis
#Course: Shell Scripting
#Assignment: Locating Executable Files
#Date: 03 MAR 2014
#set a flag to check if you should search all for
#all occurrences. By default, you will only find
#the first occurrence
file="$1"
FOUND="$2"
$FINDALL = FALSE
case $1 in
-a)
FINDALL = TRUE
shift #throw away this argument
;;
esac
for file
do
#if $file is a pathname
case $file in
*/*)
#if $file is executable and not a
#directory
if [ -x "$file" -a ! -d "$file" ]
then
echo "$file"
else
echo "$file NOT FOUND"
fi
;;
#handle the special cases of PATH, start the DO loop
#through PATH, and test if $P/$file is a directory or
#executable
*)
for P in `echo $PATH | sed -e 's/^:/.:/' -e 's/::/:.:/' -e 's/:$/:./' -e 's/:/ /g'`
do
case $file in
*)
if [ -f "$P/$file" -a ! -d "$P/$file" ]
then
FOUND = TRUE
echo "$P/$file"
echo "DEBUG: Test if if [ FINDALL = FALSE ]"
if [ $FINDALL = FALSE ]
then
break
fi
fi
;;
esac
done
if [ $FOUND = FALSE ]
then
echo "$file NOT FOUND"
fi
;;
esac
done
Last edited by boygenuis; 03-07-2014 at 12:21 PM.
Reason: forgot code tags
It is forgivable to have not done so the first time, but to ignore the request and do it again is not. Please go back and edit both posts and place your code in code tags.
I for one will not read something that is not formatted and as was pointed out by catkin, this simple process would have led you to find easily fixable issues.
Regardless of the post formatting, the OP has shown adherence to the forum rules about posting homework, has shown effort of their own, and has been polite throughout. More posters should follow that example, in my opinion.
Re the post #8 by notKlaatu, one point made is that spaces are "tokenizers" in bash and Posex-compliant variants. (bash, itself, is not Posix-compliant.) Thus A = B is three "tokens," whilst A=B is one "token," and interpreted as an implicit let command.
The other point is that $ is a substitution command, and a command can't occur as the target of an assignment.
To add to that... the reason bash tokenizes them using spaces is a variable called IFS which defaults to " \t\n" easier read as "(space)(tab)(newline)"
And I am not chiding them for their good effort, but unfortunately with my old eyes the lack of contrast and formatting makes it difficult to assist
Believe me...I agree with you; I don't wear bifocals for fun. But I did want to give credit to the OP, especially given the MANY homework requests we see that are barely intelligible and/or posted verbatim from a book, with no effort at all.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.