Sponsored Content
Top Forums Shell Programming and Scripting Passing vars or params to function Post 303011249 by bakunin on Monday 15th of January 2018 03:45:47 PM
Old 01-15-2018
Quote:
Originally Posted by Cody Learner
The previous script posted was only an exersize used to help me understand how getopts works via hands on testing. I was not understanding how it worked after reading the man page and other sources of info.
OK, this laudable effort deserves an in-depth answer. I will not cover all intricacies of the getopts-routine, though, only the basics.

What getopts does:

getopts provides a standardised way of parsing a commandline. Notice that commands in UNIX (and Linux) get different inputs on their commandline. Consider the following command:

Code:
cp -pr /some/source /some/target

The cp part is easy: it is the name of the command to call.

The -pr is a shorthand for the options -p and -r. Options always influence how a program does its work, but they do not determine what it does. In this example cp (which copies files) is told to preserve the ownership and rights (-p) and to work recursively instead of on individual files, but these two options do not tell cp what to copy and where to put the copies.

This is done in the last part: the arguments. There are two arguments here: the file (or directory) to copy and the destination where this copy should be put to.

To make things a bit more confusing options may have arguments too: they influence hwo the option works. For instance, the GNU-version of grep

Code:
grep -A 3 -i "searchtext" /path/to/file

grep is the name of the called program and it searches for text. the "searchtext" is the text it searches for (the first argument) and /path/to/file is the file in which it should search (the second argument). -i tells grep to search case-insensitive, so that "searchtext", but also "SEARCHtext" or "SeArChTeXt", etc. would equally be found. This is an option without arguments.

That leaves -A 3. -A tells grep to output not only the line where searchtext was found but a number of lines before, to provide context. If a match is found in line 10 also some lines before (9,8,...) will be shown. The 3 is an argument to this option and tells grep to provide exactly 3 lines of context before each match: lines 7, 8 and 9.


OK, after this rather long introduction to establish the correct wording, here is how getopts parses the commandline:

With each call of getopts you get one (exactly ONE!) option from the commandline. You need to react to this option, usually by setting some flags or variables in your script. After the last option getopts will tell you that there are no more and you have to take what you still have left on the commandline as arguments. Furthermore, whenever you call getopts you need to tell it what options you expect on the commandline and if these options take arguments or not.


Let us start with a simple example: The script script1.sh shall understand two options (-x and -y) and both should be optional.

The script is fairly straightforward:

Code:
#! /bin/ksh

typeset chOpt=""              # the newly parsed option will land here


while getopts "xy" chOpt  ; do
     case $chOpt in
          x)
               echo "called with the -x option"
               ;;

          y)
               echo "called with the -y option"
               ;;

     esac
done

Now try these commands:

Code:
script1.sh
script1.sh -x
script1.sh -xy
script1.sh -x -y
script1.sh -x -U

Also notice the difference between these two calls:

Code:
script1.sh -xy
script1.sh -yx

There is none, because options should NOT rely on a certain succession. It is possible to do that, but it is considered very bad style. You will notice that -U will produce an error message because U was not in our getopts string. Change this line:

Code:
while getopts "xy" chOpt  ; do

to

Code:
while getopts "xyU" chOpt  ; do

and the error message will go away because we told getopts that "U" is also a valid option. To be informed about -U being selected like -y or -x you would have to add another branch to the case-statement that handles the output of getopts results:

Code:
#! /bin/ksh

typeset chOpt=""              # the newly parsed option will land here


while getopts "xyU" chOpt  ; do
     case $chOpt in
          x)
               echo "called with the -x option"
               ;;

          y)
               echo "called with the -y option"
               ;;

          U)
               echo "-U option now not only supported but informed about"
               ;;


     esac
done


The next level: arguments.

What would the script do about this commandline:

Code:
script1.sh -xU something

Answer:nothing special, because arguments are not handled by the script:

Code:
script1.sh -xU
called with the -x option
-U option now not only supported but informed about

script1.sh -xU something
called with the -x option
-U option now not only supported but informed about

We need to provide some code to deal with arguments. This is where the OPTIND variable comes into play. OPTIND tells us how many options getopts has read. Since we have all the options already worked on, we want only the arguments remain on the commandline. We do that with the keyword shift. Here is example script2.sh:


Code:
#! /bin/ksh

typeset chOpt=""              # the newly parsed option will land here


while getopts "xyU" chOpt  ; do
     case $chOpt in
          x)
               echo "called with the -x option"
               ;;

          y)
               echo "called with the -y option"
               ;;

          U)
               echo "-U option now not only supported but informed about"
               ;;


     esac
done

shift $(( OPTIND -1 ))              # we shift out all options parsed so far

while [ -n "$1" ] ; do             # this leaves the arguments which we deal with here
     echo Next argument is: $1
     shift
done

Now run that with the commands:

Code:
script2.sh -x first
script2.sh -xU first second third "fourth fifth"

Notice that "fourth fifth" is ONE argument, because we enclosed it in double quotes on the command line.


The highest level: arguments to options.

We finally need to explain how to provide arguments to options. Suppose the following utility with its description:

Code:
script3.sh [-x][-y][-U <some numerical value>]

We have to tell getopts somehow that we expect -U to be accompanied by some numerical value. We do that by adding a colon (":") after the option in the option string (script3.sh):

Code:
#! /bin/ksh

typeset chOpt=""              # the newly parsed option will land here


