I have a table which contains an env variable and I need to fetch the variable's value and export for another java utility from within the shell script:
command="SELECT param_value FROM tableX WHERE param_name='ABCD';"
#This param_value is ${PATHX} and PATHX is /home/users/pathx
PARAM_VALUE=`sqlplus -s $CONN_STRING <<- END
SET head off;
set feedback off;
${command}
exit;
END`
echo ${PARAM_VALUE} | grep -q "ERROR"
if [ $? -eq 0 ]
then
echo "Failed in fetching param_value "
exit 1
else
#Trimming the value fetched from DB
PARAM_VALUE=`echo "${PARAM_VALUE}" | tr -d " " | tr -d "\n"`
echo "Value fetched from DB=${PARAM_VALUE}"
#This prints ${PATHX}
export PATH_VALUE="${PARAM_VALUE}"
#This is exporting PATH_VALUE as ${PATHX} instead of /home/users/pathx - WHICH IS WHERE I NEED HELP
#If I put directly export PATH_VALUE="${PATHX}", it exports the value correctly as /home/users/pathx
fi
After searching for options, I have tried various options like below but failed:
export PATH_VALUE="${PARAM_VALUE}"
export PATH_VALUE=`eval echo "\$${PARAM_VALUE}"`
export PATH_VALUE=$(eval \$$PARAM_VALUE)
export PATH_VALUE=${$PARAM_VALUE}
export PATH_VALUE=${!PARAM_VALUE}
export PATH_VALUE=`echo ${PARAM_VALUE}`
export PATH_VALUE=`expr ${PARAM_VALUE}`
Please suggest what can be done in this case to export the actual expanded value - /home/users/pathx.
For it to work the way you expect, the sqlplus query response should be PATHX instead of ${PATHX}. One way to fix it is to replace
PARAM_VALUE=`echo "${PARAM_VALUE}" | tr -d " " | tr -d "\n"`
with
PARAM_VALUE=`echo "${PARAM_VALUE}" | tr -dc '[:alnum:]\n\r'`
yes the query response is ${PATHX} and this is an environment variable which I need to expand.
You could use eval, but eval is evil, if the value is exported, do a safe envsubst:
PARAM_VALUE=$(envsubst <<<"$PARAM_VALUE")
Related
Is it possible to store the script as a variable? This is the script:
### SCRIPT1 ###
if [ "$4" = "test-1" ] ; then
existing_user1=$(ldapsearch -x -b "cn=users,cn=servers,ou=servers,dc=com" -H ldap://127.0.0.1 -D "cn=admin,dc=servers,dc=com" -w "pass" cn uid | grep "uid: $3" | grep -oE '[^ ]+$')
if [ "$existing_user1" = "$3" ] ; then
exit -1
elif [ "$existing_user1" = "" ] ; then
gid=523 ; cn="cn=users,cn=servers"
fi
elif [ "$4" = "servers2" ] ; then
existing_user2=$(ldapsearch -x -b "cn=users,cn=servers,ou=servers,dc=servers,dc=com" -H ldap://127.0.0.1 -D "cn=admin,dc=servers,dc=com" -w "pass" cn uid | grep "uid: $3" | grep -oE '[^ ]+$')
if [ "$existing_user2" = "$3" ] ; then
(echo "dn: cn=servers,ou=servers,dc=servers,dc=com"
echo "add: memberUid"
echo "memberUid: $3") | ldapmodify -D "cn=admin,dc=servers,dc=com" -w "pass"
exit -1
elif [ "$existing_user2" = "" ] ; then
gid=523 ; cn="cn=users,cn=servers"
(echo "dn: cn=servers,ou=servers,dc=servers,dc=com"
echo "add: memberUid"
echo "memberUid: $3") | ldapmodify -D "cn=admin,dc=servers,dc=com" -w "pass"
fi
fi
)
I tried like this:
my_new_variable=(
here I pasted the script from above
)
But, looks like it is not working properly... I changed brackets with quotation mark, but that that did not work either.
So far I did have some simple stuff as variable value, but nothing complicated like another bash script.
I would like to have the above script set as the variable that I can later in the script inside awk.
You can use a here-document:
script=$(cat <<"EOF"
### SCRIPT 1 ###
# commands
# last line
EOF
)
Everything on the lines in between "EOF" and EOF are passed literally, as cat's standard input. This is nested inside a command substitution, to put it in a variable. The final EOF string must be on it's own line, so the closing ) must go on the next line. Note that any trailing new lines will be stripped, because it's a command substitution.
"EOF" can be any quoted word. If quotes are not used, variables, arithmetic and command subs are expanded.
This syntax is portable to sh, and not bash specific.
You should first save it as a file, and then store it into some variable.
e.g.
var=$(cat script.sh)
I tried following the steps here to configure the prompt: https://nixos.wiki/wiki/Fish
Combined with the information here about the location and content of a basic file: https://fishshell.com/docs/current/faq.html#how-do-i-set-my-prompt
If I understood correctly the content of fish_prompt.fish should be:
set -l nix_shell_info (
if test -n "$IN_NIX_SHELL"
echo -n "<nix-shell> "
end
)
function fish_prompt
set_color $fish_color_cwd
echo -n (prompt_pwd)
set_color normal
echo -n -s ' $nix_shell_info ~>'
end
After setting it this way the prompt is the same whether in a nix-shell or not and the variable $nix_shell_info does not get set.
How can I set it so that it works as intended?
You need to set the variable inside the function, otherwise it would always contain the value set when the file was loaded:
function fish_prompt
set -l nix_shell_info (
if test -n "$IN_NIX_SHELL"
echo -n "<nix-shell> "
end
)
set_color $fish_color_cwd
echo -n (prompt_pwd)
set_color normal
echo -n -s " $nix_shell_info ~>"
end
Edit: As cole-h pointed out on IRC, you also need to also change the single quotes containing the variable to double quotes or it will not be interpolated.
I have written a shell script that will connect with database and retrieve the records. But when I exceute it, it gives me the error as: Unexpected keyword from. Can anyone please suggest me what mistake I am doing?
The code I have done is as given below:
#------------------------------------------------------------------------------------------------
# Define Script and Log Location
# ------------------------------------------------------------------------------------------------
SCRIPTHOME=/opt/psoft/scripts
SCRIPTINPUT=/opt/psoft/scripts/tac/input
SCRIPTLOG=/opt/psoft/scripts/tac/log
SCRIPTOUTPUT=/opt/psoft/scripts/tac/output
SCRIPTNOTPROCESSED=/opt/psoft/scripts/tac/notprocessed
# ------------------------------------------------------------------------------------------------
# Define Oracle Environment
# ------------------------------------------------------------------------------------------------
export ORACLE_HOME=/opt/oracle/product/9.2.0
export TNS_ADMIN=/var/opt/oracle/admin/network
export PATH=$PATH:$ORACLE_HOME/bin:$HOME/scripts:.
# ------------------------------------------------------------------------------------------------
# Main Program
# ------------------------------------------------------------------------------------------------
incno=$1;
if test ${#incno} -lt 6
then
echo "Please provide 6 digit incident no";
echo "TAC script has not been run";
exit;
fi;
cd ${SCRIPTINPUT}
if test -e *.csv
then
#cd ${SCRIPTINPUT}
for f in *.csv
do
dos2unix $f $f # To remove control M characters in the input file
echo " $f - Control M characters removed sucessfully " >> input.log
done
echo " Control M characters present in all files in input folder has been removed " >>input.log
cd ${SCRIPTINPUT}
for INP in *.csv
do
log_file="${SCRIPTLOG}/${INP}.log"
# To check if input file for Taccode or Not
cd ${SCRIPTINPUT}
echo "Taccode to be executed for the file $INP"
count=0;
while read line
do
pcode=`echo $line | cut -d "," -f "1"`
tcode=`echo $line | cut -d "," -f "2"`
cpcode=${#pcode}
ctcode=${#tcode}
#cpcode=`echo ${pcode} | grep -oE [[:digit:]] | wc -l`
#ctcode=`echo ${tcode} | grep -oE [[:digit:]] | wc -l`
if test $cpcode -eq 5
then
DBRESULT=`sqlplus sprint2/sh3rl0ck#SPRXP03
select * from mytable where productcode='10130' AND taccode='35710100';
quit;`
echo "Hello $count:$pcode:$tcode:$DBRESULT"
#here the database result should be checked for errors
if test $? -ne 0
then
echo "Query execution failed.Check ${log_file} file for errors!"
mv ${SCRIPTINPUT}/$INP ${SCRIPTNOTPROCESSED}
exit;
else
count=$(expr $count + 1)
echo "Record No:${count} ${pcode}:${tcode}" >>${log_file}
fi;
else
echo "Problem with product code or tac code. Check log file for errors"
echo "Record No:${count} ${pcode}:${tcode}:" >>${log_file}
mv ${SCRIPTINPUT}/$INP ${SCRIPTNOTPROCESSED}
exit;
fi;
done <${INP} #end file reading while loop
echo "Script excution succeeded" >>${log_file}
echo "${count} records inserted"
echo "Script excution succeeded";
done #end outer for loop
else
echo "No csv files found in input directory. -TAC script has not been run."
fi;
I think you'll need to put your sqlplus command all on one line
DBRESULT=`sqlplus sprint2/sh3rl0ck#SPRXP03 select * from mytable where productcode='10130' AND taccode='35710100'; quit;`
or include explicit line breaks
DBRESULT=`sqlplus sprint2/sh3rl0ck#SPRXP03 \
select * from mytable where productcode='10130' AND taccode='35710100'; \
quit;`
Oracle sqlplus doesn't support inline sql statement. The only commandline support it has is to run a sql script using #. The viable solution to your problem is to use heredoc.
You can do something like:
DBRESULT=$(sqlplus sprint2/sh3rl0ck#SPRXP03 <<-SQL
select * from mytable where productcode='10130' AND taccode='35710100';
exit;
SQL
)
I want to use the variables of ssh in shell script.
suppose I have some variable a whose value I got inside the ssh and now I want to use that variable outside the ssh in the shell itself, how can I do this ?
ssh my_pc2 <<EOF
<.. do some operations ..>
a=$(ls -lrt | wc -l)
echo \$a
EOF
echo $a
In the above example first echo print 10 inside ssh prints 10 but second echo $a prints nothing.
I would refine the last answer by defining some special syntax for passing the required settings back, e.g. "#SET var=value"
We could put the commands (that we want to run within the ssh session) in a cmdFile file like this:
a=`id`
b=`pwd`
echo "#SET a='$a'"
echo "#SET b='$b'"
And the main script would look like this:
#!/bin/bash
# SSH, run the remote commands, and filter anything they passed back to us
ssh user#host <cmdFile | grep "^#SET " | sed 's/#SET //' >vars.$$
# Source the variable settings that were passed back
. vars.$$
rm -f vars.$$
# Now we have the variables set
echo "a = $a"
echo "b = $b"
If you're doing this for lots of variables, you can add a function to cmdFile, to simplify/encapsulate your special syntax for passing data back:
passvar()
{
var=$1
val=$2
val=${val:-${!var}}
echo "#SET ${var}='${val}'"
}
a=`id`
passvar a
b=`pwd`
passvar b
You might need to play with quotes when the values include whitespace.
A script like this could be used to store all the output from SSH into a variable:
#!/bin/bash
VAR=$(ssh user#host << _EOF
id
_EOF)
echo "VAR=$VAR"
it produces the output:
VAR=uid=1000(user) gid=1000(user) groups=1000(user),4(adm),10(wheel)
I've been trying several fails to perform the following:
Basically, what I need is to execute several sequenced commands on a remote unix shell, such as setting environment variables with variables that I have on the script, move to a particular directory and run a script there and so on.
I've tried using a printf with the portion of the script and then piped the ssh command, but it didn't work quite well, also, I've read about the "ssh ... >> END" marker, which is great but since I'm using functions, it doesn't work well.
Do you have any thoughts?
Here's an excerpt of the code:
deployApp() {
inputLine=$1;
APP_SPECIFIC_DEPLOY_SCRIPT="$(echo $inputLine | cut -d ' ' -s -f1)";
BRANCH="$(echo $inputLine | cut -d ' ' -s -f2)";
JBOSS_HOME="$(echo $inputLine | cut -d ' ' -s -f3)";
BASE_PORT="$(echo $inputLine | cut -d ' ' -s -f4)";
JAVA_HOME_FOR_JBOSS="$(echo $inputLine | cut -d ' ' -s -f5)";
JAVA_HEAP="$(echo $inputLine | cut -d ' ' -s -f6)";
echo "DEPLOYING $APP_SPECIFIC_DEPLOY_SCRIPT"
echo "FROM BRANCH $BRANCH"
echo "IN JBOSS $JBOSS_HOME"
echo "WITH BASE PORT $BASE_PORT"
echo "USING $JAVA_HOME_FOR_JBOSS"
if [[ -n "$JAVA_HEAP" ]]; then
echo "WITH $JAVA_HEAP"
fi
echo
echo "Exporting jboss to $JBOSS_HOME"
ssh me#$SERVER <<END
cleanup() {
rm -f $JBOSS_SERVER/log/*.log
rm -Rf $JBOSS_SERVER/deploy/
rm -Rf $JBOSS_SERVER/tmp/
mkdir $JBOSS_SERVER/deploy
}
startJboss() {
cd $JBOSS_SERVER/bin
./jbossctl.sh start
return 0;
}
export JBOSS_HOME
export JBOSS_SERVER=$JBOSS_HOME/server/default
END
return 0;
}
With that "HERE" approach, I'm getting this error: "syntax error: unexpected end of file"
Thanks a lot in advance!
Just put the functions in your here document, too:
var="Hello World"
ssh user#host <<END
x() {
print "x function with args=$*"
}
x "$var"
END
[EDIT] Some comments:
You say "export JBOSS_HOME" but you never define a value for the variable in the here document. You should use export JBOSS_HOME="$JBOSS_HOME". BASH will take all text between the two END, replace all variables, and send the result to SSH for processing.
That also means the other side will see rm -f /path/to/jboss/server/*.log; the assignment to JBOSS_SERVER in the last line of the here document has no effect (at least not to the code in cleanup()).
If you want to pass $ unmodified to the remote server, you have to escape it with \: rm -f \$JBOSS_SERVER/log/*.log
You never call cleanup()
There is a } missing after return 0 to finish the definition of deployapp()
There may be other problems as well. Run the script with bash -x to see what the shell actually executes. You can also add echo commands in the here document to see what the values of the variables are or you can add set -x before cleanup() to get the same output as with bash -x but from the remote side.
I don't understand why you're using cut to split the arguments to your function. Just do
APP_SPECIFIC_DEPLOY_SCRIPT=$1
BRANCH=$2
JBOSS_HOME=$3
# etc.
If you don't quote your here document delimiter, the contents are expanded before they're sent to the server. That may be what you want. If you don't and you want all expansion to be done on the server side, then quote it like this:
ssh me#$SERVER <<'END'
# etc.
END
If you wan't a mixture, don't quote the delimiter, but do escape those things that you want delayed expansion for:
ssh me#$SERVER <<END
echo $EXPAND_ME_NOW \$EXPAND_ME_LATER
END
What are the export statements supposed to do? I can't see that they would have any effect at all.