How to create a variable value using $ in the runtime in bash - linux

I have a bash as below where i want to use the value of YYY_XXX_SK_REGISTER_CNTL in the echo .
#! /bin/bash
TRADE_TYPE=$1
YYY_XXX_SK_REGISTER_CNTL=YYY_XXX_SK_REGISTER_template.ctl
echo $TRADE_TYPE"_CTNL"
calling the base as below :
./test.sh YYY_XXX_SK_REGISTER
result expecting in echo : YYY_XXX_SK_REGISTER_template.ctl

If you don't mind changing TRADE_TYPE or using a temporary variable then you can use ${!var} expansion:
TRADE_TYPE="hello"
hello_world=1234
TRADE_TYPE="${TRADE_TYPE}_world"
echo ${!TRADE_TYPE}
# will print 1234

First you need to get rid of the typo, CNTL vs CTNL.
This script does what you want
#!/bin/bash
TRADE_TYPE=$1
YYY_XXX_SK_REGISTER_CNTL=YYY_XXX_SK_REGISTER_template.ctl
eval echo "\$${TRADE_TYPE}_CNTL"
There is probably a better solution than resorting to eval. But you will have to explain what your overall goal is.

I think you are expecting something like below code:
#!/bin/bash
TRADE_TYPE=$1
export TRADE_TYPE
variable="$TRADE_TYPE"_template.ctl
echo $variable

Using indirect variable reference:
#! /bin/bash
TRADE_TYPE="${1}_CNTL"
YYY_XXX_SK_REGISTER_CNTL=YYY_XXX_SK_REGISTER_template.ctl
echo "${!TRADE_TYPE}"
When the following is entered at the command line:
./test.sh YYY_XXX_SK_REGISTER
Your result will be:
YYY_XXX_SK_REGISTER_template.ctl

Related

Export variable from within while loop

