Bash comparisons with blank variable in simple nmap script - bash

I have a simple script that nmaps from a list of ip's, and returns any ips that have port 80 open. The problem is when 80 is closed, instead of no return, Im getting "=: command not found" as it is attempting to compare a blank/empty variable.
#!/bin/bash
for i in$(cat filename.txt); do
str=$(nmap $i |grep 80 | cut -d ' ' -f2)
if($str = "open"); then
echo port 80 on $i is open
fi
done
When port 80 is closed, $str is getting nothing for a value, then when I try to compare nothing to the string "open", im getting "=: command not found". How do I check if $str has a value before comparing it to a string? I tried
if (! -z $str); then
which I thought meant
if $str is not null, then,
but could not get it to work properly. I certainly believe I understand why its is behaving as it is, I just dont know how to correct it.

With GNU bash:
#!/bin/bash
port="80"
while read -r host; do
str=$(nmap "$host" -p "$port" | grep "^$port")
ret="${PIPESTATUS[0]}" # returncode of nmap
if [[ $ret != 0 ]]; then
echo "error"
exit 1
fi
# check if $str contains "open"
if [[ $str =~ open ]]; then
echo "port $port on $host is open"
else
echo "port $port on $host is not open"
fi
done <filename.txt
I assume filename.txt contains only one IP or hostname per line.
Output (example):
port 80 on 10.20.30.40 is not open
port 80 on localhost is open

Here's a version using netcat's exit status:
#!/bin/bash
while read host; do
nc -zw2 $host 80 &>/dev/null && state=open || state=closed
echo "port 80 on $host is $state"
done < filename.txt

Thank you all for the help, Cyrus I like yours a lot, better than what I came up with, and Cole I was very happy to see it done with netcat. Here is what I eventually arrived at
#!/bin/bash
for i in$(cat targetlist.txt); do --multiple people say this doesnt work
str=$(nmap -p 80 $i | grep 80 | cut -d ' ' -f2) --im using bash 4.2.37(1)
if [[ ! -z $str && $str = "open" ]] ; then
echo port 80 on $i is open
fi
done

Related

Perform action if nothing is returned

I'm trying to echo "It was not found" if the netstat returns no result. But, if it does return a result, then to display the netstat results.
I'm trying to google for what I'm using and can't find much about it.
#!/bin/bash
echo "Which process would you like to run netstat against?"
read psname
echo "Looking for '$psname'"
sleep 2
command=$(netstat -tulpn | grep -e $psname)
[[ ! -z $command ]]
It's to do with the [[ ! -z $command ]]
[[ ! -z $command ]] doesn't 'show' you any output.
Use a if/else setup to show the result;
if [[ ! -z $command ]]; then
echo "$psname was found!"
else
echo "No process named '${psname}' found!"
fi
Or a shorthand variant;
[[ ! -z $command ]] && echo "$psname was found!" || echo "No process named '${psname}' found!"
Note if the user input may contain a space, it's saver to use "" around the grep string;
command=$(netstat -tulpn | grep -e "$psname")
When to wrap quotes around a shell variable?
Do not intercept the output directly. You can instead do something like:
if ! netstat -tulpn | grep -e "$psname"; then
echo "not found" >&2
fi
If grep matches any output, it will print it to stdout. If it mathches nothing, it returns non-zero and the shell will write a message to stderr.

How to awk all lines instead of only looking at the first

I'm trying to write a script that allows you to enter your machine name, and then lets you know if the host is on the local network. Here's what I have:
#!/bin/bash
echo "Please enter the host you would like to ping:"
read -r host
output=$(ruptime | awk '{print $1}')
if [ "$output" == "$host" ];
then
echo "$host is up"
else
echo "$host is down"
fi
This works when I enter my machine name 'ubuntu' since I am the only one on my LAN and the awk statement outputs 'ubuntu'.
If I run for example:
#!/bin/bash
echo "Please enter the host you would like to ping:"
read -r host
output=$(cat /etc/hosts | awk '{print $1}')
if [ "$output" == "$host" ];
then
echo "$host is up"
else
echo "$host is down"
fi
The output is 2 lines: localhost and ubuntu. If I then run the script and enter either one of those, it says it's not found.
I think the awk is only looking for the value in the first line. How can I have the script check every line from the output of the awk and then compare it to what was entered?
Thanks in advance!
You're setting $output to all the names. You're not checking if $host is one of them, you're checking if $host is equal to all of them at once.
grep is a better way to do this.
if ruptime | grep -q -w "$host"
then echo "$host is up"
else echo "$host is down"
fi
Assuming that your goal is to look at whether a given name is in the first column of the output from ruptime, that might look like:
#!/usr/bin/env bash
hostname="target"
while read -r hostname _; do
[[ $hostname = "$target" ]] && { echo "$target is up"; break; }
done < <(ruptime)
read -r hostname _ puts only the first column of each line into hostname, putting remaining text into _.

How to execute nmap from ping script

