How to use ssh -t command which includes grep with quotes - linux

I am trying to grep the third octet in IP address to an tap device on remote machine.
ssh -t user#host "/sbin/ifconfig tap0 | grep "inet" | /usr/bin/awk -F'[: ]+' '{ print $4 }' | awk -F'[.]' '{print $3}'"
I am resulting this:
inet addr:10.22.66.77 Bcast:10.22.66.255 Mask:255.255.255.0
When i run the command on the remote machine it shows 66
How to make it working with ssh -t?

Sometimes using perl is simpler:
ssh -t user#host "/sbin/ifconfig tap0" | perl -n -e 'if (/inet\saddr:\d+\.\d+\.(\d+)/) { print "$1\n"}'
it runs regular expression pattern on the local machine match on the third octet following addr: and this is then printed via $1
The pattern match is run on the local machine to avoid problems with escaping " (In your example code the " in the grep inet seems to terminate the ssh...)

Related

Multiple ssh in a Single command

I need to pipe multiple ssh commands in order to run commands on a remote machine.
The commands are working fine with a single ssh but not after piping ssh.
E.g
ssh abc#remotemachine1.com "a=hello ; echo \$a"
return hello
but
ssh abc#remotemachine1.com ssh abc#remotemachine2.com"a=hello ; echo \$a"
produces no output.
Similarly:
ssh abc#remotemachine1.com "mountedDir=\$(df \tmp | grep -vi filesystem | rev | cut -d ' ' -f 1); mount | grep -w \$mountedDir"
Is working fine producing the following output :
/dev/sda2 on / type xfs (rw,relatime,attr2,inode64,noquota)
but
ssh abc#remotemachine1.com ssh abc#remotemachine2.com "mountedDir=\$(df \tmp | grep -vi filesystem | rev | cut -d ' ' -f 1); mount | grep -w \$mountedDir"
is throwing the following error:
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
Note: Passwordless ssh is established from my machine to remotemachine1.com and from remotemachine1.com to remotemachine2.com
If for some reason you do not want to modify your ssh_config file, you need to use ssh -t which will cause a real TTY to be allocated on machine 2, like so:
ssh -t abc#remotemachine1.com ssh abc#remotemachine2.com"a=hello ; echo \$a"
Be wary, as using this method implies that all the SSH login authentication procedures will happen at remotemachine1.com, so if you have security concerns, you are better off with #allo 's answer.
ssh abc#remotemachine1.com ssh abc#remotemachine2.com"a=hello ; echo \$a"
Looks wrong. If you want to jump from remotemachine1 to remotemachine2 have a look at the ProxyJump option in the ssh config. You can give it on the command line using the -o option of the ssh binary.
It finally worked after I added multiple escape characters
ssh abc#remotemachine1.com " ssh abc#remotemachine2.com \" a=hello ;echo \\\$a \" "
And
ssh abc#remotemachine1.com " ssh abc#remotemachine2.com \" mountedDir=\\\$(df /var | grep -vi filesystem | rev | cut -d ' ' -f 1); mount | grep -w \\\$mountedDir | grep -vi 'noexec' \" "

bash script interpreting awk correctly

I have a for loop script that needs to log into hosts and get their hostname and the value of eth0 interface. Im using the code below, but the awk command is not being read correctly when running it on a bash script
#!/bin/bash
for i in `cat test.txt`;
do
store_number=$(ssh -q -A -o userknownhostsfile=/dev/null -o stricthostkeychecking=no -o batchmode=yes -o connecttimeout=5 "$i" "hostname | cut -c4-7");
eth0_ip=$(ssh -q -A -o userknownhostsfile=/dev/null -o stricthostkeychecking=no -o batchmode=yes -o connecttimeout=5 "$i" "sudo ifconfig eth0 | awk 'FNR==2 {print $2}'");
output="${store_number}: ${eth0_ip}"; echo $output >> /home/eth0status.txt;
done
The output is as follow:
0021: inet addr:10.1.10.62 Bcast:10.1.10.255 Mask:255.255.255.0
0022: inet addr:10.0.1.74 Bcast:10.0.1.255 Mask:255.255.255.0
0023: inet addr:172.16.16.103 Bcast:172.16.16.255 Mask:255.255.255.0
I need the output to be something like:
0021: addr:10.1.10.62
0022: addr:10.0.1.74
0023: addr:172.16.16.103
Thanks for your help
Quoting is a hard problem. When you write:
eth0_ip=$(ssh ... "$i" "sudo ifconfig eth0 | awk 'FNR==2 {print $2}'");
The internal single quotes '' do nothing to prevent expansion of $2. The shell sees $2 in double quotes. It will perform variable expansion, and it's highly likely your second argument ($2 for the script) is unset. Test it out:
$ echo "sudo ifconfig eth0 | awk 'FNR==2 {print $2}'"
sudo ifconfig eth0 | awk 'FNR==2 {print }'
Either escape $, or use single quotes outside, or as others have recommended, use awk outside the SSH command.

