Create a variable from another variable in shell script - linux

In a shell script I will store the output as a variable like below
Test=$(/home/$USER/import.py $table)
Now this Test variable will have more than 2 lines like below
table= 123_test
min_id=1
max_id=100
123_test,1,100
Now I want to store the last line of the Test variable as another variable called output.
I have tried like below. But not getting the desired result
output=`$test | tail -n 1`
Can we create a variable from another variable in a shell script. If yes, How can we do that?

Use echo to pipe the variable to the other command.
output=$(echo "$test" | tail -1)
or a here-string:
output=$(tail -1 <<<"$test")
Don't forget to quote the variable in both cases, otherwise all the lines will be combined.
Finally, you can use a parameter expansion operator to select the last line, instead of using tail:
output=${test##*$'\n'}

Related

Save String from a file and use variable as an argument linux

I want to assign a variable to be Strings that I read from the file foo.txt. Then, I want to call a java program with that variable as the argument. However, the argument that keeps getting passed to the program is cat foo.txt. How to I get the program to take in the actual arguments?
$ temp='cat foo.txt'
$temp
> encode test 5
$ echo $temp
> cat foo.txt
What you want is command substitution, but you're using single quoutes instead of backticks, effectively making it a string.
Corrected (old-style substitution):
temp=`cat foo.txt`
Better (new-style substitution):
temp=$(cat foo.txt)
Even better:
temp=$(< foo.txt)

Execute command substitutions in input read from a file

In shell script how to make script read commands in input file string
Example 1 (script1.sh):
a="google.analytics.account.id=`read a`"
echo $a
Example 2 (script2.sh):
cat script2.sh
a=`head -1 input.txt`
echo $a
Sample input.txt
google.analytics.account.id=`read a`
If I run script1.sh the read command is working fine, but when I am running script2.sh, the read command is not executed, but is printed as part of the output.
So I want script2.sh to have the same output as script1.sh.
Your input.txt contents are effectively executed as a script here; only do this if you entirely trust those contents to run arbitrary commands on your machine. That said:
#!/usr/bin/env bash
# ^^^^- not /bin/sh; needed for $'' and $(<...) syntax.
# generate a random sigil that's unlikely to exist inside your script.txt
# maybe even sigil="EOF-$(uuidgen)" if you're guaranteed to have it.
sigil="EOF-025CAF93-9479-4EDE-97D9-483A3D5472F3"
# generate a shell script which includes your input file as a heredoc
script="cat <<$sigil"$'\n'"$(<input.txt)"$'\n'"$sigil"
# run that script
eval "$script"
In script1.sh the first line is evaluated, therefore the read a is executed and replaced in the string.
In script 2.sh the first line is evaluated, therefore the resulting string from execution of head is put into the variable a.
There is no re-evaluation done on the resulting string. If you add the evaluation with eval $a and the first line in input.txt is exactly as the first line of script1.sh (actually the a="..." is missing) then you might get the same result. The heredoc, as CharlesDuffy suggested, seems more accurate.

Concat 2 variables and use that variable to get value from property file using shell script

I have a property file with below properties,
apache_ip=127.0.0.1
apache_user=root
Now in my shell script i did something like below,
source $1
service=$2 #$2=apache
variable=${service}_ip
serviceIP=${variable}
echo ${serviceIP}
I want to get the output as 127.0.0.1, but the output was apache_ip
I have tried different combination but it dint work. How to concat two variable and use that variable to get the value from property file.
Are you looking for this? I assume you are using bash.
service="apache"
apache_ip="127.0.0.1"
variable="${service}_ip"
ip="${!variable}"
echo "$ip"
which prints 127.0.0.1.
Look here for more information on shell parameter expansion in bash shell.
If the first character of parameter is an exclamation point (!), and
parameter is not a nameref, it introduces a level of variable
indirection. 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. If parameter is a nameref, this expands to the name of the
variable referenced by parameter instead of performing the complete
indirect expansion.
When you want to get the values from the config file, you can use grep:
configfile=$1
service=$2
serviceIP=$(grep "^${service}_ip=" configfile|cut -d= -f2-)
echo "serviceIP=${serviceIP}"
You can do about the same when the configfile has been sourced:
serviceIP=$(set | grep "^${service}_ip=" |cut -d= -f2-)
echo "serviceIP=${serviceIP}"

linux bash sed-command with variable

I have a variable in a linux bash ".sh" script
$data="test_1"
now I want to create a new variable ($name) that contains only the part of $data before the underscore, so
$name="test"
I thought of doing this with sed
name=$(echo "$dataset" | sed 's/_.*//');
but this doesn't seem to work. What am I doing wrong?
No need to call an external process(sed). Instead you can use shell's parameter substitution like this:
$ data="test_1"
$ echo "${data%%_*}"
test
${var%%Pattern} Remove from $var the longest part of Pattern that matches the back end(from the right) of $var.
${var%Pattern} for removing shortest pattern
More info on parameter substitution can be found here.
You can store it in a variable like this:
$ name="${data%%_*}"
$ echo "$name"
test

Extract all variable values in a shell script

I'm debugging an old shell script; I want to check the values of all the variables used, it's a huge ugly script with approx more than 140 variables used. Is there anyway I can extract the variable names from the script and put them in a convenient pattern like:
#!/bin/sh
if [ ${BLAH} ....
.....
rm -rf ${JUNK}.....
to
echo ${BLAH}
echo ${JUNK}
...
Try running your script as follows:
bash -x ./script.bash
Or enable the setting in the script:
set -x
You can dump all interested variables in one command using:
set | grep -w -e BLAH -e JUNK
To dump all the variables to stdout use:
set
or
env
from inside your script.
You can extract a (sub)list of the variables declared in your script using grep:
grep -Po "([a-z][a-zA-Z0-9_]+)(?==\")" ./script.bash | sort -u
Disclaimer: why "sublist"?
The expression given will match string followed by an egal sign (=) and a double quote ("). So if you don't use syntax such as myvar="my-value" it won't work.
But you got the idea.
grep Options
-P --perl-regexp: Interpret PATTERN as a Perl regular expression (PCRE, see below) (experimental) ;
-o --only-matching: Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line.
Pattern
I'm using a positive lookahead: (?==\") to require an egal sign followed by a double quote.
In bash, but not sh, compgen -v will list the names of all variables assigned (compare this to set, which has a great deal of output other than variable names, and thus needs to be parsed).
Thus, if you change the top of the script to #!/bin/bash, you will be able to use compgen -v to generate that list.
That said, the person who advised you use set -x did well. Consider this extension on that:
PS4=':$BASH_SOURCE:$LINENO+'; set -x
This will print the source file and line number before every command (or variable assignment) which is executed, so you will have a log not only of which variables are set, but just where in the source each one was assigned. This makes tracking down where each variable is set far easier.

Resources