LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-19-2022, 05:27 AM   #1
chrisqck
LQ Newbie
 
Registered: Jan 2021
Posts: 5

Rep: Reputation: Disabled
Using GetOpts and error handling


Hi All,

I learning bash scripting and this time I trying to write a script that accepts a folder path (-P) and a file name (-N) then check if this file exists in the folder path specified. I'm using /home/chrisqck/Scripting/sometextfile.txt to test the script.

I'm having a problem where if I run the script with -P then -N it will work beautifully. However if i swap the switches, -N first then -P the script will error out. I know there's a "logic flow" problem but for the life of me, i just can't figure out how else to do this. Is there a way for me to do for -N : If [[ -z $FolderPath ]] then "jump to -P then jump back to -N" else proceed with -N ? If not, how should i reqork the 'logic' of this script ?

Here is the script :

Code:
FolderPath=""   # Default to empty path
FileName=""     # Default to empty file name.

while getopts "P:N:H" opt ; do
  case $opt in
      
    P)  # Handles Folder Path
	if [[ -d $OPTARG ]]; then   	 # If folder path is valid...
        	FolderPath=$OPTARG       # Set var $FolderPath to value of $OPTARG
	else 
	      	echo -e "\nError: Please enter a valid folder path.\nHint: Run FileLocate -H for Help."
		exit 1;	
        fi
        ;;

    N)  # Handles File name
	
	if [[ -f $FolderPath$OPTARG ]]; then	# Check if file name provided exists in folder.
		FileName=$OPTARG 
		echo "File $OPTARG exists in folder $FolderPath"
	else 
		echo -e "\nError: Please enter a valid file name. \nHint: Run FileLocate -H for Help."
                exit 1;
      	fi
        ;;

    H)   # Show Help Menu - Quick Usage Guide.
         echo "FileLocate Usage Quick Guide"
         ;;

    ?)
         echo -e "\nError: Invalid option.\nHint: Run FileLocate -H for Help."
         ;;

    :)
         echo -e "\nError: No argument provided !!\nHint: Run FileLocate -H for Help."
         ;;

  esac 

done


# To ensure that -P & - N are both entered 
if [[ -z $FolderPath ]] || [[ -z $FileName ]]; then 
	echo -e "\nError: Both -P and -N are MANDATORY !!!\nRun with FileLocate -H for Help" >&2
	exit 1;
fi

Any advice / guidance is much appreciated. Thanks in advance.

Last edited by chrisqck; 06-19-2022 at 05:49 AM.
 
Old 06-19-2022, 06:44 AM   #2
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora
Posts: 4,153

Rep: Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265Reputation: 1265
only set the variables as you parse the options. Do the logic tests after all the options have been read.
 
1 members found this post helpful.
Old 06-19-2022, 06:48 AM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,760

Rep: Reputation: 5931Reputation: 5931Reputation: 5931Reputation: 5931Reputation: 5931Reputation: 5931Reputation: 5931Reputation: 5931Reputation: 5931Reputation: 5931Reputation: 5931
Your possible options are:
Use one option for both /path/filename
Do not check for a valid path/filename until after the while loop.

Since both P and N require arguments exit the program in the loop if no argument provided i.e. either at :) or ?)
 
Old 06-19-2022, 08:53 AM   #4
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,976

Rep: Reputation: 7337Reputation: 7337Reputation: 7337Reputation: 7337Reputation: 7337Reputation: 7337Reputation: 7337Reputation: 7337Reputation: 7337Reputation: 7337Reputation: 7337
yes, the general way is first check the arguments only, and validate them after the while loop.
Otherwise you may try shellcheck to help fix issues.
 
Old 06-24-2022, 10:35 PM   #5
chrisqck
LQ Newbie
 
Registered: Jan 2021
Posts: 5

Original Poster
Rep: Reputation: Disabled
Hi All,

I've been tied up with other critical task the pst couple of days. Just wanna drop in and thank everyone for the recommendations and guidance. Will work on the script and update once done.

Much thanks ~!!!
 
Old 06-25-2022, 09:47 AM   #6
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,146
Blog Entries: 6

Rep: Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834
Quote:
I'm having a problem where if I run the script with -P then -N it will work beautifully. However if i swap the switches, -N first then -P the script will error out.
This is what you are doing. You will need to do them in P N H order, or you won't get all of them in the output

test1.sh
Code:
#!/usr/bin/bash

while getopts "P:N:H" opt ; do
    case "$opt" in
        P) echo "P" ;;
        
        N) echo "N" ;;
        
        H) echo "H" ;;
    esac
done
Code:
bash ./test1.sh -P x -N x -H x
P
N
H

bash ./test1.sh -N x -H x -P x
N
H

This will get them in any order.

test2.sh
Code:
#!/usr/bin/bash

optstring='P:N:H:'

while getopts "$optstring" opt ; do
    case "$opt" in
        P) echo "P" ;;
        
        N) echo "N" ;;
        
        H) echo "H" ;;
        
        *) echo "Bad input"
    esac
done
Code:
bash ./test2.sh -N x -P x -H x
N
P
H

bash ./test2.sh -P x -N x -H x
P
N
H

bash ./test2.sh -H x -N x -P x
H
N
P

bash ./test2.sh -G x -N x -H x
./test2.sh: illegal option -- G
Bad input

Last edited by teckk; 06-25-2022 at 09:50 AM.
 
