UNIX : Storing awk output to variable not working [duplicate] - bash

This question already has answers here:
Bash assign output to variable inside here document
(2 answers)
Quotes within HERE document in shell scripts
(1 answer)
How to pass local variable to remote using ssh and bash script?
(3 answers)
Closed 2 years ago.
I know there are too many question regarding saving awk output to variable available on stack overflow, but I've tried all the possible answers but non seems to be working. Please help me with the following piece of code.
I've attemped the following types of solutions, but all of them give me blank output when echo.
Case 1:
sshpass -p$password ssh -T -o StrictHostKeyChecking=no $hostname <<EOF
tomcat=`ps -ef | grep -i tomcat | grep -i bootstrap | awk '{print \$2}' `
httpd=`systemctl status httpd | awk 'NR==3 {print \$2}'`
echo $tomcat
echo $httpd
EOF
Case 2:
sshpass -p$password ssh -T -o StrictHostKeyChecking=no $hostname <<EOF
tomcat=$(ps -ef | grep -i tomcat | grep -i bootstrap | awk '{print \$2}')
httpd=$(systemctl status httpd | awk 'NR==3 {print \$2}')
echo $tomcat
echo $httpd
EOF
Case 3:
sshpass -p$password ssh -T -o StrictHostKeyChecking=no $hostname <<EOF
tomcat=`ps -ef | grep -i tomcat | grep -i bootstrap | awk '{print $2}' `
httpd=`systemctl status httpd | awk 'NR==3 {print $2}'`
echo $tomcat
echo $httpd
EOF
Case 4:
sshpass -p$password ssh -T -o StrictHostKeyChecking=no $hostname <<EOF
tomcat=$(ps -ef | grep -i tomcat | grep -i bootstrap | awk '{print $2}')
httpd=$(systemctl status httpd | awk 'NR==3 {print $2}')
echo $tomcat
echo $httpd
EOF
Please help me out.
Thanks,
Sid

Related

How do i redirect a list of IP addresses to a command line function?

I want to see what countries are trying to access my VPS. I have installed a tool called "goiplookup", which was forked from another effort called "geoiplookup". If I type this at the command line:
goiplookup 8.8.8.8
It returns this:
US, United States
So I figured out how to get a list of IPs that are trying to access my server by using this:
sudo grep "disconnect" /var/log/auth.log | grep -v COMMAND | awk '{print $9}'
Which gives a long list of IPs like this:
1.1.1.1
2.2.2.2
3.3.3.3
I cannot figure out how to get this list of IPs to be processed by the "goiplookup" tool. I tried this:
sudo grep "disconnect" /var/log/auth.log | grep -v COMMAND | awk '{print $9}' | goiplookup
but that did not work. I also tried with no luck:
sudo grep "disconnect" /var/log/auth.log | grep -v COMMAND | awk '{print $9}' | xargs -0 goiplookup
Try this:
sudo grep "disconnect" /var/log/auth.log | grep -v COMMAND | awk '{print $9}' | sort | uniq | xargs -n 1 goiplookup
I added | sort | uniq to ensure each IP only appears once
and xargs -n 1 so that each found IP is processes by goiplookup
I would put it into a file and make a small utility to parse it:
sudo grep "disconnect" /var/log/auth.log | grep -v COMMAND | awk '{print $9}' | sort -u > ./file.txt
cat ./file.txt | while read -r line; do
temp$(echo $line)
goiplookup $temp
done
This will read through the file one line at a time and execute the goiplookup with each IP.
sudo grep disconnect /var/log/auth.log | awk '!/COMMAND/ && !seen[$0]++ {system("geoiplookup \""$9"\""}
Note that geoiplookup only allows one IP per invocation.
The whole thing can be done in awk, but using grep allows the rest to be run unprivileged.
Consider whether grep -w (match whole word) is appropriate, and in awk you can do a similar thing with !/(^|[^[:alnum:]_])COMMAND($|[^[:alnum:]_])/.
I just made a shell script, which works.
#!/bin/bash
readarray -t array < <(sudo grep "disconnect" /var/log/auth.log | grep -v COMMAND | awk '{print $9}' | sort | uniq)
for ip in "${array[#]}"
do
:
country=$(/usr/local/bin/goiplookup -c $ip)
echo "$ip $country"
done

ssh remote command execution quoting and piping awk

