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.
Related
For example, I have a bash script named getimage. In the script I have:
wget http://www.example.com/images/1.jpg
If I type bash getimage in the terminal, it would download the picture.
But what I want is to type bash getimage 2 or bash getimage 3 and so on in the terminal and download 2.jpg or 3.jpg respectively.
Basically, I want to type a number in terminal (bash getimage number) and have it correspond to wget http://www.example.com/images/number.jpg.
As Aaron mentioned in comments, you need to give the variables externally by specifying them as $1 or $2 etc in your script.
The way to do this is-
wget http://www.example.com/images/"$1".jpg
Then launch your script as bash getimage 1
If (as I suspect) you want to wget in a loop, do-
for i in {1..10} ; do bash getimage "$i" ; done
Or from the commandline,
for i in {1..10} ; do wget http://www.example.com/images/"$i".jpg ; done
Here's what I would do :
#!/bin/bash
image_name=${1-1}
wget "http://www.example.com/images/$image_name.jpg"
The script is to be called as getimage x. If x is omitted, 1 will be chosen as a default value.
The first line is a shebang : it tells your shell to execute the script with the specified executable, /bin/bash.
The second line defines an image_name variable and assigns it the result of an expression. That expression is a parameter expansion, which will return $1 (that is the first parameter passed to the script) if it is defined, or 1 either. It's hard to see in this case, but the syntax is ${variable-default} where variable is a variable name whose value you want, and default a default used when that variable isn't defined.
The third line is your command, where the static 1 has been replaced by a reference to the image_name variable. Note that "" have been added in case the image_name contains spaces : that would break the url in two parts that would be understood by wget as two separate parameters. Don't use '' though, the $variable contained in the string wouldn't be expanded to their value.
A minimal script for what you want would be the following.
#!/usr/bin/env bash
wget "http://www.example.com/images/${1}.jpg"
The first line is called a shebang The shebang tells the script which program to run it in. In this case we use the env program to find the default version of bash in the current environment.
On the second line we simply run your wget command, but we pass in the variable $1. This is a special variable called a positional parameter, in this case the first argument passed to the script.
To run the command, make it executable with chmod +x getimage and then call it like so:
./getimage 1
./getimage 2
etc.
I have this interpreter, which prints the ARGS variable:
#!/bin/bash
echo "[$ARGS]"
I use this interpreter in another script:
#!/usr/bin/env ARGS=first interpreter
Calling the second script, I get
[first]
How do I get
[first second]
?
The short of it: don't rely on being able to pass multiple arguments as part of a shebang line, and the one argument you can use must be an unquoted, single word.
For more background information, see the question #tholu has already linked to in a comment (https://stackoverflow.com/a/4304187/45375).
Thus, I suggest you rewrite your other script to use bash as well:
#!/bin/bash
ARGS='first second' /usr/bin/env interpreter "$#"
This allows you to use bash's own mechanism for defining environment variables ad-hoc (for the command invoked and its children) by prefixing commands with variable assignments, allowing you to use quoting and even define multiple variables.
Whatever command-line arguments were passed in are passed through to interpreter via "$#".
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"
I'm writing a bash shell script. There's a required first argument and I want to have an optional second argument.
If the second argument is omitted I want it to use the value of the first argument.
Currently I have:
SOMEVAR=${2:-Untitled}
How can I use something like basename $1 instead of Untitled?
You can just do something like SOMEVAR=${2:-$(basename "$1")}. You can do any shell or variable in the optional part.
Just use command substitution: $(basename $1), literally instead of Untitled.
However, bash also has the ability to do this without an external process: ${1##*/}
SOMEVAR=${2:-${1##*/}}
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).