Here is my variable:
time="$(date)";
I have used positional parameter set -- $time
to form JSON format
JSON_FMT='{"time" : "%s"}\n'
printf "$JSON_FMT" "${time}"
Here the variable is not getting printed. Any solution to this ?!
Related
I'm writing a simple graphing script that uses gnuplot, and I use a helper function to construct a .gscript file.
add_gscript() {
echo "->>"
echo $1
echo $1 >> plot.gscript
cat plot.gscript
}
However after passing the following argument into the function
echo "--"
echo 'set xrange [0:$RANGE]'
echo "--"
add_gscript "set xrange [0:100]"
where $RANGE has been defined beforehand, I get the following output
--
set xrange [0:$RANGE]
--
->>
set xrange 1
set datafile separator ","
set term qt size 800,640
set size ratio .618
set xrange 1
Is bash evaluating [0:100] to 1 somehow?
A fix was accurately described in comments on the question:
Always double-quote variable references to have their values treated as literals; without quoting, the values are (in most contexts) subject to shell expansions, including word splitting and pathname expansion. [0:100] happens to be a valid globbing pattern that matches any file in the current dir. named either 0 or : or 1. – mklement0
so echo "$1"; echo "$1" >> plot.gscript and any other unquoted vars. Good luck. – shellter
Double quoting the variables did indeed fix my issue. Thanks!
I'm unable to substitute the argument value(s) in the bash command as below:
# echo $int1
{"id":"74953939-fd20-4472-8aaa-067e6f4c4106"}
# echo $int2
{"id":"5ef4664d-3600-4df9-a6a9-01ffb0f49422"}
# echo $int3
{"id":"6dc95c01-742e-4225-8298-e5750fe67f27"}
# set -x
# data set net-agent interfaces '["$int1", "$int2", "$int3"]'
+ data set net-agent interfaces '["$int1", "$int2", "$int3"]'
Any idea on why the values are not being substituted?
Thanks!
I'm guessing that the argument to the command should be valid JSON, in which case you should remove the double quotes from around each variable and wrap the entire string in double quotes so variables are expanded:
data set net-agent interfaces "[$int1, $int2, $int3]"
Using set -x, this produces:
$ data set net-agent interfaces "[$int1, $int2, $int3]"
+ data set net-agent interfaces '[{"id":"74953939-fd20-4472-8aaa-067e6f4c4106"}, {"id":"5ef4664d-3600-4df9-a6a9-01ffb0f49422"}, {"id":"6dc95c01-742e-4225-8298-e5750fe67f27"}]'
I have a ksh script that reads a profile script with a number of sessions defined. Each session defines its own parameters as such:
SESSION_ONE_USER=...
SESSION_ONE_PWD=...
SESSION_TWO_USER=...
...
The script gets the SESSION parameter from the command line, but I simply set it for the example.
I want to let the SESSION parameter value define part of another parameter name, that I need the value from, like:
SESSION="SESSION_ONE"
USER=${${SESSION}_USER}
PASS=${${SESSION}_PWD}
That gives me a compile error.
I also tried
GET_USER_PARAM(){
echo ${SESSION}_USER
}
echo $`GET_USER_PARAM`
But that returns $SESSION_ONE_USER
I want it to return the value of the parameter SESSION_ONE_USER instead.
Does anyone have any solutions?
This is what eval is for:
SESSION=SESSION_ONE
eval echo \$${SESSION}_USER
should display the value of $SESSION_ONE_USER.
Don't monkey with variable names, use associative arrays instead
typeset -A users
typeset -A pwd
session=SESSION_ONE
users[$session]=joe
pwd[$session]=secret
for key in "${!users[#]}"; do
echo "user for session $key is ${users[$key]}"
echo "pwd for session $key is ${pwd[$key]}"
done
Try this:
SESSION="SESSION_ONE"
SESSION_ONE_USER="foo"
SESSION_ONE_PWD="bar"
SESSION_USER=${SESSION}_USER
SESSION_PWD=${SESSION}_PWD
USER=${!SESSION_USER}
PASS=${!SESSION_PWD}
echo $USER
echo $PASS
The "!" does a level of indirection. See Shell Parameter Expansion.
If this is ksh, then this is a job for nameref
alias nameref='typeset -n'
Example Solution
function session_parameters { set -u
typeset session=${1:?session name}
nameref user=SESSION_${session}_USER
nameref pass=SESSION_${session}_PASS
print session=$session user=$user pass=$pass
}
SESSION_ONE_USER="User1"
SESSION_ONE_PASS="Pass1"
SESSION_TWO_USER="User2"
SESSION_TWO_PASS="Pass2"
for s in ONE TWO THREE; do
session_parameters $s
done
Sample output
session=ONE user=User1 pass=Pass1
session=TWO user=User2 pass=Pass2
test_session_parameters[12]: session_parameters: line 5:
SESSION_THREE_USER: parameter not set
Note the usage of set -u to force the error message on line 3.
nameref usage: (from the builtin help text)
NAME
typeset - declare or display variables with attributes
SYNOPSIS
typeset [ options ] [name[=value]...]
-n
Name reference.
The value is the name of a variable that name references. name cannot contain a ... Cannot be use with any other options.
I am new to linux shell script. i want that my script read a property file and save the value in any variable , the same which i can pass in same script..
as i wrote script is not fulfilling my requirement:
!/bin/bash
. test1
flat
if [ "$1" == test1 ]; then
flat=$1; /assign value to var flat
echo "flat"
fi
test1 is property file which includes :
la=12
tu=15
now i want when i run:
./myscript la
it read it from property file and store the value in flat variable.
Please help me.
You just need to use indirect referencing, but to do so, you need to store the value of the special parameter $1 in a regular parameter first.
!/bin/bash
. test1
var="$1"
# Only assign to flat if the variable specified in var is defined
if [ -n "${!var:-}" ]; then
flat="${!var}"; # assign value to var flat
echo "flat"
fi
First, ${!var} expands to the value of the variable whose name is in var. If var is "foo", it's the same as $foo. If var is "baz", it's the same as $baz.
${var:-default} expands to the value of var if it is set and has a non-null value. Otherwise, it expands to whatever you have after the ':-', in this case the string default. If there is no string, it uses the null value. So ${var:-} would expand to the null string if var was not set (or was already the null string).
Combining the two, ${!var:-} takes the variable var, and uses its value as a variable name. It then tries to expand that variable, and if it isn't set or is null, expand to the null string. So if var is la, it expands to the value of la. If var is re, and there is no variable re set, it expands to the null string.
Finally, the -n operator tests if its argument is non-zero length. In other words, it checks that the result of trying to expand the variable whose name is in var is not the null string. If that's true, then expand it again (yes, it's a little redundant) and assign its value to flat.
As the answer is written above, the variable flat is undefined if the argument to the script is not the name of a variable set in test1. If you don't mind flat being set regardless (say, flat=""), you don't need the if statement. You can just use one line to set the value of flat:
#!/bin/bash
. test1
var="$1"
flat="${!var:-}"
If I understood correctly you want to achieve an indirect variable dereferencing (see e.g. this example).
The solution is to use eval:
eval flat=\$$1
I want to save the variable name and its contents easily from my script.
Currently :-
LOGFILE=/root/log.txt
TEST=/file/path
echo "TEST : ${TEST}" >> ${LOGFILE}
Desired :-
LOGFILE=/root/log.txt
function save()
{
echo "$1 : $1" >> ${LOGFILE}
}
TEST=/file/path
save TEST
Obviously the above save function just saves TEST : TEST
Want I want it to save is TEST : /file/path
Can this be done? How? Many thanks in advance!
You want to use Variable Indirection. Also, don't use the function keyword, it is not POSIX and also not necessary as long as you have () at the end of your function name.
LOGFILE=/root/log.txt
save()
{
echo "$1 : ${!1}" >> ${LOGFILE}
}
TEST=/file/path
save TEST
Proof of Concept
$ TEST=foo; save(){ echo "$1 : ${!1}"; }; save TEST
TEST : foo
Yes, using indirect expansion:
echo "$1 : ${!1}"
Quoting from Bash reference manual:
The basic form of parameter expansion is ${parameter} [...] If the first character of parameter is an exclamation point (!), a level of variable indirection is introduced. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion
Consider using the printenv function. It does exactly what it says on the tin, prints your environment. It can also take parameters
$ printenv
SSH_AGENT_PID=2068
TERM=xterm
SHELL=/bin/bash
LANG=en_US.UTF-8
HISTCONTROL=ignoreboth
...etc
You could do printenv and then grep for any vars you know you have defined and be done in two lines, such as:
$printenv | grep "VARNAME1\|VARNAME2"
VARNAME1=foo
VARNAME2=bar