while getopts "xyU:" chOpt  ; do
     case $chOpt in
          x)
               echo "called with the -x option"
               ;;

          y)
               echo "called with the -y option"
               ;;

          U)
               echo "-U option now not only supported but informed about"
               echo OPTARG is $OPTARG
               ;;


     esac
done

shift $(( OPTIND -1 ))              # we shift out all options parsed so far

while [ -n "$1" ] ; do             # this leaves the arguments which we deal with here
     echo Next argument is: $1
     shift
done

Now try the following:

Code:
script3.sh -xU3
script3.sh -xU 3
script3.sh -xU foobar

You will notice that -U now accepts an argument but its value is not checked: the numerical value 3 and the string "foobar" are equally allowed. We need to check this for ourselves in the option-handling loop, i.e.:

Code:
#! /bin/ksh

typeset chOpt=""              # the newly parsed option will land here


while getopts "xyU:" chOpt  ; do
     case $chOpt in
          x)
               echo "called with the -x option"
               ;;

          y)
               echo "called with the -y option"
               ;;

          U)
               echo "-U option now not only supported but informed about"
               if [ -n "$(echo $OPTARG | sed 's/[0-9]//g')" ] ; then
                    echo "only numerical values allowed!"
               fi
               ;;


     esac
done

shift $(( OPTIND -1 ))              # we shift out all options parsed so far

while [ -n "$1" ] ; do             # this leaves the arguments which we deal with here
     echo Next argument is: $1
     shift
done

OK, so far as an introduction. I suggest you play around with getopts yourself and see what it does under certain circumstances. If you still have questions don't be shy and ask.

I hope this helps.

bakunin

____________
PS: as a suggestion: "Hands-On KornShell93 Programming", Barry Rosenberg. My favourite book on the topic and a fun read.

Last edited by bakunin; 01-16-2018 at 10:06 AM.. Reason: corrected typos and clarified text
 

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Passing Vars between scripts

Im running a script that runs scripts within it self and i need to pass vars made in the original script to scripts run within it and the only way i can think to do it is right the string to a file and read the file in the script (4 Replies)
Discussion started by: rcunn87
4 Replies

2. UNIX for Dummies Questions & Answers

passing variable to function

Hi, I am trying to sum up numbered columns and in order to tidy up the program I have wrote a function to do the adding of some numbers. I have a problem though with passing a variable to the function in the UNIX bash shell. The function only gives the first number in the variable list and does... (4 Replies)
Discussion started by: Knotty
4 Replies

3. Shell Programming and Scripting

Passing global variable to a function which is called by another function

Hi , I have three funcions f1, f2 and f3 . f1 calls f2 and f2 calls f3 . I have a global variable "period" which i want to pass to f3 . Can i pass the variable directly in the definition of f3 ? Pls help . sars (4 Replies)
Discussion started by: sars
4 Replies

4. AIX

ErrCode:-2 Message:Application Initialisation function Err Params:Could not Load SO

hello, I got this error while I was trying to start some application in UNIX. It was an AIX 5.0 machine. It was not loading an .so file.Can anyone help me solving this issue...Its urgent please!!!!! (1 Reply)
Discussion started by: arun_chelsea
1 Replies

5. UNIX for Advanced & Expert Users

Set vars (by reference) in function

Hello everyone, I am curious to find a possible way of doing something like this in ksh: call a function and have that function set the value of the variable that the function knows by the name of $1.... example: #! /bin/ksh set_var(){ case $1 in var1) this is where I would like to... (7 Replies)
Discussion started by: gio001
7 Replies

6. Shell Programming and Scripting

Passing the parameters using a function

Hi All, I am new to shell scripting required some help in passing the parameter value to the shell script. I am writing a shell script, in the script I have created two functions as below. first function get_trend_ids () { Here I am connecting to the database and getting all the... (3 Replies)
Discussion started by: shruthidwh
3 Replies

7. Shell Programming and Scripting

passing argument from one function to another

Hi all, In the given script code . I want to pass the maximum value that variable "i" will have in function DivideJobs () to variable $max of function SubmitCondorJob(). Any help? Thanks #!/bin/bash ... (55 Replies)
Discussion started by: nrjrasaxena
55 Replies

8. Shell Programming and Scripting

Passing alias to a function

The objective of this function is to validate the file full path. cat /dev/null > crontab_NOTEXISTS.txt function File_Existence # Accepts 1 parameter { file_name="$(echo $1)" echo "${file_name}" && break || echo "$file_name NOT FOUND" >> crontab_NOTEXISTS.txt } while read file_name... (7 Replies)
Discussion started by: aimy
7 Replies

9. UNIX for Dummies Questions & Answers

Passing Input To Function

May i please know why is it printing the script name for $0 when i pass those parameters to function. #!/bin/bash -x usage() { echo "In Usage Function" echo $0 echo $1 echo $2 } echo "printing first time" echo $0 echo $1 echo $2 usage $0 $1 $2 Output: (2 Replies)
Discussion started by: Ariean
2 Replies

10. Shell Programming and Scripting

Passing variable value in a function to be used by another function

Hello All, I would like to ask help from you on how to pass variable value from a function that has been called inside the function. I have created below and put the variables in " ". Is there another way I can do this? Thank you in advance. readtasklist() { while read -r mod ver... (1 Reply)
Discussion started by: aderamos12
1 Replies
All times are GMT -4. The time now is 05:49 PM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy