You are not logged in.

#1 2017-12-14 21:54:47

Cody Learner
Banned
Registered: 2017-12-06
Posts: 54
Website

[Solved] parsing positional parameters and shift in shell

I'm parsing positional parameters to call functions and pass as variables in this script, https://bbs.archlinux.org/viewtopic.php?id=232437

I don't understand why one would want to shift the parameters? Most similar parsing code I can find all shift after parsing. Why?

Running the test script below indicates nothing but problems that would need worked around, if the script were to ever run more than one function sequentially, using the positional parameters that were used when calling the script.

Are there any problems with how I'm parsing that I am not seeing or understanding?

I also see getopts, getopt, and a few other add ons for parsing, with what I see as introducing their own difficulties. Would anyone care to explain what parsing positional parameters could not easily do, that using getopts would solve?


Thanks

echo 'echo "how many"' "$#"
echo 'echo "what are they"' "$@"
echo
	#    |Operation|Function-Command|Parameter passed|

	case "${1}" in
		    -S)
			echo install		"${@}"
			;;
		    -R)
			echo remove		"${@}"
			;;
		    -C)
			echo cower -uv
			;;
		    -s)
			echo search		"${@}"
			;;
		    -D)
			echo download-dep	"${@}"
			;;
		    -h)
			echo help
			;;
 		   -ch)
			echo cower -h
			;;
		    -p)
			echo cat /var/log/pacman.log
			;;
		     *)
			echo header
			;;
	esac
#	shift
echo
echo '"position 0"' "${0}"
echo '"position 1"' "${1}"
echo '"position 2"' "${2}"
echo '"position 3"' "${3}"
echo '"position 4"' "${4}"
echo '"echo how many"' "$#"
echo '"echo what are they"' "$@"


EDIT: Writing this post got me thinking... Most scripts offer what I'd call: $ program [-operation] [-option] [package],
say -s to search, then options for sort of standard options, like -v for verbose, etc.

Also most programs allow either combining operations/options such as  $ program -sv   -or-  $ program -s -v separately. Throw in a package name at the end and I can imagine covering every possible combination would cause some very lengthy parameter parsing code based on position only..

Last edited by Cody Learner (2017-12-17 21:39:03)


Self designated Linux and Bash mechanic.....
I fix and build stuff hands on. I'm not opposed to creating a mess in obtaining a goal.

Offline

#2 2017-12-14 23:30:39

eschwartz
Fellow
Registered: 2014-08-08
Posts: 4,097

Re: [Solved] parsing positional parameters and shift in shell

Parsing options based on position is doomed to failure, you'd introduce far too much complexity and inflexibility by demanding that no parameters can be optional. And there is nothing special about using case + shift, it is simply reimplementing getopts in shellcode. Somewhat more verbose, but far more flexible.

The Bash guide discusses option parsing: http://mywiki.wooledge.org/BashFAQ/035


Managing AUR repos The Right Way -- aurpublish (now a standalone tool)

Offline

#3 2017-12-15 00:00:05

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,442
Website

Re: [Solved] parsing positional parameters and shift in shell

Your example is quite trivial/simple.  So if that's all you care about there may be no reason to worry about getopt(s).  But often parameters are optional and may have long and short forms, and may have arguments themselves, which may in turn themselves be optional (or sometimes not).

getopt(s) was designed to deal with (most) of these complexities smoothly.  I rarely use getopt(s), but I have several times when it was called for.  It is a tool, and it is the best tool for certain jobs (and completely inappropriate for other jobs).

`shift` has countless uses.  One handy use can be to have functions in a script that act as sub-scripts:

function do_one_thing() {
# ...
}

function do_another_thing() {
# ...
}

shift
"$@"

The shift drops off the script name from the invocation, and what is left is (assumed to be) the name of the function and parameters intended to be passed to the function.  This is oversimplified as it could go horribly wrong if the first parameter was not the name of the function, but it is used well in lots of creative scripts.

Also note in your case statement, without a shift odd things would happen.  For example "yourscript -S pkgname" would not echo "install pkgname" but "install -S pkgname".  A single shift would clear out the -S leaving the (assumed) package name(s).


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#4 2017-12-15 20:33:12

malm
Member
Registered: 2017-10-09
Posts: 7
Website

Re: [Solved] parsing positional parameters and shift in shell

The case "${1}"  + shift should sit within a while loop. That way all your arguments can be processed.

Offline

#5 2017-12-15 20:49:04

malm
Member
Registered: 2017-10-09
Posts: 7
Website

Re: [Solved] parsing positional parameters and shift in shell

I have found an example for you.
https://github.com/git/git/blob/master/ … tch.sh#L30

while test $# != 0
do
	case "$1" in
	--force)
		force=t
		;;
	-v|--verbose)
		verbose=t
		;;
	esac
	shift
done

Offline

#6 2017-12-15 20:52:56

malm
Member
Registered: 2017-10-09
Posts: 7
Website

Re: [Solved] parsing positional parameters and shift in shell

And you can do --foo=<value> type arguments like this

  --foo=*)
    foo="${1#--foo=}" ;;

Offline

#7 2017-12-17 06:18:01

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: [Solved] parsing positional parameters and shift in shell

malm: learn how to use the edit button, there is no call to keep bumping the thread.


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

Board footer

Powered by FluxBB