I'm learning bash for pentesting, so i started with kinda usefull things for me. I created a script, thath scan whole network by my requirements. But at the end of script i want to do Nmap of this Ips.
And thats the problem, no idea how to execute it.
time=$(date +"%T")
ip=(192.168.0)
echo -e "Scan started at $time"
for x in $(seq 1 254); do
ping -c 1 $ip.$x | grep "from" &
done
echo -n "Would you like to do NMAP scan (y/n)? "
read nmap
if [ "$nmap" != "${nmap#[Yy]}" ] ;then
#here i guess have to be something
else
#here i guess have to be something
fi
If user chose "y" than NMAP should scan IPs, which are pinged as live.
Here is a simple solution on how to use ping and nmap together
#!/bin/bash
ipfile=$(mktemp) # create tmpfile for online ip's
trap 'rm -f "$ipfile"' EXIT # rm tmpfile on exit
BASE="192.168.0" # define your IP base
for (( i=1; i <= 254; i++ )); do
ip="$BASE.$i"
printf "Scanning %s " "$ip"
# check if ip is online
if ping -c 1 "$ip" | grep "from" >/dev/null; then
printf "online\n"
# write ip's into tmpfile
printf "%s\n" "$ip" >> "$ipfile"
else
printf "offline\n"
fi
done
echo -n "Would you like to do NMAP scan (y/n)? "
read -r answer
if [ "$answer" = "y" ]; then
# check all ip's in tmpfile with nmap
nmap -iL "$ipfile"
fi

Netcat Chat bash script problems

I'm creating a sh script for a Chat using netcat.
This is the code:
#!/bin/bash
clear
echo
echo "-----------------------"
echo "| handShaker Chat 2.0 |"
echo "-----------------------"
echo
read -p 'Server or Client setUp? (s or c) > ' type
if [ $type == 's' ] || [ $type == 'S' ] || [ $type == 'server' ]
then
read -p 'Port (4321 Default) > ' port
if [ $port -gt 2000 ] && [ $port -lt 6500 ]
then
echo
echo "Started listening on port $port."
echo "Stream (Press ctrl + shift to end session) >"
echo
awk -W interactive '$0="Anonymous: "$0' | nc -l $port > /dev/null
else
echo "handShaker Error > The port $port is not a in the valid range (2000 ... 6500)."
fi
elif [ $type == 'c' ] || [ $type == 'C' ] || [ $type == 'client' ]
then
read -p 'Port (4321 Default) > ' port
if [ $port -gt 2000 ] && [ $port -lt 6500 ]
then
read -p 'Destination IP > ' ip
if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]
then
echo
echo "Started streaming $ip on port $port."
echo "Stream (Press ctrl + shift to end session) >"
echo
awk -W interactive '$0="Anonymous: "$0' | nc $ip $port > /dev/null
else
echo "handShaker Error > Invalid IP Address."
fi
else
echo "handShaker Error > The port $port is not a in the valid range (2000 ... 6500)."
fi
else
echo "handShaker Error > $type is not a valid keyword."
fi
But I have the following problems: the awk -W parameter doesn't seem to exist, and the program actually stops after running the client.
I'm using the macOS terminal.
Can someone help me to fix this bugs and to improve my script?
Your script has an incorrect & unnecessary usage of awk with -W interactive flags which are not defined in any of the flavours of awk. Removing it should solve your problem.
Also your script has a bunch of bash variables defined and used without double-quoting. Remember to double quote variables prevent globbing and word splitting.

Nested if statement inside a for loop in bash script

I'm writing a bash script that goes through a for loop which is a list of each hostname, then will test each one if it's responding on port 22, if it is then execute an ssh session, however both the first and second if statements are only executed on the first host in the list, not the rest of the hosts. If the host isn't responding on port 22, I want the script to continue to the next host. Any ideas how to ensure the script runs the ssh on each host in the list? Should this be another for loop?
#!/bin/bash
hostlist=$(cat '/local/bin/bondcheck/hostlist_test.txt')
for host in $hostlist; do
test=$(nmap $host -P0 -p 22 | egrep 'open|closed|filtered' | awk '{print $2}')
if [[ $test = 'open' ]]; then
cd /local/bin/bondcheck/
mv active.current active.fixed
ssh -n $host echo -n "$host: ; cat /proc/net/bonding/bond0 | grep Active" >> active.current
result=$(comm -13 active.fixed active.current)
if [ "$result" == "" ]; then
exit 0
else
echo "$result" | cat -n
fi
else
echo "$host is not responding"
fi
done
exit 0 exits the entire script; you just want to move on to the next iteration of the loop. Use continue instead.
You problem is most likely in the lines
if [ "$result" == "" ]
then
exit 0
else
echo "$result" | cat -n
fi
Here the exit 0 causes the entire script to exit when the $result is empty. You could the way around using :
if [ "$result" != "" ] #proceeding on non-empty 'result'
then
echo "$result" | cat -n
fi

Resources