get a DHCP server's IP

I wanted to get the IP of my DHCP server into a bash variable.
like : IP="192.168.1.254"
I know this IP can be found in /var/lib/dhcp/dhclient.leases or in /var/log/syslog but I don't know of to extract it and put it in variable during my script (bash)
EDIT: file dhclient.leases look's like
lease {
interface "eth0";
fixed-address 192.168.1.200;
option subnet-mask 255.255.255.0;
option routers 192.168.1.254;
option dhcp-lease-time 7200;
option dhcp-message-type 5;
option domain-name-servers 192.168.1.254;
option dhcp-server-identifier 192.168.1.254;
option host-name "bertin-Latitude-E6430s";
option domain-name "laboelec";
renew 1 2015/02/16 10:54:34;
rebind 1 2015/02/16 11:53:49;
expire 1 2015/02/16 12:08:49;
}
I want the IP from line option dhcp-server-identifier 192.168.1.254;.
To more compatibility I finally opted for a simple solution which is to send the IP server like a string on broadcast every seconds. For that I use socat (because netcat can't send message to braodcast)
my DHCP server run this script in background:
#!/bin/bash
interface="eth0"
IP=$(ifconfig $interface | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}')
Broadcast=$(ifconfig $interface | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f3 | awk '{ print $1}')
Port="5001"
while [ true ];
do
sleep 1
echo $IP | socat - UDP4-DATAGRAM:$Broadcast:$Port,so-broadcast
#to listen: netcat -l -u $Broadcast -p $Port
done
exit 0

Shell script to find the IP address of an Virtual machine created by using KVM/virsh command

I am looking for the shell script to find the IP address of a virtual machine created by using KVM/VIRSH.
I used the following steps to get it so, but couldn´t able to find it.
Ping the IP addresses in range
2.Use Virsh list command to list all the active VM
3.use Virsh dumpxml domainname and project the xml of vm
use grep command and fetch the Hardware address of vm
5.Display the hardware address of each vm
Now I would like to add one more step like fetching the IP address for that particular Hardware address using ¨arp -ne¨
I couldn´t able to figure out how to add the part.
could any one help me on this.
for i in {1..150}
do
ping -c 1 -n -q -r -t 1 -s 1 -W 1 192.168.1.$i > /dev/null &
done
for name in `virsh list | grep running | awk '{ print $2 }'`
do
# printf "\n$name\n "
arp -e | grep "`virsh dumpxml $name | grep "mac address"|sed "s/.*'\(.*\)'.*/\1/g"`" |
awk '{ printf $1 ; printf " " ; printf $3 "\n" }'
done
current output:
$ ./virshshell.sh
vm2 52:54:00:4b:7f:41
vm3 52:54:00:0e:4c:42
The output I am expecting is
$ ./virshshell.sh
vm2 52:54:00:4b:7f:41 192.*.*.*
vm3 52:54:00:0e:4c:42 192.*.*.*
Use nmap to do network discovery instead of ping. It can do what ping does but also much more, plus it runs way faster and takes care of the network-scope scanning that you're doing in your for loop.
$ nmap -T5 -n -PE 192.168.4.0/24 > /dev/null
$ ip neigh show | grep 192.168.4 | grep -v FAILED
192.168.4.92 dev eth0 lladdr 54:52:00:90:90:92 REACHABLE
192.168.4.11 dev eth0 lladdr fa:16:3e:fa:ac:07 REACHABLE
192.168.4.91 dev eth0 lladdr 54:52:00:90:90:91 REACHABLE
192.168.4.90 dev eth0 lladdr 54:52:00:90:90:90 REACHABLE

Command line shell for identifying interfaces that are up and running

Is there any shell command for filtering interface names that are up and running
Run the command /sbin/ifconfig and look for UP.
If you want just the names of the active interfaces, you need some scripting:
ifconfig | awk '/^[^ ]/ { name=$1; } /^ +UP / {print name;}'
You may check it with several commands:
See the content of the network interface file:
cat /sys/class/net/eth0/operstate
Using ip command
ip a | grep -Eq ': eth0:.*state UP'
Or:
ifconfig | grep -Eq ': eth0:.*state UP'
Where eth0 is your interface. Original post
ifconfig | awk -v RS="" '/MULTICAST/ && /UP/ && /RUNNING/ && /BROADCAST/ {print substr($1, 0, length($1)-1)}'

Resources