How to pass an argument in a .shell script file - linux

This is the first time i am trying to edit a .sh file on ubuntu
ng build #xyz--abc/my-${library}
I am trying to pass a flag --build-optimizer=false but if i add it to end it is giving error Unknown option: '--build-optimizer'
Need some help on how can I add this flag.
Thanks

Usually commandline argument option parsing is implemented with either the bash builtin getopts or one of the platform specific getopt implementations. While getopts does not support parsing long commandline options the GNU getopt implementation does. This answer points out in detail the differences between the corresponding implementations. For an example on how to use the bash builtin getopts I'll refer to the Advanced Bash Scripting Guide.
In order to give you a correct answer it therefore depends on how the script you're trying to modify implements commandline option parsing.

LS_OPTIONS=''
while [ $# -gt 0 ]; do
case "$1" in
--color=*)
colorarg="${1#*=}"
LS_OPTIONS="${LS_OPTIONS} ${1}"
;;
-a|--all)
allarg="${1}"
LS_OPTIONS="${LS_OPTIONS} ${1}"
;;
*)
printf "* Error: Invalid argument.*\n"
exit 1
esac
shift
done
printf "all val: %s\n\n" "$allarg"
printf "color val: %s\n\n" "$colorarg"
ls ${LS_OPTIONS}
Parses the arguments and passes them to the underlying ls. Is that what you are trying to achieve?

Related

How can I change a bash script's `echo` output?

My problem consists that I need to change a bash script's output, printed with echo, using a tool (like sed or awk) that works on most of all the GNU/Linux distributions and, if it is possible, on MacOS X too.
The script is available on the CS50 IDE, it is called apache50 and it's usage output is:
Usage: apache50 [start VHOST_DIR|restart|reload|stop|status]
The output I want to print is:
Usage: cli webserver [start VHOST_DIR|restart|reload|stop|status]
To execute apache50 I pass the instruction as argument to a function and then I try to change the output produced:
optional_args(){
${#:2} | sed 's/apache50/cli webserver/g'
}
case $opt in:
webserver)
optional_args $opt "apache50" $#
break;
;;
esac
## output:
## Usage: apache50 [start VHOST_DIR|restart|reload|stop|status]
My script is not printing the wanted output.
Here is a part of apache50:
usage() {
echo "Usage: `basename $0` [start VHOST_DIR|restart|reload|stop|status]" 1>&2
exit 1
}
case "$1" in
*)
usage
;;
esac
If you know how to make it in a better way, please make me a suggestion!
The usage information might be printed to standard error, while sed processes only standard input (on the other side of the pipe, the command's standard output).
You might redirect standard error to standard output:
${#:2} 2>&1 | sed 's/apache50/cli webserver/g'
But that would conflict with the original intention (showing an error message along with usage info, for instance.)

getopts: How to accept arguments that aren't tied to an option in my script? [duplicate]

This question already has answers here:
How do I parse command line arguments in Bash?
(40 answers)
Closed 6 years ago.
I'm writing a Bash script that has the following usage:
ci-badge -t|-a [-b branch] [-m] [-d description] [-l [link] ] repo
Examples:
$ ci-badge -t foo/bar
$ ci-badge -ab dev foo/bar -m
$ ci-badge quux/bar -md 'Hello, world.'
More samples can be found here on GitHub. Anyway, I'm wondering exactly how to implement argument parsing for this script using getopts. After a few hours looking at this basic getopts guide and scouring SO, this is what my code looks so far:
#!/usr/bin/env bash
generate_url=false # set to true if -l is passed with no arg
markdown=false # true -> surround the URL with markdown
# Parse options
while getopts ':tab:md:l:' opt
do
case "$opt" in
a) service=appveyor ;;
b) branch=$OPTARG ;;
d) description=$OPTARG ;;
l) url=$OPTARG ;;
m) markdown=true ;;
t) service=travis ;;
# Colon: runs if no args are passed to
# an option that normally requires parameters.
:) test "$OPTARG" = l && generate_url=true ;;
# ?: Runs if an invalid option is passed.
'?') die ;;
esac
done
As you can see, most of the functionality is there, but I'm wondering how to accept repo as an argument to the script. Since getopts stops parsing after it encounters the first non-option argument, I'm wondering, how would I implement this (preferably with minimal complexity)? The guide I linked earlier doesn't seem to mention dealing with arguments that aren't associated with an option, so I'm a bit lost.
Thanks for helping!
Use $OPTIND value. After getopts cycle:
shift $((OPTIND-1))
echo $#
echo $1 $2 ...

need help parsing shell script command line arguments

I am new to Unix shell scripting and would like some help with writing small script.
I have defined a following synopsis for my script:
install.sh [-h|-a path|[-k path][-f path][-d path][-e path]]
ie user can request some help (-h), install all to a specified place (-a path), or install one or more of a components (-k, -f, -d -e) to a appropriate paths. If there is no arguments, the help should be shown.
Thanks in advance.
You can use getopts to parse a command line with bash. Here is an example taken from Bash/Parsing command line arguments using getopts (obviously you'd have to adjust the options to your needs).
#!/bin/bash
#Set a default value for the $cell variable
cell="test"
#Check to see if at least one argument was specified
if [ $# -lt 1 ] ; then
echo "You must specify at least 1 argument."
exit 1
fi
#Process the arguments
while getopts c:hin: opt
do
case "$opt" in
c) cell=$OPTARG;;
h) usage;;
i) info="yes"
n) name=$OPTARG;;
\?) usage;;
esac
done
Related SO question How do I parse command line arguments in bash?
For more information search for getopts on this man page for bash.