I'm working on a script, that should find certain disks and add hostname to them.
I'm using this for 40 servers with a for loop in bash
#!/bin/bash
for i in myservers{1..40}
do ssh user#$i findmnt -o SIZE,TARGET -n -l |
grep '1.8T\|1.6T\|1.7T' |
sed 's/^[ \t]*//' |
cut -d ' ' -f 2 |
awk -v HOSTNAME=$HOSTNAME '{print HOSTNAME ":" $0}'; done |
tee sorted.log
can you help out with the quoting here? It looks like awk gets piped (hostname) from localhost, not the remote server.
Everything after the first pipe is running locally, not on the remote server.
Try quoting the entire pipeline to have it run on the remote server:
#!/bin/bash
for i in myservers{1..40}
do ssh user#$i "findmnt -o SIZE,TARGET -n -l |
sed 's/^[ \t]*//' |
cut -d ' ' -f 2 |
awk -v HOSTNAME=\$HOSTNAME '{print HOSTNAME \":\" \$0}'" ;
done | tee sorted.log
This is a shorter version of your stuff:
findmnt -o SIZE,TARGET -n -l |
awk -v HOSTNAME=$HOSTNAME '/M/{print HOSTNAME ":" $2}'
Applied to the above:
for i in myservers{1..40}
do ssh user#$i bash -c '
findmnt -o SIZE,TARGET -n -l |
awk -v HOSTNAME=$HOSTNAME '"'"'/M/{print HOSTNAME ":" $2}'"'"' '
done |
tee sorted.log
see: How to escape the single quote character in an ssh / remote bash command?

Ubuntu grep option error while executing a batch script

#!/bin/bash
vm1_MAC=`virsh -c qemu:///system domiflist instance-00000009 -e | grep virbr0 | awk '{print $5}'`
vm2_MAC=`virsh -c qemu:///system domiflist instance-0000000d -e | grep -i virbr0 | awk -e '{print $5}'`
vm1_IP=`arp -e | grep $vm1_MAC | awk '{print $1}'`
vm2_IP=`arp -e | grep $vm2_MAC | awk '{print $1}'`
echo "VM1 IP Address: $vm1_IP"
echo "VM2 IP Address: $vm2_IP"
The shell script was meant to display the IP addresses of my two openstack instances but I am receiving grep command option error:
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
VM1 IP Address:
VM2 IP Address:
Is there anyone here who can assist me as I am not a bash script expert, just need to do this to get some tasks done. Thank you
This message typically happens when you try to grep for a string which starts with a dash.
The immediate workaround is to use grep -e "$variable" but really, you want to avoid the useless use of grep here.
#!/bin/bash
vm1_MAC=$(virsh -c qemu:///system domiflist instance-00000009 -e | awk "/virbr0/"'{print $5}')
vm2_MAC=$(virsh -c qemu:///system domiflist instance-0000000d -e | awk -e 'tolower($0) ~ /vibr0/ {print $5}')
vm1_IP=$(arp -e | awk -v mac="$vm1_MAC" '$0 ~ mac {print $1}')
vm2_IP=$(arp -e | awk -v mac="$vm2_MAC" '$0 ~ mac {print $1}')
Incidentally, this also demonstrates three different ways to pass a regex to Awk. Notice as well how we prefer the modern $(command) substitution over the dinosaur `backtick` syntax.

bash script to kill process on remote machines

I want to kill process on remote machines via ssh but its not working
VAR=$(ssh ${HOSTS} ps -ef | grep $SERVICE | grep -v grep | awk '{print $2}' | xargs kill -9)
ssh ${HOSTS} ps ef < /dev/null > /dev/null 2> /dev/null
The problem is that your pipe process get execute on your local host rather than on the server.
A solution is to quote protect the command:
VAR=$(ssh ${HOSTS} "ps -ef | grep $SERVICE | grep -v grep | awk '{print \$2}' | xargs kill -9")
ssh ${HOSTS} "ps ef" < /dev/null > /dev/null 2> /dev/null
Below command worked well for me to kill processes on remove server.
I'm able to kill tail command running on remote server.
ssh -tty ${Host}" ps -efwww | grep tail |grep -v grep |cut -c 10-15|xargs kill -9 "

Using awk inside ssh from ruby

When running the command:
puts `ssh -o StrictHostKeyChecking=no -i keyfile user#host "sudo cat file | awk '/^server/ {print \$2}' | sort -u"`
After running this command, its only counts the ^server, but it ignores the print $2 command.
i get the whole line instead of just the 2nd word.
You're running through a couple of shell processing layers, so you need an additional backslash:
puts `ssh -o StrictHostKeyChecking=no -i keyfile user#host "sudo cat file | awk '/^server/ {print \\$2}' | sort -u"`
What happens if you change this:
sudo cat file | awk '/^server/ {print \$2}' | sort -u
to this:
sudo cat file | grep '/^server' | awk '{ print \$2 }' | sort -u
If still not working, try not escaping the $ - try $2 instead of \$2
Might be more maintainable to split it up into pieces. Also using ruby's single quoting mechanism works to send the command as you intend.
cmd = %q(sudo cat file | awk '/^server/ {print $2}' | sort -u)
puts %x(ssh -o StrictHostKeyChecking=no -i keyfile user#host #{cmd})

Resources