Substituting argument value in bash - bash

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"}]'

Related

How to get dictionary value to parse variables referenced in value using Bash?

I have a dictionary that has variable names in the value string.
I'm trying to lookup the dictionary value, then parse the result with the actual variable value in the string (not the variable name).
How would I do it?
Example:
asset_symbol='BTC'
counter_asset_symbol='ETH'
Dictionary entry:
['ct']=https://charts.cointrader.pro/charts.html?coin=$asset_symbol%3A$counter_asset_symbol
When calling the value I want it to parse $asset_symbol and $counter_asset_symbol" to "BTC" and "ETH"
So in this case I want:
https://charts.cointrader.pro/charts.html?coin=BTC%3AETH
Examples of what didn't work:
#!/bin/bash
chart_engines=('ct cg')
# No ''
declare -A search_urls=(
['ct']=https://charts.cointrader.pro/charts.html?coin=$asset_symbol%3A$counter_asset_symbol
['cg']=https://beta.coinigy.com/markets/$exchange_symbol/$asset_symbol/$counter_asset_symbol
)
# With single quotes
declare -A search_urls=(
['ct']='https://charts.cointrader.pro/charts.html?coin=$asset_symbol%3A$counter_asset_symbol'
['cg']='https://beta.coinigy.com/markets/$exchange_symbol/$asset_symbol/$counter_asset_symbol'
)
# With double quotes
declare -A search_urls=(
['ct']='https://charts.cointrader.pro/charts.html?coin=$asset_symbol%3A$counter_asset_symbol'
['cg']='https://beta.coinigy.com/markets/$exchange_symbol/$asset_symbol/$counter_asset_symbol'
)
asset_name='Bitcoin'
asset_symbol='BTC'
counter_asset_name='Ethereum'
counter_asset_symbol='ETH'
exchange_name='Binance'
exchange_symbol="BINA"
open_charts_urls(){
for i in ${chart_engines[#]}; do
# Get URL
# Dictonary lookup doesn't fill in the variables.
local charts_url="${search_urls[$i]}"
echo "$charts_url"
# Direct reference does.
# echo "https://beta.coinigy.com/markets/$exchange_symbol/$asset_symbol/$counter_asset_symbol"
# echo "https://charts.cointrader.pro/charts.html?coin=$asset_symbol%3A$counter_asset_symbol"
# local subs="$charts_url"
# echo "subs:$subs"
done
}
open_charts_urls
You are referencing $asset_symbol and $counter_asset_symbol before they are declared. Declare the $search_urls array below the declaration of these symbols. Also, use double quotes for the values within the array. Single quotes will prevent the parameter substitution. See quoting. In your example below the comment # With double quotes you are still using single quotes.

Use shell variable into shell set

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 ?!

Bash Automatically replacing [0:100] with 1

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!

How to make a script read a value from a property file and pass it to the same script?

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

local variable and asterisk

I´ve declared a LOCAL variable (a) inside a function that receives the value of first parameter (${1}). When I call it with a with an asterisk in first parameter´s content, the value assignment had a different treatment. Why?
# function_name () { local a="${1}"; echo $a; }
# set -xv && function_name "param_1_*" && set +xv
set -xv && function_name "param_1_*" && set +xv
+ set -xv
+ function_name 'param_1_*'
+ local 'a=param_1_*'
+ echo 'param_1_*'
param_1_*
+ set +xv
NOTE: + local 'a=param_1_*' <-- See? the quote is inserted before the variable name "a"
# function_name () { a="${1}"; echo $a; }
# set -xv && function_name "param_1_*" && set +xv
+ function_name 'param_1_*'
+ a='param_1_*'
+ echo 'param_1_*'
param_1_*
+ set +xv
NOTE: + a='param_1_*' <-- On this case, the quote is inserted after the equal signal
They're being displayed differently by bash's -x mode, but that doesn't mean bash is treating them differently. What's happening here is that when bash executes local a="${1}", it parses it into some internal representation (something more complicated than a string), substitutes the first parameter into that, and then notices that -x mode is active. So what it does is take that internal representation, and un-parses it into a command you could type in to get the same effect. In general, there will be a number of ways to type in a command that'd produce the same effect (i.e. the internal representation), and it chooses one of these. It could print any of the following:
+ local a='param_1_*'
+ local 'a=param_1_*'
+ local $'a=param_1_*'
+ local a=param_1_"*"
+ local a=param_1_\*
... or any of a number of other possibilities. Its choice may not be the one you'd expect, but it's a perfectly valid way of typing in the "same" command.
BTW, as #Rob said, there is a difference in that a='param_1_*' and 'a=param_1_*' are not equivalent commands, while local a='param_1_*' and local 'a=param_1_*' are equivalent. This is because with the local command, the assignment is essentially a parameter, and quoting around it doesn't matter as much as with a standalone assignment. Thus, when displaying a="${1}", it could print any of:
+ a='param_1_*'
+ a="param_1_*"
+ a=param_1_$'*'
+ a=param_1_\*
but not any of these:
+ 'a=param_1_*'
+ "a=param_1_*"
+ $'a=param_1_*'
I don't think the asterisk is the difference. In your two functions, one is declaring a local and one is setting a shell variable. In the first case you're passing a=param_1_* as an argument to the local builtin (and the shell doesn't care that one of those characters is an * or an =), but in the second the shell is parsing the a=foo into its components. In the first case, it makes sense to put quotation marks around the entire argument, which is a=param_1_*, but it doesn't make sense in the second, since you couldn't really type 'a=param_1_*' at a shell prompt and expect the shell to set the a variable.

Resources