Bash command line arguments, replacing defaults for variables - bash

I have a script which has several input files, generally these are defaults stored in a standard place and called by the script.
However, sometimes it is necessary to run it with changed inputs.
In the script I currently have, say, three variables, $A $B, and $C. Now I want to run it with a non default $B, and tomorrow I may want to run it with a non default $A and $B.
I have had a look around at how to parse command line arguments:
How do I parse command line arguments in Bash?
How do I deal with having some set by command line arguments some of the time?
I don't have enough reputation points to answer my own question. However, I have a solution:
Override a variable in a Bash script from the command line
#!/bin/bash
a=input1
b=input2
c=input3
while getopts "a:b:c:" flag
do
case $flag in
a) a=$OPTARG;;
b) b=$OPTARG;;
c) c=$OPTARG;;
esac
done

You can do it the following way. See Shell Parameter Expansion on the Bash man page.
#! /bin/bash
value=${1:-the default value}
echo value=$value
On the command line:
$ ./myscript.sh
value=the default value
$ ./myscript.sh foobar
value=foobar

Instead of using command line arguments to overwrite default values, you can also set the variables outside of the script. For example, the following script can be invoked with foo=54 /tmp/foobar or bar=/var/tmp /tmp/foobar:
#! /bin/bash
: ${foo:=42}
: ${bar:=/tmp}
echo "foo=$foo bar=$bar"

Related

How to pass arguments to a command line program via bash?

I have a simple python script that takes a value from input and displays it like so:
x = raw_input ("say something:")
print x
I would like to run this exact program through a bash script and pass some parameter to the script so that it can be printed out on the screen? How would I go about doing this with the bash programming language?
p.s. I know about sys.argv, but I am looking for a bash based solution because I want to also be able to use this solution to pass values to command line programs where I may not necessarily be able to access the source code.
Use positional parameters for this
#!/bin/bash
echo "Your first arguement : $1" # Simlarly $2, $3 & so
echo "Whole arguements to the script : $#"
echo "Argument Count : ${##}"
And run it like :
./script "xxmbabanexx" # here you have only one argument
For a quick reference , check [ this ]. For a complete reference, check the bash manpage, ie do
man bash
in the terminal and scroll down to Positional Parameters and then check Special Parameters section just below that.

Concatenate command string in a shell script

I am maintaining an existing shell script which assigns a command to a variable in side a shell script like:
MY_COMMAND="/bin/command -dosomething"
and then later on down the line it passes an "argument" to $MY_COMMAND by doing this :
MY_ARGUMENT="fubar"
$MY_COMMAND $MY_ARGUMENT
The idea being that $MY_COMMAND is supposed to execute with $MY_ARGUMENT appended.
Now, I am not an expert in shell scripts, but from what I can tell, $MY_COMMAND does not execute with $MY_ARGUMENT as an argument. However, if I do:
MY_ARGUMENT="itworks"
MY_COMMAND="/bin/command -dosomething $MY_ARGUMENT"
It works just fine.
Is it valid syntax to call $MY_COMMAND $MY_ARGUMENT so it executes a shell command inside a shell script with MY_ARGUMENT as the argument?
With Bash you could use arrays:
MY_COMMAND=("/bin/command" "-dosomething") ## Quoting is not necessary sometimes. Just a demo.
MY_ARGUMENTS=("fubar") ## You can add more.
"${MY_COMMAND[#]}" "${MY_ARGUMENTS[#]}" ## Execute.
It works just the way you expect it to work, but fubar is going to be the second argument ( $2 ) and not $1.
So if you echo arguments in your /bin/command you will get something like this:
echo "$1" # prints '-dosomething'
echo "$2" # prints 'fubar'

Run a bash including a variable in the "bash XXX.sh" command

