1

Background:

I'm using NMAP, shell script, and a python script to run a scan on a list of IPs. The python portion parses the XML output of nmap to generate two lists, a list of alive hosts and down hosts. The python then re-executes the shell script(starting point) on the list of down hosts over and over until one becomes alive and the info gets appended onto the xml and the two lists of hosts gets corrected.

Problem: This was once working but now I'm getting strange behavior(syntax error) when running the shell script on the list of down hosts.

Script:
# Grap Complete Info in XML file
sudo nmap -v -sS -oX full-scan.xml --append-output --no-stylesheet -iL $1

# Set permissions of xml for python script to write
sudo chmod a+rw full-scan.xml

# Clean NMAP XML Root Appends
sed '/<?xml/s/.*//' full-scan.xml > scan.tmp && mv scan.tmp full-scan.xml
sed 's/<\/nmaprun>//g' full-scan.xml > scan.tmp && mv scan.tmp full-scan.xml
sed '/<nmaprun/d' full-scan.xml > scan.tmp && mv scan.tmp full-scan.xml
echo "<nmaprun>" | cat - full-scan.xml > temp && echo "</nmaprun>" >> temp
mv temp full-scan.xml

# Run python parser here
./parseXMLnmap.py full-scan.xml

Error:
./scanIPlist.sh ip.list.down 

Starting Nmap 5.00 ( http://nmap.org ) at 2013-03-21 11:55 EDT
....
Nmap done: 8 IP addresses (0 hosts up) scanned in 0.59 seconds
       Raw packets sent: 16 (672B) | Rcvd: 0 (0B)
de????@????:~/workspace/nmap-script$   File "./scanIPlist.sh", line 6
sudo nmap -v -sS -oX full-scan.xml --append-output --no-stylesheet -iL $1
        ^
SyntaxError: invalid syntax

I'm confused at pinpointing where the problem is... when I use this command: "sudo nmap -v -sS -oX full-scan.xml --append-output --no-stylesheet -iL ip.list.down"

in the command line.. it works perfectly fine. You can see nmap doing the command so where is the error coming from that's stopping the rest of my script from continuing?

If I comment out every line after the nmap command it works so I thought maybe a permission issue but I tried executing the sed and mv commands with sudo but that didn't fix the issue.

Permissions are as follows after the first run on the ORIGINAL IP list:
ls -l
total 32
-rw------- 1 user user 11469 2013-03-21 12:03 full-scan.xml
-rw------- 1 user user   110 2013-03-21 12:03 ip.list.down
-rw------- 1 user user   238 2013-03-20 14:44 ip.list.orig
-rw------- 1 user user   128 2013-03-21 12:03 ip.list.up
-rwx--x--x 1 user user  1528 2013-03-21 10:26 parseXMLnmap.py
-rwx--x--x 1 user user   676 2013-03-21 12:02 scanIPlist.sh

So the problem is that I need a loop that never ends, but does not keep creating more and more processes.

User Input Start -> Shell Script -> Python Script -> Shell Script -> .... and so on until interrupted by the user.

Previously, In my python code I was using:

subprocess.call(['./scanIPList.sh', 'ip.list.down'])

This was no good because the processes would stay open and it would just keep creating them over and over until the computer would eventually crash. I needed it to detach from the child process and exit when it executes the next script.

I tried using this:

subprocess.Popen([sys.executable, './scanIPlist.sh', 'ip.list.down'])

this must be the cause of issue I am getting now.

any help appreciated.

Joe deNecola
  • 25
  • 1
  • 6
  • UPDATE: Changing owner to root on the initial 3 files (parseXMLnmap.py, scanIPlist.sh, ip.list.orig) and running everything as root did NOT fix the problem. – Joe deNecola Mar 21 '13 at 16:16

2 Answers2

0

SyntaxError: invalid syntax is a python error. Looks like you are trying to run shell commands in a python program. You probably need import subprocess.

Or maybe you have #!/usr/bin/python at the top of your shell script?

cdarke
  • 42,728
  • 8
  • 80
  • 84
0

Your problem is that this call to subprocess.Popen is actually calling the Python interpreter (from sys.executable):

subprocess.Popen([sys.executable, './scanIPlist.sh', 'ip.list.down'])

Here's some context to help:

>>> import sys
>>> print sys.executable
/usr/bin/python
>>> 

The first argument to Popen is supposed to be an array or string to be passed to exec (or similar), so the first argument in this case should either be "/bin/sh" or "./scanIPlist.sh", if that shell script is executable:

subprocess.Popen(['/bin/sh', './scanIPlist.sh', 'ip.list.down'])
# or
subprocess.Popen(['./scanIPlist.sh', 'ip.list.down'])
bonsaiviking
  • 5,825
  • 1
  • 20
  • 35
  • so my issue before trying to use Popen was that since the python script will not exit before the end of the child process, it will forever keep opening processes on my server. I need it to execute the ./scanIPlist.sh and exit immediately after. Which one should I use? The first one? – Joe deNecola Mar 21 '13 at 21:25
  • If `scanIPlist.sh` is executable, either should work. Note that this returns a [Popen object](http://docs.python.org/2/library/subprocess.html#popen-objects), which you can use to wait for the child to finish. If you want to daemonize (disown) the subprocess, see [this question](http://stackoverflow.com/questions/5772873/python-spawn-off-a-child-subprocess-detach-and-exit) – bonsaiviking Mar 21 '13 at 21:42