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')

nmap -p $i


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



2 Answers 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?


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
  • 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. Commented Jan 4, 2022 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 Commented Jan 17, 2022 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'$'\r\n''20013'$'\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? Commented Jan 17, 2022 at 20:18
  • seems as I am closer to a solution using these options xargs -t -L 1 -a file.prn nmap -p Commented Jan 17, 2022 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
    Commented Jan 17, 2022 at 21:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .