Can I export variable with another variable inside? - shell

I have a .sh script which uses environment variables I export before. I would like my variables to be like this: VAR1="${libDir}/test" so that in my script, the ${libDir} will be replaced with some value. I declared my export like below: export VAR1="${libDir}/test" but in my script the libDir is not taken into account at all. Can I do it this way?

No, you can't have a variable that contains a variable reference that gets substituted in a "delayed" fashion:
$ libDir=foo
$ VAR1="${libDir}/test"
$ libDir=bar
$ echo "$VAR1"
foo/test
You could get around this using eval, but you shouldn't.
However, a function will do exactly what you want, with the price of a touch extra syntax:
$ var1() {
echo "${libDir}/test"
}
$ libDir=foo
$ echo "$(var1)"
foo/test
$ libDir=bar
$ echo "$(var1)"
bar/test

Related

Assigning a variable in a shell script for use outside of the script

I have a shell script that sets a variable. I can access it inside the script, but I can't outside of it. Is it possible to make the variable global?
Accessing the variable before it's created returns nothing, as expected:
$ echo $mac
$
Creating the script to create the variable:
#!/bin/bash
mac=$(cat \/sys\/class\/net\/eth0\/address)
echo $mac
exit 0
Running the script gives the current mac address, as expected:
$ ./mac.sh
12:34:56:ab:cd:ef
$
Accessing the variable after its created returns nothing, NOT expected:
$ echo $mac
$
Is there a way I can access this variable at the command line and in other scripts?
A child process can't affect the parent process like that.
You have to use the . (dot) command — or, if you like C shell notations, the source command — to read the script (hence . script or source script):
. ./mac.sh
source ./mac.sh
Or you generate the assignment on standard output and use eval $(script) to set the variable:
$ cat mac.sh
#!/bin/bash
echo mac=$(cat /sys/class/net/eth0/address)
$ bash mac.sh
mac=12:34:56:ab:cd:ef
$ eval $(bash mac.sh)
$ echo $mac
12:34:56:ab:cd:ef
$
Note that if you use no slashes in specifying the script for the dot or source command, then the shell searches for the script in the directories listed in $PATH. The script does not have to be executable; readable is sufficient (and being read-only is beneficial in that you can't run the script accidentally).
It's not clear what all the backslashes in the pathname were supposed to do other than confuse; they're unnecessary.
See ssh-agent for precedent in generating a script like that.

Exporting variables with eval not working as expected

I've got a file with variable exports like this:
$ cat file.txt
export A=foo
export B=\"B-\$A\" # I want export another var, which depends on a previously exported var
Using eval to execute those statements does not produce the expected behavior:
$ eval $(cat file.txt)
$ echo ${B:-unset}
unset
When not using export, it works as expected:
$ eval $(echo "A=foo B=\"B-\$A\"")
$ echo ${B:-unset}
B-foo
Why the difference, and is there any way to achieve the same result without removing the export from the variable A (that part of the file comes from an external source outside my control, but I can change the variable B)?
First, change file.txt to this (and consider naming it file.sh instead):
export A=foo
export B="B-$A"
Then, instead of eval $(cat file.txt), do this:
source file.txt
That does the same thing as if you had pasted the content file.txt into your shell.

Double Parameter in shell scripting throwing error

I am trying to make my scripts more generic and hence trying to pass parameter.
I have config file which contains variables (which are used in the scripts) and in the scripts ,I am sourcing (source command) the file in another scripts (ksh).
Config file contains:
p2020_m23_ORACLE_USERNAME=sanjeeb
Parameter for the script is p2020_m23.
ksh script:
export SOURCE_CD=$1
export CONFIG_FILE=/user/spanda20/dbconfig.txt
source $CONFIG_FILE
USERNAME=${${SOURCE_CD}_ORACLE_USERNAME} << **This throws error** >>
USERNAME=$p2020_m23_ORACLE_USERNAME <<< **This gives correct result** >>
manual test:
[spanda2 config]$ export SOURCE_CD=p2020_m23
[spanda2 config]$ export m23_ORACLE_USERNAME=sanjeeb
[spanda2 config]$ export USERNAME=${${SOURCE_CD}_ORACLE_USERNAME}
-bash: USERNAME=${${SOURCE_CD}_ORACLE_USERNAME}: bad substitution
USERNAME_REF="${SOURCE_CD}_ORACLE_USERNAME"
USERNAME="${!USERNAME_REF}"
${parameter} -The value of parameter is substituted
so If you want to append the value of 2 variables and assign in other . You should have written in like this
export SOURCE_CD=p2020_m23
export m23_ORACLE_USERNAME=sanjeeb
export USERNAME="${SOURCE_CD}_${ORACLE_USERNAME}"
In ksh you can use variable indirection with typeset -n or nameref.
Simple example:
$ typeset -n that
$ this=word
$ that=this
$ echo $that
word
$ this=nothing
$ echo $that
nothing
The name reference now makes $that return the current value of $this.

Variables and the CLI?

I want the following:
$ DOMAIN=chron echo snippet-www.$DOMAIN.com-head.html
to output:
snippet.www.chron.com-head.html
but for the life of me, I can't figure out how do this except via the two commands:
$ export DOMAIN=chron
$ echo snippet-www.$DOMAIN.com-head.html
Isn't there a way to get this to work as one command?
I have stumbled upon the answer!!
Just add a semicolon (;) after the variable assignment.
$ DOMAIN=chron; echo snippet-www.$DOMAIN.com-head.html
snippet-www.chron.com-head.html
$ ( export DOMAIN=chron ; echo snippet-www.$DOMAIN.com-head.html )
This makes $DOMAIN an environment variable (which doesn't matter for this example, but might for other similar commands), and it limits its lifetime to the parentheses.
Your answer:
$ DOMAIN=chron; echo snippet-www.$DOMAIN.com-head.html
causes $DOMAIN to be a (non-exported) shell variable, and retains the setting for later commands.
this should work
DOMAIN=chron eval 'echo snippet-www.$DOMAIN.com-head.html'

what is the significance of exporting path in shell script?

I have seen below two lines in a shell script.
Im new to unix scripting, what is the use of setting this?
PATH=$PATH:/bin:/usr/bin:/usr/sbin:/sbin:/etc:/usr/ucb:/usr/ccs/bin:/usr/local/bin
export PATH
Thanks in advance
If you export something (in bash anyway which I assume is your shell), it will mark that something to be available in subsequently executed commands.
$ FOO=1 # Set the variable
$ echo $FOO # Check the value
1
$ bash # New shell here.
$ echo $FOO # No value since it's not exported
$ exit # Quit the subshell
$ export FOO # Export it
$ bash
$ echo $FOO # It has a value now
1
export is a shell builtin for bash so doing a help export will give you more information on it.
Explicitly exporting the PATH doesn't hurt but generally has no effect as the PATH variable is almost certainly already marked as exported when you launch a shell script.

Resources