BASH IF statement false negative - bash

I am having some problems comparing a variable from a script to the IP address of the system. I have a source file for an app which is not bash fiendly but it has a value set like so
DKUS_MASTER=127.0.0.1
I am fetching that variable in my bash file by doing
DKUSMASTER=`grep "DKUS_MASTER" /root/somestuff.conf | sed 's/DKUS_MASTER=//'`
Here is what i am then doing in my script as i am trying to see if eth0 ip is set to the DKUS_MASTER parameter i am fetching
DKUSMASTER=`grep "DKUS_MASTER" /root/somestuff.conf| sed 's/DKUS_MASTER=//'`
ETH0=$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
if [ "$ETH0" = "$DKUSMASTER" ]; then
DKUS_STATUS="Master"
else
DKUS_STATUS="Slave"
fi
doing some testing, i can see the variables look correct
echo $DKUSMASTER
echo $ETH0
however, the end status is else false and never true as seen here. In my case the variable $DKUSMASTER does indeed equal to $ETH0, so the status should come back as master.
echo $DKUS_STATUS

Related

How to save to the var, only one from the output

Im writing a script that executes dig command on 2 domains, and after next cmd is host on output.
And always i will get for exmaple:
findUserServer=for r in $(dig +short $login.example.COM && dig +short $login.example.ORG); do host $r|awk '{print $NF}';done | awk -F "." '{print $1}';
1 output: >> asdf02 example
asdf02 - its a server name, its always same name starts "asdf".
Question: Have you any idea how to save to the variable only asdf02?
question+: asdf02 woudln't be always first, could be example asdf02
Should i do maybe a sed which looks on 4 first characters? If it's "asdf", then: [...]
Try not to pipe awk commands into each other and so:
for r in $(dig +short $login.example.COM && dig +short $login.example.ORG); do host $r;done | awk -F [.\ ] '/asdf02/ { print $10 }'
We use both a space and . as delimiters and then pattern match the output for the occurance of asdf02. If we find is, we print the address.
Run that through shellcheck.net ...
Try this.
findUserServer="$( for end in COM ORG; do
host $( dig +short $login.example.$end );
done | sed -n '/ asdf/{ s/^.* //; s/[.].*//; p; }' )"
This will run 2 digs and pipe the collective output through sed,
which will ignore lines that don't have asdf, and strip the matches clean for you.
Let me know if I missed details, because I don't have those exact values available.

Wrong search result in a file through Bash script

I am searching an event field in a file but is giving wrong output. I am searching gpio-keys event in input devices for which I have written a script, but I'm unable to print anything in output file (in my case I am writing in a button device file it is null always). Please help me to figure out this. Where am I doing wrong in script file?
Bash script:
#!/bin/bash
if grep -q "gpio-keys" /proc/bus/input/devices ; then
EVENT=$(cat /proc/bus/input/devices | grep "Handlers=kbd")
foo= `echo $EVENT | awk '{for(i=1;i<=NF;i++) if($i=="evbug")printf($(i-1))}'`
#foo=${EVENT:(-7)}
echo -n $foo > /home/ubuntu/Setups/buttonDevice
fi
i am still not able to get anything in buttondevce
That's no wonder, since in the input line
H: Handlers=kbd event0
there's nowhere the evbug your awk script is looking for.
I my case it is event0 but it may vary also depends on how kernel allows.
If it is event0 or similar, then it's nonsensical to look for evbug. Change the statement
if($i=="evbug")printf($(i-1))
to
if ($i~"event") print $i
(using regular expression match).
I have rewritten my script like above. but through it, I have got two events(event0, event3) but … my input devices are many but i want the gpio-keys event
Aha - in order to take only the handler line from the gpio-keys section, you can use sed with an address range:
EVENT=`sed -n '/gpio-keys/,/Handlers=kbd/s/.*Handlers=kbd //p' </proc/bus/input/devices`
Prakash, I don't have access to your google drive. But I just want to give you some suggestion:-
foo= `echo $EVENT | awk '{for(i=1;i<=NF;i++) if($i=="evbug")printf($(i-1))}'`
This is old style now. Better use like below:-
foo=$(echo $EVENT | awk '{for(i=1;i<=NF;i++) if($i=="evbug")printf($(i-1))}')
Also always use double quotes "" when echoing a variable. See below:-
echo -n "$foo" > /home/ubuntu/Setups/buttonDevice
Try with the below code it will work for you
#!/bin/bash
if grep "gpio-keys" /proc/bus/input/devices >/dev/null ; then
cat /proc/bus/input/devices | grep "Handlers=kbd" | awk '{for(i=1;i<=NF;i++){ if($i ~ /eve/){printf "%s \n", $i} } }') > /home/ubuntu/Setups/buttonDevice
fi
The output in buttonDevice would be
event0
event1
.
.
.
.
event100

Bash Replace Variable IP Address with Network

