How do I revert in case of wrong option? - shell

select_again_dir:
echo -e "\033[32m enter the name of the source file; \033[0m"
echo
ls
echo
read build_source_dir
if [ ! -d $build_source_dir ]
then
echo "Folder Not Found. Please select again;"
goto select_again_dir:
else
echo "folder exists"
fi
Hello,
If the source file cannot be found, I want it to re-enter a value.
Is there a function you can suggest instead of goto?

The standard way is a while loop. One way to avoid duplication of the input read:
echo -e "\033[32m enter the name of the source file; \033[0m"
while [ ! -d "$build_source_dir" ]; do
echo
ls
echo
read build_source_dir
echo "Folder Not Found. Please select again: "
done
echo "folder exists"

Just loop it. You can use break and continue to your favor.
while true; do
echo -e "\033[32m enter the name of the source file; \033[0m"
echo
ls
echo
read build_source_dir
if [ ! -d "$build_source_dir" ]
then
echo "Folder Not Found. Please select again;"
continue # not really needed, there is nothing below to happen
else
echo "folder exists"
break # jump out of the loop
fi
done

Related

i don't know if my shell script is correct

I have a homework using for loop but I'm not quite understand the task that I have to do in there. I wrote a script but I feel like it's not a correct script. Please help!
Here is the question:
Write a shell script to list out the contents of any directory, and indicate for each file (including invisible ones) whether the file is a directory, a plain file, and whether it is public and/or executable to this process
#!/bin/bash
if [ $# -lt 1 ] ; then
echo " file doesn't exist"
echo
echo " variable needed to run a command"
fi
echo ---------------------------------------------
echo ---------------------------------------------
for i in $*
do
if [ -f $i ]; then
echo " it's a file";
echo "THIS IS A LIST OF FILE and DIRECTORY in $i"
ls -a $i
fi
done
echo -----------------------------------------
if [ -d $i ]; then
echo "directory" ;
echo "THIS IS A LIST OF FILES AND DIRETORY in $i"
ls -a $i
fi
echo ------------------------------------------
if [ -x $i ]; then
echo "executable"
echo "THIS IS A LIST OF EXECUTABLE FILE IN $i"
ls -x $i
fi
echo -----------------------------------------
if [ -r $i ]; then
echo "this file is a public file"
else "this is a private file"
fi
#!/bin/bash
if [ $# -lt 1 ] ; then
echo " file doesn't exist"
echo
echo " variable needed to run a command"
fi
echo ---------------------------------------------
echo ---------------------------------------------
for i in $*
do
if [ -f $i ]; then
echo " it's a file";
echo "THIS IS A LIST OF FILE and DIRECTORY in $i"
ls -a $i
fi
done
echo -----------------------------------------
if [ -d $i ]; then
echo "directory" ;
echo "THIS IS A LIST OF FILES AND DIRETORY in $i"
ls -a $i
fi
echo ------------------------------------------
if [ -x $i ]; then
echo "executable"
echo "THIS IS A LIST OF EXECUTABLE FILE IN $i"
ls -x $i
fi
echo -----------------------------------------
if [ -r $i ]; then
echo "this file is a public file"
else "this is a private file"
fi
Poorly written specifications are the bane of education. "Public" sounds like the wrong word here. I'll assume it means "readable".
You check if there's an argument, but you don't exit the program if there is not. I'd also confirm it's a directory, and readable.
The manual will do you a lot of good. Expect to do a lot of reading till you learn this stuff, and then reference it a lot to be sure.
Read this section carefully, create some tests for yourself to prove they work and that you understand them, and your job will be more than half done.
Don't use [. Generally it's just better to always use [[ instead, unless you are using (( or case or some other construct.
I don't see that a for loop was specified, but it ought to be fine. Just be aware that you might have to specify $1/* and $1/.* separately.
Put all your tests in one loop, though. For each file, test for whether it's a directory - if it is, report it. Test if it's a plain file - if it is, report it.
I do NOT like doing homework for someone, but it looks like you could use an example that simplifies this. I recommend you not use this as written - break it out and make it clearer, but this is a template for the general logic.
#! /bin/env bash
(( $# )) && [[ -d "$1" ]] && [[ -r "$1" ]] || {
echo "use: $0 <dir>" >&2
exit 1
}
for e in "$1"/.* "$1"/*
do echo "$e:"
[[ -d "$e" ]] && echo " is a directory"
[[ -f "$e" ]] && echo " is a plain file"
[[ -r "$e" ]] && echo " is readable"
[[ -x "$e" ]] && echo " is executable"
done
If you read the links I provided you should be able to break this apart and understand it.
Generally, your script is long and a bit convoluted. Simpler is easier to understand and maintain. For example, be very careful about block indentation to understand scope.
$: for i in 1 2 3
> do echo $i
> done
1
2
3
$: echo $i
3
Compare this to -
for i in $*
do if [ -f $i ]; then
echo " it's a file";
echo "THIS IS A LIST OF FILE and DIRECTORY in $i"
ls -a $i
fi
done
echo -----------------------------------------
if [ -d $i ]; then
echo "directory" ;
echo "THIS IS A LIST OF FILES AND DIRETORY in $i"
ls -a $i
fi
You are testing each entry to see if it is a file, and if it is, reporting "THIS IS A LIST OF FILE and DIRECTORY in $i" every time...
but then only testing the last one to see if it's a directory, because the [ -d $i ] is after the done.
...did you run this somewhere to try it, and look at the results?

while loop for checking a file name exists or not

filename=""
while [[ $filename = "" ]];do
echo "Enter the file name"
read filename
if [[ -f $filename ]];then
echo "$filename exists"
else
echo "File name doesn't exists, so re-enter"
fi
done
with this style of loop, the loop exists when the file name is not present.
But i want the loop to continue until the user input the file name.
Please suggest what additional command i should include in the above script.
Use break to get out of the loop
while true ; do
echo "Enter the file name"
read filename
if [ -f "${filename}" ]; then
echo "${filename} exists"
break
else
echo "File name doesn't exists, so re-enter"
fi
done
echo "Thanks for ${filename}"
or shorter
while true ; do
read -p "Enter the file name: " filename
test -f "${filename}" && break
echo "File name doesn't exists, so re-enter"
done
echo "Thanks for ${filename}"
Quick and dirty way of doing it while utilizing the same code you have is simply adding your code inside an infinite loop.
while :
do
filename=""
while [[ $filename = "" ]];do
echo "Enter the file name"
read filename
if [[ -f $filename ]];then
echo "$filename exists"
else
echo "File name doesn't exists, so re-enter"
fi
done
done
Keep in mind that this will only look within the directory that the program is executed from unless a full path is given.

Bash and shell script if statement to do something if a file is found

I have created a shell script to find a string within a text file, then display the results to the screen sorted through grep.
How could I surround this in an if statement so that if results are found then echo "Found!" and display the results afterwards else say "not found"?
I have gotten this far already by using various websites but I am stuck with this.
Here is what I have so far:
echo "enter name "
read search
echo "The String searched for "
grep -i $search $fileName
if [$search ????]
then
echo "Found!"
else
echo "Not Found!"
fi
Your grep call can be a part of the if statement:
if grep -q "$search" "$filename"; then
echo "Found!"
else
echo "Not Found!"
fi
Check if grep returns a non-zero length string:
if [ -n "$(grep -i "$search" "$fileName")" ]; then
echo "Found!"
else
echo "Not Found!"
fi

if [ `ls $op_file` ]; then is returning true even the file is not found

#!/bin/bash
echo "Enter the o/p file name"
read op_file
echo "Enter the count"
read count
echo "OP filename : "
echo $op_file
if [ `ls $op_file` ]; then
echo "O/P file found"
else
exit 0
fi
I'm trying to check whether the filename is existing or not.Have to proceed if the file is existing. Though the above code doesn't give me error. It prints O/P file found even though the file is not found by ls.
Your script can be refactored to this:
#!/bin/bash
read -p "Enter the o/p file name" op_file
read -p "Enter the count" count
echo "OP filename: $op_file"
if [ -f "$op_file" ]; then
echo "O/P file found"
else
exit 1
fi
Better to use -f "$file" check for checking existence of a file. Also see man test
Use the -e operator in your if, this checks the for existence of a file, so:
if [ -e $op_file ]; then
echo "O/P file found"
else
exit 0
fi

Using find in bash script - how to handle case where find returns "file or directory does not exist"

I'm using the find command in my bash script like so
for x in `find ${1} .....`;
do
...
done
However, how do I handle the case where the input to my script is a file/directory that does not exist? (ie I want to print a message out when that happens)
I've tried to use -d and -f, but the case I am having trouble with is when ${1} is "." or ".."
When the input is something that doesn't exist it does not enter my for loop.
Thanks!
Bash gives you this out of the box:
if [ ! -f ${1} ];
then
echo "File/Directory does not exist!"
else
# execute your find...
fi
Bash scripting is a bit weird. Practice before implementation. But this site seems to break it down well.
If the file exists, this works:
if [ -e "${1}" ]
then
echo "${1} file exists."
fi
If the file does not exist, this works. Note the '!' to denote 'not':
if [ ! -e "${1}" ]
then
echo "${1} file doesn't exist."
fi
assign the find to a variable and test against the variable.
files=`find ${1} .....`
if [[ "$files" != “file or directory does not exist” ]]; then
...
fi
You can try something like this:
y=`find . -name "${1}"`
if [ "$y" != "" ]; then
for x in $y; do
echo "found $x"
done
else
echo "No files/directories found!"
fi

Resources