Get hostname mapped to IP Address from file similar to hosts file using BASH - bash

I have a file similar to hosts file where IP Address is mapped to hostname.
Below is a snapshot of file
20.200.80.15 slave1
20.200.80.16 slave2
20.200.80.17 slave3
20.200.80.18 slave4
20.200.80.19 slave5
20.200.80.20 master1
I would like to retrive Hostname from IP Address from the above file using bash script i.e. if I supply ipaddress as 20.200.80.18 then i should get output as slave4

The script could be something like this:
#!/bin/bash
if [ $# -ne 1 ];then
echo "Usage: myscript.sh IP";
exit 1;
fi;
IP=$1
HOSTS_FILE=/root/hosts_test
grep -F "$IP " "$HOSTS_FILE" | awk '{ print $2 }'
exit 0;
And you call it like:
sh myscript.sh 20.200.80.16
It is important to use the -F option in grep (or use fgrep) so te dots are considered as litterals and as not regex wildcards.

I think something like this would work:
#!/bin/sh
ip=$1
file=$2
grep $ip $file | tr -s ' ' | cut -d ' ' -f2
and running the script like this:
getHost 20.20.20.20 /etc/ipfile

Related

Extracting specific nmap output in bash

I'm getting following nmap output from a scan:
PORT STATE SERVICE
113/tcp closed ident
443/tcp open https
5060/tcp open sip
I want to extract only open ports and save them into a variable while my script progress is below:
#!/bin/bash
echo Please enter your IP/domain address for nmap vulnerability scanning:
read IP
echo Your results against $ip will be output in sometime
nmap -sS -oG output.txt $ip
Grep them
nmap -sS -oG output.txt $ip | grep open
To store in var
open_ports=$(nmap -sS -oG output.txt $ip | grep open)
open_ports=${open_ports//[^0-9]/ } # remove text
Convert to an array
open_ports_arr=( $open_ports )
Here is how you can filter and extract open ports using awk and read the results into a bash array:
#!/usr/bin/env bash
# Read prompt ip address
read \
-p 'Please enter your IP/domain address for nmap vulnerability scanning: ' \
-r ip
# Print format info to user
printf 'Your results against %s will be output in sometime.\n' "$ip"
# Read the output of the nmap | awk commands into the ports array
IFS=$'\n' read -r -d '' -a ports < <(
# Pipe the result of nmap to awk for processing
nmap -sS -oG output.txt "$ip" |
awk -F'/' '
/[[:space:]]+open[[:space:]]+/{
p[$1]++
}
END{
for (k in p)
print k
}'
)
# If the resulting pors array is not empty iterate print format its content
if [ ${#ports[#]} -gt 0 ]; then
printf 'List of open ports on host IP: %s\n' "$ip"
for p in "${ports[#]}"; do
printf '%d\n' "$p"
done
fi

insert hosts in check via for loop

following problem:
we have a file called "file.conf"
192.168.30.1|192.168.30.1|os
_gateway|192.168.30.2|Linux 2.6.18 - 2.6.22
...
first is the hostname second is the ipv4
now we have a script where he should automaticaly insert the hosts and ip's via automated user from checkMK
#!/bin/bash
FILE=filename
source $FILE
for i in ${FILE}
do
HOSTNAME=$(cat $i | cut -d '|' -f1)
IP=$(cat $i | cut -d '|' -f2)
curl "http://checkmkadress/check_mk/host&user" -d 'request={"hostname":"'"$HOSTNAME"'","folder":"ansible","attributes":{"ipaddress":"'"$IP"'","site":"sitename","tag_agent":"cmk-agent"}}'
done
but if we do it like that we get the following error cause he try's to put in every host in host and every ip in ip without going through all lines
{"result": "Check_MK exception: Failed to parse JSON request: '{\"hostname\":\"allhostnames":{\"ipaddress\":all_ips\",\"site\":\"sitename\",\"tag_agent\":\"cmk-agent\"}}': Invalid control character at: line 1 column 26 (char 25)", "result_code": 1}
how can we make the curl script go through each line to get host and ip individually
Using what you already done, try in this way.
FILE="filename"
source $FILE
while read line
do
HOSTNAME=$(echo $line | cut -d '|' -f1)
IP=$(echo $line | cut -d '|' -f2)
#your curl command here
done <$FILE
OR, which I prefer
while IFS='|' read -r host ip description
do
#your curl command here
echo "$host : $ip : $description"
done <$FILE

Bash is redirecting output from command only after script has finished

Context
Got a daft script that checks a process is running on a group of hosts, like a watchdog, as I say it's a daft script so bear in mind it isn't 'perfect' by scripting standards
Problem
I've ran bash -x and can see that the script finishes its first check without actually redirecting the output of the command to the file which is very frustrating, it means each host is actually being evaluated to the last hosts output
Code
#!/bin/bash
FILE='OUTPUT'
for host in $(cat /etc/hosts | grep webserver.[2][1-2][0-2][0-9] | awk {' print $2 ' })
do ssh -n -f $host -i <sshkey> 'ps ax | grep myprocess | wc -l' > $FILE 2> /dev/null
cat $FILE
if grep '1' $FILE ; then
echo "Process is NOT running on $host"
cat $FILE
else
cat $FILE
echo "ALL OK on $host"
fi
cat $FILE
done
Script traceback
++ cat /etc/hosts
++ awk '{ print $2 }'
++ grep 'webserver.[2][1-2][0-2][0-9]'
+ for host in '$(cat /etc/hosts | grep webserver.[2][1-2][0-2][0-9] | awk {'\'' print $2 '\''})'
+ ssh -n -f webserver.2100 -i <omitted> 'ps ax | grep myprocess | wc -l'
+ cat OUTPUT
+ grep 1 OUTPUT
+ cat OUTPUT
+ echo 'ALL OK on webserver.2100'
ALL OK on webserver.2100
+ cat OUTPUT
+ printf 'webserver.2100 checked \n'
webserver.2100 checked
+ for host in '$(cat /etc/hosts | grep webserver.[2][1-2][0-2][0-9] | awk {'\'' print $2 '\''})'
+ ssh -n -f webserver.2101 -i <omitted> 'ps ax | grep myprocess | wc -l'
+ cat OUTPUT
2
+ grep 1 OUTPUT
+ cat OUTPUT
2
+ echo 'ALL OK on webserver.2101'
ALL OK on webserver.2101
+ cat OUTPUT
2
+ printf 'webserver.2101 checked \n'
webserver.2101 checked
Issue
As you can see, it's registering nothing for the first host, then after it is done, it's piping the data into the file, then the second host is being evaluated for the previous hosts data...
I suspect its to do with redirection, but in my eyes this should work, it doesn't so it's frustrating.
I think you're assuming that ps ax | grep myprocess will always return at least one line (the grep process). I'm not sure that's true. I'd rewrite that like this:
awk '/webserver.[2][1-2][0-2][0-9]/ {print $2}' /etc/hosts | while IFS= read -r host; do
output=$( ssh -n -f "$host" -i "$sshkey" 'ps ax | grep "[m]yprocess"' )
if [[ -z "$output" ]]; then
echo "Process is NOT running on $host"
else
echo "ALL OK on $host"
fi
done
This trick ps ax | grep "[m]yprocess" effectively removes the grep process from the ps output:
the string "myprocess" matches the regular expression "[m]yprocess" (that's the running "myprocess" process), but
the string "[m]yprocess" does not match the regular expression "[m]yprocess" (that's the running "grep" process)

Bash while read to include if [duplicate]

I have a file which maps IP Address to hostname. Its format is similar to hosts file and contains a list of ipaddress to hostname mapping.
eg.
10.200.99.1 master1
10.200.99.2 master2
10.200.99.3 master3
10.200.99.4 slave1
10.200.99.5 slave2
10.200.99.6 slave3
...
...
...
I would like to obtain hostname from a given ipaddress using bash script.
How can i do so?
You can try that :
sh script.sh listofip
#!/bin/bash
echo "IP ?"
echo -n "(Value and press Enter) :"
read ip
while read line
do
#VARIABLES
file1=$line
mip=$(echo $file1 | awk '{print $1}')
name=$(echo $file1 | awk '{print $2}')
if [ "$mip" = "$ip" ]
then
echo "Machine name is " $name
fi
done < $1
results :
IP ?
(Value and press Enter) :10.200.99.2
Machine name is master2
In Bash 4, I would use an associative array; see http://mywiki.wooledge.org/BashFAQ/006#Associative_Arrays
For older versions of Bash, maybe use a simple wrapper such as
lookup () {
echo "$1" |
awk 'NR==FNR { a[$1] = $2; next }
$1 in a { print a[$1]; exit 0 }
END { exit 1 }' input.txt -
}
This is slightly inelegant in that it requires the file to exist in the current directory. You can embed the mapping file in the script itself, though that requires some modest refactoring (the here document will tie up standard input so you cannot pipe your input to the script which reads it).
lookup () {
awk -v q="$1" '$1 == q { print $2; exit 0 }
END { exit 1 }' <<'________HERE'
10.200.99.1 master1
10.200.99.2 master2
10.200.99.3 master3
10.200.99.4 slave1
10.200.99.5 slave2
10.200.99.6 slave3
________HERE
}
I got a much simpler solution
#!/bin/bash
### GET IP ADDRESS ###
echo "IP Address ?"
echo -n "(Value and press Enter) :"
read ip_address
### Find Hostname matching to IPADDRESS ###
grep $ip_address /etc/hosts | awk '{print $2}'

How to get hostname from IP address from file similar to /etc/hosts

I have a file which maps IP Address to hostname. Its format is similar to hosts file and contains a list of ipaddress to hostname mapping.
eg.
10.200.99.1 master1
10.200.99.2 master2
10.200.99.3 master3
10.200.99.4 slave1
10.200.99.5 slave2
10.200.99.6 slave3
...
...
...
I would like to obtain hostname from a given ipaddress using bash script.
How can i do so?
You can try that :
sh script.sh listofip
#!/bin/bash
echo "IP ?"
echo -n "(Value and press Enter) :"
read ip
while read line
do
#VARIABLES
file1=$line
mip=$(echo $file1 | awk '{print $1}')
name=$(echo $file1 | awk '{print $2}')
if [ "$mip" = "$ip" ]
then
echo "Machine name is " $name
fi
done < $1
results :
IP ?
(Value and press Enter) :10.200.99.2
Machine name is master2
In Bash 4, I would use an associative array; see http://mywiki.wooledge.org/BashFAQ/006#Associative_Arrays
For older versions of Bash, maybe use a simple wrapper such as
lookup () {
echo "$1" |
awk 'NR==FNR { a[$1] = $2; next }
$1 in a { print a[$1]; exit 0 }
END { exit 1 }' input.txt -
}
This is slightly inelegant in that it requires the file to exist in the current directory. You can embed the mapping file in the script itself, though that requires some modest refactoring (the here document will tie up standard input so you cannot pipe your input to the script which reads it).
lookup () {
awk -v q="$1" '$1 == q { print $2; exit 0 }
END { exit 1 }' <<'________HERE'
10.200.99.1 master1
10.200.99.2 master2
10.200.99.3 master3
10.200.99.4 slave1
10.200.99.5 slave2
10.200.99.6 slave3
________HERE
}
I got a much simpler solution
#!/bin/bash
### GET IP ADDRESS ###
echo "IP Address ?"
echo -n "(Value and press Enter) :"
read ip_address
### Find Hostname matching to IPADDRESS ###
grep $ip_address /etc/hosts | awk '{print $2}'

Resources