I have an IP address set in a variable that I'd like to convert into a network address.
This only works for a single digit:
echo '192.168.1.2' | sed 's/.$/0/' => 192.168.1.0
echo '192.168.1.22' | sed 's/.$/0/' => 192.168.1.20
echo '192.168.1.223' | sed 's/.$/0/' => 192.168.1.220
I need a method to return the same network value if the last digit(s) change, i.e:
myip="192.168.1.2" => "192.168.1.0"
myip="192.168.1.22" => "192.168.1.0"
myip="192.168.1.223" => "192.168.1.0"
How can I replace any IP address with it's network address like above?
Pure bash solution without external commands:
echo "${myip%.*}.0"
for example:
$ echo "$myip"
192.168.1.22
$ echo "${myip%.*}.0"
192.168.1.0
Using sed
echo '192.168.1.2' | sed 's/\.[^.]*$/.0/'
sed 's/\.[^.]*$/.0/' <<< 192.168.1.22 # echo + pipe is not needed here
Logic: Replace everything from last . till end with .0
Using awk
awk -F. '{$NF=0}1' OFS=. <<< 192.168.1.22
awk '{$NF=0}1' FS=. OFS=. <<< 192.168.1.22
Logic: Split string with . and set last field to 0.
pure bash:
{ IFS=. read a b c _; echo $a.$b.$c.0; } <<< 192.168.1.22
( IFS=.; read -a ip; ip[3]=0; echo "${ip[*]}"; ) <<< 192.168.1.22
Logic: Read 4 parts of the IP address in 4 variables. Print first 3 and a 0.
Or by using a bash array, if you don't want to clutter environment with too many variables.
You can do this with awk using:
pax> awk -F. '{print $1"."$2"."$3".0"}' <<<12.34.56.78
12.34.56.0
With sed, it's possible to just replace all the digits at the end:
pax sed 's/[0-9]*$/0/' <<<12.34.56.78
12.34.56.0
However, all of those result in an extra process being started up, not something you need to worry about for a few IP addresses but it will make a difference if you're converting many of them.
To do it within bash only (not requiring another process), you can use:
pax> ip=12.34.56.78
pax> echo ${ip%.[0-9]*}.0
12.34.56.0
It is very simple to do with pure bash:
myip="192.168.1.2 "; echo "$myip ==> ${myip%.*}.0"
myip="192.168.1.22 "; echo "$myip ==> ${myip%.*}.0"
myip="192.168.1.223"; echo "$myip ==> ${myip%.*}.0"
Results in:
192.168.1.2 ==> 192.168.1.0
192.168.1.22 ==> 192.168.1.0
192.168.1.223 ==> 192.168.1.0
However, that is assuming the network has a CDIR of 24 (192.168.1.2/24).
If that is not what you will always use, this idea will break.

Retrieve oracle sid from oratab file

I'm creating this ksh shell script to compare Oracle homes from two database name which user inputs.
I tried using cat and also sed from various threads but somehow not able to put oracle home value into variable to compare them.
Oratab:
db1:/oracle/app/oracle/product/11.2.0.3:Y
db2:/oracle/app/oracle/product/11.2.0.3:N
#db3:/oracle/app/oracle/product/11.2.0.4:Y
Runtime:
./compare_db db1 db2
#!/bin/ksh
sid1=$1;
sid2=$2;
file=/etc/oratab
function compare {
home1= sed -n "s#${sid1}.*/\(.*\)${sid1}.*#\1#p" $file
home2= sed -n "s#${sid2}.*/\(.*\)${sid2}.*#\1#p" $file
if $home1 = $home2; then
echo "Success"
else
echo "Failure"
fi
}
Output: (I don't want to include last part "N/Y" after the : (colon))
home1 = /oracle/app/oracle/product/11.2.0.3
home2 = /oracle/app/oracle/product/11.2.0.3
db1 = db2
success
Obviously above is not working and only test code, does somebody comment and what's missing or how it can be done in elegant way?
Thanks,
awk works:
awk -F: "/^${mysid}/{printf \"%s\n\",\$2}" /etc/oratab
You can do it elegantly with this combination of programs :
home1=$(grep $sid1 $file | cut -d":" -f2) --> output /oracle/app/oracle/product/11.2.0.3
home2=$(grep $sid2 $file | cut -d":" -f2) --> output /oracle/app/oracle/product/11.2.0.3
grep --> finds the line in which the specified SID is
cut --> cuts the second field (specified by -f2), fields are delimited with the specified character -d":"

Making code generic

I have one script /location/centers_password.sh in which I have below lines of code :
if [ "$DC" = "sl" ]
then
arg1=`echo -n $Center|wc -m`
if [ $arg1 -gt 3 ]
then
grep "^$Center" /location/.CenterPassword.file.sdi.sl
grep "^$Center" /location/.CenterPassword_xel.file.sdi.sl
else
grep "^$Center" /location/.CenterPassword.file.sl
grep "^$Center" /location/.CenterPassword_xel.file.sl
grep "^$Center" /location/.sftpPasswod.file.sl
fi
elif [ "$DC" = "ch" ]
then
arg1=`echo -n $Center|wc -m`
if [ $arg1 -gt 3 ]
then
grep "^$Center" /location/.CenterPassword.file.sdi.ch
grep "^$Center" /location/.CenterPassword_xel.file.sdi.ch
else
grep "^$Center" /location/.CenterPassword.file.ch
grep "^$Center" /location/.CenterPassword_xel.file.ch
grep "^$Center" /location/.sftpPasswod.file.ch
fi
What I am doing here is, when I execute this code it reads the datacenter name .CenterPassword.file.sdi.ch file. If I explain more, suppose the datacenter starts from 'sl' it reads .CenterPassword.file.sdi.sl file and fetch the password and suppose datacenter starts from 'ch' it reads .CenterPassword.file.sdi.ch and fetch the password.
My requirement is to make this code generic. This file should read the hostname and if the hostname's initial two letter match with .CenterPassword.file.sdi.ch file last two letters (in this example, should match with 'ch') it should fetch the password. Please help to do this.
Problem 1: get the first two letters of the hostname:
DC=`hostname | cut -b1,2`
Problem 2: Use that to read the right filenames:
You could just use your long list of if/else statements (how many datacenters can there be?), but as shell lets you build a filename on the fly, there's no need.
grep "^Center" /location/.CenterPassword.file.sdi.$DC
The $DC will add the proper two-letter suffix to the filename.

Resources