Old 06-25-2022, 10:24 AM   #7
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,146
Blog Entries: 6

Rep: Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834Reputation: 1834
Follow up.

test3.sh
Code:
#!/usr/bin/bash

optstring='P:p:N:n:H:h:'

while getopts "$optstring" opt ; do
    case "$opt" in
        [Pp]*) echo ""$opt" arg is > "$OPTARG"" ;;
        
        [Nn]*) echo ""$opt" arg is > "$OPTARG"" ;;
        
        [Hh]*) echo ""$opt" arg is > "$OPTARG"" ;;
        
        *) echo "Bad input"
    esac
done
Code:
bash ./test3.sh -N cow -P cat -H dog
N arg is > cow
P arg is > cat
H arg is > dog

bash ./test3.sh -H house -p cat -n dog
H arg is > house
p arg is > cat
n arg is > dog

bash ./test3.sh -p xx -H yy -N zz
p arg is > xx
H arg is > yy
N arg is > zz
 
Old 06-28-2022, 05:12 AM   #8
chrisqck
LQ Newbie
 
Registered: Jan 2021
Posts: 5

Original Poster
Rep: Reputation: Disabled
Hi All,

Again, I want to thank everyone for the tips and guidance. This script I wanted to learn how to use GetOpts. The function of the script is simply to check and let the person running it know if a specific file exists in a specific folder. The biggest mistake I made, I've learnt, was trying to fit in too many things in the GetOpt. What I should've done was to use it to just get the arguments then assign it to the correct variable and proceed from there.


As the common practice in forums, I'm sharing my final script that I've been working on the couple of day. I'm sure someone here can make it even more efficient. As a newbie in this, I'm a little proud of that part that checks if the given path ends with "/" This has been an interesting lesson and I've learnt so much more than I thought I would.


Code:
FolderPath=""   # Default to empty path
FileName=""     # Default to empty file name.

# Function Help_Full - Full Help / User Guide. Note: Use when -h swicth is used with script. 
function Help_Full () {
	echo -e "FILELOCATE(1)\t\t\tUsage Guide\n"
	echo -e "\033[1mUSAGE:\033[0m\n\t./FileLocate -p \"/path/to/folder\" -n \"FileName\"\n"
        echo -e "\033[1mDESCRIPTION:\033[0m\n\tScript to check if a specific File exists in a specific folder.\n"
	echo -e "\033[1m\t-p\033[0m\t\033[1mMandatory Option.\033[0m Specify folder path to be checked. Must end with "/" otherwise will result in error.\n"
	echo -e "\033[1m\t-n\033[0m\t\033[1mMandatory Option.\033[0m Specify file name to find.\n"
	echo -e "\033[1m\t-h\033[0m\tPrints this Quick Guide menu.\n\n"
	echo -e "Written By Chris Q. With Assistance From Jason L. - June 2022\n"	
	exit 0;
} 


# Function Help_Quick - Quick Help / Guide. Note : Use in switches error message OR when script run without options. 
function Help_Quick () {
	echo -e "\033[1mUSAGE: \033[0m./FileLocate.sh -p \"/path/to/folder\" -n \"Filename\".\n "
}




while getopts "p:n:h" opt; 
do
  case $opt in
      
    p)  # Handles Folder Path argument.
       	FolderPath=$OPTARG      # Set value of $FolderPath
	;;

    n)  # Handles File name argument. 
	FileName=$OPTARG	# Set value of $FileName 
	;;

    h)  # Show Help Menu / Usage Guide.
	Help_Full	
    	;;
    :)	# Handling Missing Mandatory Switches
	echo -e "\nError: Switches -p and -n requires argument.\n"
        Help_Quick	
      	exit 1;
	;;

    ?) 	# Handling Invalid Option(s)
      	echo -e "\nError: Invalid option.\n" 
	Help_Quick
      	exit 1;
	;;

  esac

done 


# To ensure that -P & - N are both entered 

if [[ -z $FolderPath ]] || [[ -z $FileName ]]; then 
	echo -e "Error: Switches -p and -n requires an argument !!!\n" >&2
	Help_Quick
	exit 1;
fi


# This section verifies folder path & file name is valid. 

if [[ -d $FolderPath ]]; then   	 # If folder path is valid...
	i=$( echo "${FolderPath: -1}" )	
	if [[ $i != "/" ]]; then
		echo "Error: Folder Path must end with /"	
	else
		if [[ -f $FolderPath$FileName ]]; then		 
			echo "File $FileName exists in Folder $FolderPath !!!"
			exit 0;	
		else 	
			echo "File $FileName does not exists in Folder $FolderPath !!!"  
		fi
		exit 0;
	fi	
else 
	echo -e "\nError: Please enter a valid folder path.\n"
	Help_Quick 
	exit 1;	
fi
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Handling default values when using getopts t:: Faki Linux - Newbie 10 12-19-2021 02:05 PM
Handling long options with getopts Faki Linux - Software 6 10-31-2021 09:44 AM
[SOLVED] Bash - using getopts, call one flag first and use input from proceeding flags? Springs Programming 4 11-06-2018 09:19 AM
wrapper script using getopts to pass all arguments except one threezerous Linux - Newbie 1 04-14-2014 06:08 PM
Using getopts in Shell properly?? khandu Programming 2 01-12-2012 07:15 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:42 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration