diff --git a/bin/mn b/bin/mn
index 31919713191981a717769de5d258d41bb0ec6a1e..d4e4905d3a55cf05b55929a73a102210e9ddf467 100755
--- a/bin/mn
+++ b/bin/mn
@@ -16,6 +16,7 @@ import os.path
 import sys
 import time
 
+from mininet.clean import cleanup
 from mininet.log import lg, LEVELS, info
 from mininet.net import Mininet, init
 from mininet.node import KernelSwitch, Host, Controller, ControllerParams, NOX
@@ -144,6 +145,8 @@ class MininetRunner( object ):
         opts.add_option( '--topo', type='string', default=TOPODEF,
                         help='[' + ' '.join( TOPOS.keys() ) + '],arg1,arg2,'
                         '...argN')
+        opts.add_option( '--clean', '-c', action='store_true',
+                        default=False, help='clean and exit' )
         opts.add_option( '--custom', type='string', default=None,
                         help='read custom topo and node params from .py file' )
         opts.add_option( '--test', type='choice', choices=TESTS,
@@ -184,6 +187,10 @@ class MininetRunner( object ):
     def begin( self ):
         "Create and run mininet."
 
+        if self.options.clean:
+            cleanup()
+            exit()
+
         start = time.time()
 
         topo = buildTopo( self.options.topo )
diff --git a/bin/mnclean b/mininet/clean.py
old mode 100755
new mode 100644
similarity index 79%
rename from bin/mnclean
rename to mininet/clean.py
index e80c63b048660cf3804fad456d6d5d5a44824e72..7768bfc11eb994a773bdc55156a49f5e34f260e4
--- a/bin/mnclean
+++ b/mininet/clean.py
@@ -14,17 +14,19 @@
 
 from subprocess import Popen, PIPE
 
+from mininet.log import info
 from mininet.xterm import cleanUpScreens
 
 def sh( cmd ):
     "Print a command and send it to the shell"
-    print cmd
+    info( cmd + '\n' )
     return Popen( [ '/bin/sh', '-c', cmd ], stdout=PIPE ).communicate()[ 0 ]
 
 def cleanup():
     """Clean up junk which might be left over from old runs;
        do fast stuff before slow dp and link removal!"""
-    print "*** Removing excess controllers/ofprotocols/ofdatapaths/pings/noxes"
+    info("*** Removing excess controllers/ofprotocols/ofdatapaths/pings/noxes"
+         "\n")
     zombies = 'controller ofprotocol ofdatapath ping nox_core lt-nox_core '
     zombies += 'udpbwtest'
     # Note: real zombie processes can't actually be killed, since they
@@ -32,25 +34,22 @@ def cleanup():
     # you can't connect to them either, so they're mostly harmless.
     sh( 'killall -9 ' + zombies + ' 2> /dev/null' )
 
-    print "*** Removing junk from /tmp"
+    info("*** Removing junk from /tmp\n")
     sh( 'rm -f /tmp/vconn* /tmp/vlogs* /tmp/*.out /tmp/*.log' )
 
-    print "*** Removing old screen sessions"
+    info("*** Removing old screen sessions")
     cleanUpScreens()
 
-    print "*** Removing excess kernel datapaths"
+    info("*** Removing excess kernel datapaths\n")
     dps = sh( "ps ax | egrep -o 'dp[0-9]+' | sed 's/dp/nl:/'" ).split( '\n' )
     for dp in dps:
         if dp != '':
             sh( 'dpctl deldp ' + dp )
 
-    print "*** Removing all links of the pattern foo-ethX"
+    info("*** Removing all links of the pattern foo-ethX\n")
     links = sh( "ip link show | egrep -o '(\w+-eth\w+)'" ).split( '\n' )
     for link in links:
         if link != '':
             sh( "ip link del " + link )
 
-    print "*** Cleanup complete."
-
-if __name__ == "__main__":
-    cleanup()
+    info("*** Cleanup complete.\n")
diff --git a/setup.py b/setup.py
index 30150793662432d7803af11ef6acee6757c1c172..c8e4f0cac0b5a39c1f7d82b1899a7dd9331159cc 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@
 from os.path import join
 
 scripts = [join('bin', filename) for filename in
-            ['mn', 'mnclean']]
+            ['mn']]
 
 modname = distname = 'mininet'