How does a Bash for loop read script parameters? [duplicate] - bash

This question already has answers here:
What is $opt variable for command line parameter in bash
(3 answers)
Closed 4 years ago.
Normally, script parameters are read from $1, $2, ...
Sometimes this is combined with shift and a while-loop and case-statement to process multiple parameters.
while [[ $# > 0 ]]; do
case "$1" in
-v|--verbose)
VERBOSE=1
;;
-d|--debug)
VERBOSE=1
DEBUG=1
;;
*) # unknown option
echo 1>&2 -e "${COLORED_ERROR} Unknown command line option '$key'.${ANSI_NOCOLOR}"
exit 1
;;
esac
shift # parsed argument or value
done
Today, I found a code snippet based on a simple for-loop:
#! /bin/bash
for opt; do
echo $opt
done
Execution:
$ ./test.sh foo bar spam
foo
bar
spam
Normally, one would see for i in ...; do.
Why/how can a simplified for-loop access script parameters?
Does it also work with parameters in functions?

From help for:
If in WORDS ...; is not present, then in "$#" is assumed.

Related

Ways to provide list of parameters to options in shell scripts? [duplicate]

This question already has answers here:
How do I parse command line arguments in Bash?
(40 answers)
Closed 2 years ago.
Basically I am making a script where I would like to give a list of parameters to some option, say -l, eg:
usr#domain:$./somescript -l hi bye cry nigh
The list specified to -l would be then stored into a specific array and iterated over.
So far, I have been using these lines from Arch linux's mkinitcpio script to do so. This allows one to specify a comma-separated list to an option:
_optaddhooks()
while :; do
case $1 in
-A|--add|--addhooks)
shift
IFS=, read -r -a add <<< "$1"
_optaddhooks+=("${add[#]}")
unset add
;;
What are some other methods to do this, particularly when other options/parameters will be used? Can the list provided to an option be space separated? Or is specifying a list by "," (or some other character") easier to manage?
UPDATE: OP is looking for a non-getopts solution; adding a -l option to the current code:
NOTE: OP has shown the command line flag as -l so not sure what the -A|-add|--addhooks) relates to ... ???
unset _optaddhooks
while :; do
case "${1}" in
-A|--add|--addhooks)
shift
....
;;
-a) shift
vara="${1}"
;;
-l) shift
_optaddhooks=( ${1} )
;;
-z) shift
varz="${1}"
;;
....
esac
done
OP would still use the same command line as in the earlier answer (below):
$ ./somescript -a this_is_a -l 'hi bye cry nigh' -z 123456
If you're willing to wrap the -l args in quotes you could then pass the args as a single parameter and then have bash parse this parameter however you wish.
One idea to load the -l args into an array named _optaddhooks[]:
$ cat somescript
#!/usr/bin/bash
while getopts :a:l:z: opt
do
case ${opt} in
a) vara="${OPTARG}" ;;
l) _optaddhooks=( ${OPTARG} ) ;;
z) varz="${OPTARG}" ;;
*) echo "Sorry, don't understand the option '${opt}'" ;;
esac
done
typeset -p vara _optaddhooks varz
A sample run:
$ ./somescript -a this_is_a -l 'hi bye cry nigh' -z 123456
declare -- vara="this_is_a"
declare -a _optaddhooks=([0]="hi" [1]="bye" [2]="cry" [3]="nigh")
declare -- varz="123456"
While this was a simple example, it should be easy enough to modify the code (l section of the case statement) as needed.

Read Shell Script option separated by space [duplicate]

This question already has answers here:
How do I parse command line arguments in Bash?
(40 answers)
Closed 2 years ago.
I have this shell script:
for i in "$#"
do
case $i in
-l=*|--ddloc=*)
DDLOC="${i#*=}"
shift # past argument=value
;;
*)
# unknown option
;;
esac
done
Its working fine as -x=y but i want to be like -x y. What changes will be required here?
for i in "$#"
do
case $i in
-l=*|--ddloc=*)
DDLOC="${i#*=}"
shift # past argument=value
;;
-l|--ddloc)
shift # past argument
DDLOC="$1"
shift # past value
;;
*)
# unknown option
;;
esac
done

getopt multiple line statements while parsing arguments

Having a bit of trouble here.
I haven't had to do long options ever, so I am trying getopt rather than getopts.
For some reason it keeps stating shift as an unrecognized token.
Any reason why?
Also is this a proper implementation for getopt? Or is there a better method for this?
BASH SCRIPT BELOW:
FLAGS=$(getopt --long "help,user:" --name $PROGNAME -- "$#")
echo $FLAGS
eval set -- "$FLAGS"
while true; do
case $1 in
--help)
usage()
shift
;;
*)
shift
exit 1
;;
esac
shift
done
In Bash you don't call functions with brackets - usage() should instead be usage.

getopts not working when called with an argument [duplicate]

This question already has answers here:
Why does getopts only work the first time?
(2 answers)
Closed 3 years ago.
This is my first attempt using getopts, and so far it hasn't been working for me. The code in my script is:
while getopts "s:" opt; do
case $opt in
s) subj=$OPTARG;;
\?) echo "Incorrect usage";;
esac
done
echo ""
echo $subj
When I try to run to script like this:
myScript.sh -s 100
I want it to echo the subject id number I've specified. So far though it just gives me a blank statement.
getopts uses the current value of OPTIND to know which argument to look at next. If you are using source to run your script, though, OPTIND never gets reset between calls. You probably added subj after the first run, so that its value wasn't set the first time you sourced the script. Explicitly setting OPTIND=1 would fix it.
$ source myScript.sh -s 100
100
$ unset subj; source myScript.sh -s 100
$ OPTIND=1
$ source myScript.sh -s 100
100

How to read arguments from bash [duplicate]

This question already has answers here:
Creating bash scripts that take arguments
(3 answers)
Closed 8 years ago.
I am curious as to how to pass in arguments via terminal to the bash script and read them and process the script functions based on the arguments.
So if I did something like:
./scriptname.sh install
#or
./scriptname.sh assets install
How would I say, ok the first argument installs something, while the second sais to do something else based on the first argument.
$0 is the name of the command
$1 first parameter
$2 second parameter
$3 third parameter etc. etc
$# total number of parameters
for args in $*
blah blah
One great way to pass arguments to a script is to use the bash builtin functionality getopts
you can use it like this:
# a script that accepts -h -a <argument> -b
while getopts "ha:b" OPTION
do
case $OPTION in
h)
# if -h, print help function and exit
helpFunction
exit 0
;;
a)
# -a requires an argument (because of ":" in the definition) so:
myScriptVariable=$OPTARG
;;
b)
# do something special
doSomeThingSpecial
;;
?)
echo "ERROR: unknonw options!! ABORT!!"
helpFunction
exit -1
;;
esac
done
You can access a particular argument with $1, $2, ... See eg What does "$1/*" mean in "for file in $1/*"
You can also use "$#" to loop on your arguments. Ex : https://github.com/gturri/dotfiles/blob/master/bootstrap.sh#L64

Resources