issue in getopt , Unix shell script

Hi can someone fix this issue, i am not able to get outpt.
I am not able to get output of -p.
#!/bin/bash
args=`getopt c:m:p $*`
if [ $? != 0 -o $# == 0 ]
then
echo 'Usage: -c <current-dir> -m <my dir> -p <argument>'
exit 1
fi
set -- $args
for i
do
case "$i" in
-c) shift;CURRDIR=$1;shift;shift ;;
-m) MYDIR=$1;shift;;
-p) ARGVAL=$OPTARG;;
esac
done
echo "CURRDIR = $CURRDIR"
echo "MYDIR = $MYDIR"
echo "ARGVAL = $ARGVAL"
./1.sh -c "def" -m "ref" -p "ref -k ref"
Expected output
output -c = "def"
-m ="ref"
-p ="ref -k ref"
getopt
args=`getopt c:m:p $*`
You need to add a colon after the p to indicate that -p takes an argument. Also you should change $* to "$#" for better handling of spaces.
args=`getopt c:m:p: "$#"`
You are also mixing up getopt and getopts. $OPTARG is a getopts feature. With plain getopt and set you should simply use $2 and then shift off the argument.
-p) ARGVAL=$2; shift 2;;
At this point you've done as good as you can with getopt. Unfortunately it doesn't handle the multi-word argument to -p no matter what you do. For that, we need to use getopts.
getopts
From getopt and getopts:
Easier to use and generally better than getopt, though of course not available in csh-like shells. You shouldn't be using those anyway.
This works rather differently than "getopt". First, because it's a built-in, you usually won't find a separate man page for it, though "help getopts" may give you what you need.
The old "getopt" is called once, and it modifies the environment as we saw above. The builtin "getopts" is called each time you want to process an argument, and it doesn't change the original arguments .
Using getopts is a lot simpler. Your entire loop can be simplified to this:
while getopts c:m:p: flag
do
case "$flag" in
c) CURRDIR=$OPTARG;;
m) MYDIR=$OPTARG;;
p) ARGVAL=$OPTARG;;
esac
done
No shifting needed, you just read $OPTARG each time to get each option's value.

Using getopt in unix shell

I have to use a Unix script to pass arguments:
./Script.sh -c "abc" -d "def" -k "abc -d -c"
where the argument for:
-c = "abc"
-d = "def"
-k = "abc -d -c"
How can I handle options in a Uunix shell script?
Here is some option handling using getopts:
# -F Final version (do not append date to version)
# -s suffix Add '-suffix' after version number
# -V Print version and exit
# -h Print help and exit
# -j jdcfile JDC file for project - required
# -q Quiet operation
# -v Verbose operation
arg0=$(basename $0 .sh)
usage()
{
echo "Usage: $arg0 [-hqvFV] [-s suffix] -j jdcfile file.msd" 1>&2
exit 1
}
error()
{
echo "$0: $*" 1>&2
exit 1
}
Fflag=
suffix=
jdcfile=
qflag=
vflag=no
while getopts FVhj:qs:v opt
do
case "$opt" in
(F) Fflag="-F";;
(V) echo "Version information";;
(h) echo "Help information";;
(j) jdcfile="$OPTARG";;
(q) qflag="-q";;
(s) suffix="$OPTARG";;
(v) vflag=yes;;
(*) usage;;
esac
done
shift $(($OPTIND - 1))
case $# in
(1) : OK;;
(*) usage;;
esac
if [ -z "$jdcfile" ]
then error "you did not specify which jdcfile to use (-j option)"
fi
The script then continues and does its task based on the options it was given. The shift removes the 'consumed' options, leaving just the file name arguments.
The argument can contain whitespace, so either use the getopts built-in shell command or the GNU enhanced version of the external getopt program.
The getopts option is more portable, because not all systems have the GNU enhanced version of getopt. For example, Linux has the GNU enhanced version, but Mac OS X does not. The original version of getopt does not support whitespaces. Despite this limitation, there is a reason why you might want to use toe the GNU enhanced version: it supports long option names, which getopts does not.
This is how to use the GNU enhanced getopt with whitespaces. It is important to use "$#" (use $# instead of $* and make sure the double quotes are around it) and to eval the whole set command so that whitespaces are handled properly.
eval set -- `getopt --long currdir:,dir:,argval:,verbose -o c:d:k:v -- "$#"`
while [ $# -gt 0 ]
do
case "$1" in
-c | --currdir) CURRDIR="$2"; shift;;
-d | --dir) MYDIR="$2"; shift;;
-k | --argval) ARGVAL="$2"; shift;;
-v | --verbose) VERBOSE=yes;;
esac
shift
done
There is a command getopts, and a program getopt, though I'm of the opinion that by the time you need to handle arguments, you've outgrown shell scripting.
I'm not actually sure how getopts work, having never actually used it; but here, and check your shell's docs.
getopt splits your arguments into flags -- rest as far as I can tell.

Resources