I want to export a variable from within a loop. I was not able to do it. I am not sure what is missing here.
Any suggestion would be great help
var="ahs tcs amq tos"
for i in ${var}
do
${i}_log="/var/tmp/pmp_${i}_log"
#export ${i}_log
done
The idea is right, just use the declare variable to create variables on the fly. Also avoid using un-quoted variable expansion(for i in ${var}) for looping. Use a proper array syntax as
var=("ahs" "tcs" "amq" "tos")
for i in "${var[#]}"; do
declare ${i}_log="/var/tmp/pmp_${i}_log"
export "${i}_log"
done
As a side note for good practice, always specify the interpreter to run your script. It could be #!/bin/bash or #!/bin/sh or best do it by #!/usr/bin/env bash
This works on dash and bash (as long as the i's and the path to interpolate them into are reasonable):
#!/bin/sh
var="a b c d"
for i in $var
do
export "${i}_log=/var/tmp/pmp_${i}_log"
#test
sh -c "echo \$${i}_log"
done
An alternative could be to use a single exported associative array instead of multiple variables:
EDIT: oops, this won't work since arrays can't be exported. :\
var="ahs tcs amq tos"
declare -A logs
for i in ${var}
do
logs[$i]="/var/tmp/pmp_${i}_log"
done
echo ${logs[#]}
#### export logs
Also see Inian's answer for better practices for looping and arrays.
This can be done in one line without a loop
printf '%s\n' {ahs,tcs,amq,tos} | xargs -I {} bash -c 'export {}_log="/var/tmp/pmp_{}_log"; echo {}_log=${{}_log}'
or with a loop
#!/bin/bash
for i in {ahs,tcs,amq,tos}; do
#export
export "${i}_log=/var/tmp/pmp_${i}_log";
#test
bash -c 'echo '"${i}_log"'='"\$${i}_log"; done
done
The reason ${i}_log="/var/tmp/pmp_${i}_log" failed is because ${i}_log is unquoted and the syntax for exporting is export somevar=somedefintion. In order to dynamically generate the variable name, surround the statement in quotes so that it gets interpolated. ie. export "${dynamic}_var=${dynamic}_definition"
see http://wiki.bash-hackers.org/syntax/quoting

How to call a variable as a path from another script?

Example
Var = '/etc/sysconfig/..'
export Var
bash script1.sh
in another script1
cat $Var
This is my Problem: The variable does not call the file in this path
Do this:
Var='/etc/sysconfig/..'
bash script1.sh "$Var"
Then in script1.sh:
Var=$1
cat "$Var"
The quotes around "$Var" are required to support paths containing spaces.
Your variable assignment is wrong, it should be:
Var='/etc/sysconfig/..'
No spaces around =.
If you want to send in a environment variable for one script only then you can use:
Var='/etc/sysconfig/..' ./my_script.sh
And inside my_script.sh:
printf "%s\n" "$Var"
# Will print /etc/sysconfig/..
If you want to send arguments to my_script.sh do what #JohnZwinck suggested. What I suggested is only to change environment variable and shouldn't be abused to send/receive regular variables to a command.
I think no need to to more thing
script 1
#!/bin/bash
a="/home/example" ### you can do with export command also export a="/home/example"
sctipt2 ## make effective
. script1;
cd $a

Proper Quoting in Bash: Attach numbers stored in i to a

I wanted to write a short shell script, which removes specified pages from a pdf. Maybe I'm doing that in a bit convoluted manner, but that is what I came up with so far:
#!/bin/bash
#This is a script to remove a specified page from a specified pdf.
set verbose
s="A1-$(($2-1))"
if [ n -ge 3 ]; then
for i in 2..$#
do
s+=A$(($($i)+1))-$(($($(($i+1)))-1))
done
fi
pdftk A="$1" cat $s A$(($($#)+1))-end output output.pdf
I know it's quite convoluted code and if you know about the working of pdftk, I would appreciate a hint to make it easier, but for now I just need to know how to substitute a variable into a variable name. E.g. if
i=2
a2=3
echo $a($i)
gave me 3, that would be great, but it doesn't. How do I achieve this?
bash allows indirect parameter expansion:
$ i=2
$ a2=3
$ var="a$i" # a2
$ echo "${!var}"
3
What you really seem to want, though, is an array:
$ a=([2]=3) # Or simply a[2]=3
$ i=2
$ echo "${a[i]}"
3
(This is really a stop-gap answer, as there is almost certainly a much simpler answer to your question that doesn't involve this type of indirect parameter manipulation.)
I think this much simpler script that will do what you want:
#!/bin/bash
inputfile=$1
shift
ranges=() from=1
for pageToOmit in "$#"; do
ranges+=( "A$from-$(( pageToOmit - 1))" )
from=$(( pageToOmit + 1 ))
done
ranges+=( "$from-end" )
pdftk A="$inputfile" cat "${ranges[#]}" output output.pdf
Using eval:
i=2
a2=3
eval echo \$a$i
eval b=\$a$i
echo $b

Why doesn't this bash code work?

x="a=b"
`echo $x`
echo $a
I expect the second line to generate "a=b", and execute it in the context of the main shell, resulting in a new variable a with value b.
However, what I really get (if I enter the commands manually) is the error message after the second line, bash: a=b: command not found
Why is that so?
Try
eval $x
(And we need 30 characters for this answer to be posted)
What your first echo line does is running in a subshell and returns its value to the callee.. The same result is achieved using $() and is - by the way - easier to use than backticks.
So, what you are doing is first running echo $x (which returns a=b). And, because of the backticks, a=b is returned to the shell that tries to run that line as a command which - obviously - won't work.
Try this in a shell:
$(echo ls)
And you will clearly see what is happening.
It's because of the order in which bash parses the command line. It looks for variable definitions (e.g. a=b) before performing variable and command substitution (e.g. commands in backticks). Because of this, by the time echo $x is replaced by a=b, it's too late for bash to see this as a variable definition and it's parsed as a command instead. The same thing would've happened if you'd just used $x as the command (instead of echo in backticks). As in #mvds's answer, the eval command can be used to force the command to be reparsed from the beginning, meaning that it'll be recognized as a variable definition:
$ x="a=b"
$ `echo $x`
-bash: a=b: command not found
$ $(echo $x) # Exact same thing, but with cleaner syntax
-bash: a=b: command not found
$ $x # This also does the same thing, but without some extra steps
-bash: a=b: command not found
$ eval "$x" # This will actually work
$ echo $a
b
$ a= # Start over
$ eval "$(echo "$x")" # Another way of doing the same thing, with extra steps
$ echo $a
b
Note that when using eval I've put all of the references to $x in double-quotes -- this is to prevent the later phases of bash parsing (e.g. word splitting) from happening twice, since bash will finish its regular parsing process, then recognize the eval command, and then redo the entire parsing process again. It's really easy to get unexpected results from using eval, and this removes at least some of the potential for trouble.
Did you try $x in that funny apostrophes? Without echo, echo seems to be only for displaying string, not execute commands.

Bash:Single Quotes and Double Quotes and Exclamation Mark

I have a simple script named example:
#!/bin/sh
echo $'${1}'
Please note that the usage of $'' here is to convert \n into new line.
${1} is the first parameter passed to this shell script.
I want to pass a parameter to this script example and it prints the following:
#1. You're smart!
#2. It's a difficult question!
I tried the following:
example "#1. You're smart!\n#2. It's a difficult question!"
An error: -bash: !\n#2.: event not found
Then I tried to escape ! by single quote, and tried:
example '#1. You're smart\!\n#2. It's a difficult question\!'
It outputs:
${1}
Any solution here? Thanks a lot!
$ cat t.sh
#! /bin/bash
echo -e $#
Or echo -e $1, or echo -e ${1} if you just want to process the first argument.
To get bash to stop trying to expand !, use set +H (see In bash, how do I escape an exclamation mark?)
$ set +H
$ ./t.sh "#1. You're smart!\n#2. It's a difficult question!"
#1. You're smart!
#2. It's a difficult question!
What's inside a $'' expression has to be a literal. You can't expand other variables inside it.
But you can do this:
echo "${1//\\n/$'\n'}"
Jan Hudec has an even better answer:
echo -e "$1"

Resources