0

I am trying to create a simple bash script that can run the "specific" port scan on mulitple IPs and Ports using nmap -p. The issue I am having is that when it reads the port# followed by the IP from the .txt file, the text file has the necessary space between port and IP, but it causes the script to fail. The code I have is below. I was trying to make this simple the only other thing I can think of is creating an array, but even then I am thinking that format for the nmap -p port scan is going to have the same issue. Any suggestions?

for i in $(cat 'filepathway')

do nmap -p $i

done

its executing this: nmap -p 'port#'

instead of this: nmap -p 'port#' 'IP#'

The .txt looks like this:(these values are random)

23001 172.55.545.254
23002 172.55.545.254

...

Kusalananda
  • 333,661

2 Answers2

2
for i in $(cat file); ...

Does not read your file line by line but word by word.

You can use while read ...:

while read port ip; do
    nmap -p "$port" "$ip"
done < "file"

See also: Why is using a shell loop to process text considered bad practice?

pLumo
  • 22,565
2

Your issue is that the loop reads the each word individually from the split up expansion of $(cat filepathway). This would be a port number, an IP address, another port number, etc. You should generally avoid looping over the expansion of command substitutions as it's memory inefficient, prone to the type of errors that you encountered and others, and does not allow the loop to start executing until the full result of the command is read into memory.

If it wasn't for the port numbers, you could have nmap read your list of IP addresses using -iL:

nmap -iL addr.list

... or possibly, if you want to cover a particular range of ports,

nmap -p 23000-23100 -iL addr.list

Now, what you could possibly do is to use xargs like so:

xargs -L 1 nmap -p <addr.list

This would read each line and execute the command given by nmap -p followed by the port number and the IP address.

Most common xargs implementations would allow you to run many parallel invocations using the -P option with a numeric option-argument (see tho xargs manual on your system).

If you still want to use a loop, make sure that you read the port number and IP address individually from each line (as already shown by pLumo):

while read -r port ip; do
    nmap -p "$port" "$ip"
done <addr.list
Kusalananda
  • 333,661
  • Thanks for the advice! I did come across xargs implementation, but it wasn't very informative. I will search further on that method so that I can be more efficient. I appreciate it. – Tricepticon Jan 04 '22 at 23:54
  • So I have been trying xargs route and can't seem to get it to work. I will first list my process then the issue. Process: I paste the ports in the first column of an excel sheet and the IP address in the second column. Since the command nmap -p requires "port" "space" "ip", I have chosen to save the sheet as a .prn (single space dilimiter)

    I am using command: xargs -L 1 nmap -p <file.prn

    – Tricepticon Jan 17 '22 at 20:18
  • Now, the issues I get are the following: I believe that it is executing correctlu up until it reaches the next line. My reason for thinking this is when I use xargs -t -L 1 -a nmap -p file.prn to see what command is actually being executed, the output is nmap -p '20013 172.13.124.214'$'\r\n''20013 172.13.124.224'$'\r\n'

    which leads me to believe that the return line and new line are being registered into the command and causing it to fail.

    Any thoughts? Am I missing something?

    – Tricepticon Jan 17 '22 at 20:18
  • seems as I am closer to a solution using these options xargs -t -L 1 -a file.prn nmap -p – Tricepticon Jan 17 '22 at 20:26
  • @Tricepticon Save as tab-delimited. Make sure the file is a Unix text file, not a DOS text file (use dos2unix to convert it, or tell Excel to do the right thing from the start), don't use -L 1. – Kusalananda Jan 17 '22 at 21:18
  • @Tricepticon Also, you can't use xargs if you want to use specific ports (I hope I made this clear in the answer). In my previous comment, I said "don't use -L 1", You should use -L 1 i you only have IP-addresses in the file, as I mentioned in my answer. I misread your other comments, that's why I was slightly confused. If you have port numbers and IP-addresses in a tab-delimited file, then use my loop variation at the end of the answer (you can't use xargs in this case). – Kusalananda Jan 17 '22 at 22:09
  • Can you elaborate further on "You should generally avoid looping over the expansion of command substitutions as it's memory inefficient, prone to the type of errors that you encountered and others, and does not allow the loop to start executing until the full result of the command is read into memory." I'm not sure what what looping over the expansion means. P.S. I did read the article link above – Tricepticon Jan 17 '22 at 23:21
  • I was confused because initially you said you said to use -L 1 as a potential solution. You said to use the "iL" option if I was just using the IP. However if this was just a misunderstanding...no problem. Moving forward, I guess I feel that the loop is the wrong choice now because I am "looping over the expansion of the command substitutions". – Tricepticon Jan 17 '22 at 23:29