I am completely new to "programming" in Linux, and I wonder if it is possible to include the definition of a variable when I run a bash file.
My bash file needs the variable in order to go from one or another path, so I would like to be able to include it when running the script.
Something like this:
bash MYFILE.sh -VARIABLE
So the -VARIABLE would be used in the script.
Thank you!
You can take advantage of shell parameter expansion to smoothly read variables from the environment of the parent process, if it's that what you want to achieve.
Look at the following script named test.sh:
#!/bin/bash
VARIABLE=${VARIABLE:="default value"}
echo $VARIABLE
If you start it with the line
$ ./test.sh
it outputs
default value
But if you invoke test.sh with the line
$ VARIABLE="custom Value" ./test.sh
it outputs
custom value
But make sure that the variable assignment is at the beginning of the line. Otherwise it is passed to test.sh as command line argument.
The used form of parameter expansion ${parameter:=word} is described in the bash reference manual as:
If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way.

While executing shell scripts, how to know which line number it's executing,

While executing shell scripts, how to know which line number it's executing, do have write a wrapper , where i can execute a shell scripts from a shell scripts and to know which line number it's executing.
You can set the PS4 variable to cause set -x output to include the line number:
PS4=':${LINENO}+'
set -x
This will put the line number before each line as it executes:
:4+command here
:5+other command
It's important to have some sigil character (such as a + in my examples) after your variable expansions in PS4, because that last character is repeated to show nesting depth. That is, if you call a function, and that function invokes a command, the output from set -x will report it like so:
:3+++command run within a function called from a function
:8++command run within a function
:19+line after the function was called
If multiple files are involved in running your script, you might want to include the BASH_SOURCE variable as opposed to only LINENO (assuming this really is a bash script, as opposed to /bin/sh -- be sure your script starts with #!/bin/bash!):
PS4=':${BASH_SOURCE}:${LINENO}+'
set -x
Bash has a special variable $LINENO which does what you want.
#!/bin/bash
echo "$LINENO"
echo "$LINENO"
echo "$LINENO"
Demo:
$ ./lineno
2
3
4
#!/bin/sh -x
will report the lines as they're executed (the -x option, to be clear). It won't give you the line number, but report the actual line.
An alternative, but more painful, approach is to use a trap handler, as documented here.

Problem in running a script

i have unix shell script which is need to be run like below
test_sh XYZ=KLMN
the content of the script is
#!/bin/ksh
echo $XYZ
for using the value of XYZ i have do set -k before i run the script.
is there a way where i can do this without doint set -k before running the script. or is there something that i can do in the script where i can use value of the parameter given while running the script in the below way
test_sh XYZ=KLMN
i am using ksh.
Any help is appreciated.
How about running this?
XYZ=KLMN ./test_sh //running from directory where test_sh is
If your script needs no other arguments, a quick and dirty way do to it is to put
eval "$#"
at the start of your script. This will evaluate the command line arguments as shell commands. If those commands are to assign a shell/environment variable, then that's what it will do.
It's quick-and-dirty since anything could be put on the command line, causing problems from a syntax error to a bad security hole (if the script is trusted).
I'm not sure if "$#" means the same in ksh as it does in bash - using just $* (without quotes) would work too, but is even dirtier.
It looks like you are trying to use the environment variable "INSTANCE" in your script.
For that, the environment variable must be set in advance of executing your script. Using the "set" command sets exportable environment variables. Incidentally, my version of ksh dates from 1993 and the "-k" option was obsolete back then.
To set an environment variable so that it is exported into spawned shells, simply use the "export" command like so:
export INSTANCE='whatever you want to put here'
If you want to use a positional parameter for your script -- that is have the "KLMN" value accessed within your script, and assuming it is the first parameter, then you do the following in your script:
#!/bin/ksh
echo $1
You can also assign the positional parameter to a local variable for later use in your script like so:
#!/bin/ksh
param_one=$1
echo $param_one
You can call this with:
test_sh KLMN
Note that the spacing in the assignment is important -- do not use spaces.
I am tring this option
#!/bin/ksh
echo $1
awk '{FS="=";print $2}' $1
and on the command line
test_sh INSTANCE=LSN_MUM
but awk is failing.is there any problem over here?
Probably #!/bin/ksh -k will work (untested).

Resources