Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pyrasite
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kirill Smelkov
pyrasite
Commits
f86d40fb
Commit
f86d40fb
authored
Mar 24, 2012
by
Luke Macken
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release/2.0beta9'
parents
3beb3c96
9cc79978
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
356 additions
and
80 deletions
+356
-80
README.rst
README.rst
+16
-5
docs/CLI.rst
docs/CLI.rst
+1
-25
docs/Installing.rst
docs/Installing.rst
+6
-17
docs/Payloads.rst
docs/Payloads.rst
+5
-2
docs/Shell.rst
docs/Shell.rst
+29
-0
docs/index.rst
docs/index.rst
+3
-2
pkgs/fedora/pyrasite.spec
pkgs/fedora/pyrasite.spec
+2
-1
pkgs/ubuntu/make_deb.sh
pkgs/ubuntu/make_deb.sh
+14
-0
pyrasite/__init__.py
pyrasite/__init__.py
+1
-1
pyrasite/ipc.py
pyrasite/ipc.py
+20
-14
pyrasite/main.py
pyrasite/main.py
+29
-3
pyrasite/reverse.py
pyrasite/reverse.py
+9
-7
pyrasite/tests/__init__.py
pyrasite/tests/__init__.py
+0
-0
pyrasite/tests/test_code_injection.py
pyrasite/tests/test_code_injection.py
+70
-0
pyrasite/tests/test_ipc.py
pyrasite/tests/test_ipc.py
+72
-0
pyrasite/tests/utils.py
pyrasite/tests/utils.py
+77
-0
pyrasite/tools/shell.py
pyrasite/tools/shell.py
+1
-2
setup.py
setup.py
+1
-1
No files found.
README.rst
View file @
f86d40fb
...
...
@@ -3,8 +3,7 @@ pyrasite
.. split here
Pyrasite lets you to inject arbitrary code into an unaltered running Python
process.
Pyrasite lets you to inject arbitrary code into running Python processes.
:documentation: http://pyrasite.com
:download: http://pypi.python.org/pypi/pyrasite
...
...
@@ -14,19 +13,31 @@ process.
:jenkins: http://ci.csh.rit.edu/view/Pyrasite
:irc: #pyrasite on Freenode
Requirements
~~~~~~~~~~~~
* `gdb <https://www.gnu.org/s/gdb>`_ (version 7.3+)
Compatiblity
~~~~~~~~~~~~
Pyrasite works with Python 2.4 and newer. Injection works between versions
as well, so you can run Pyrasite under Python 3 and inject into 2, and
vice versa.
pyrasite-gui
~~~~~~~~~~~~
The g
ui has been moved into it's own repository
: https://github.com/lmacken/pyrasite-gui
The g
raphical interface can be found here
: https://github.com/lmacken/pyrasite-gui
.. image:: http://lewk.org/img/pyrasite/pyrasite-info-thumb.png
Authors
~~~~~~~
Luke Macken (`@lmacken <http://twitter.com/lmacken>`_)
`Luke Macken <http://twitter.com/lmacken>`_
.. image:: http://api.coderwall.com/lmacken/endorsecount.png
:target: http://coderwall.com/lmacken
David Malcolm
(dmalcolm ~ redhat ~com)
David Malcolm
<dmalcolm@redhat.com>
docs/CLI.rst
View file @
f86d40fb
pyrasite - A command-line interface for injecting code into
running Python processe
s
pyrasite - A command-line interface for injecting code into
a running Python proces
s
====================================================================================
::
...
...
@@ -19,28 +19,4 @@ pyrasite - A command-line interface for injecting code into running Python proce
For updates, visit https://github.com/lmacken/pyrasite
pyrasite-shell
--------------
You can easily open up a shell and execute commands in a running process using
the `pyrasite-shell`.
.. code-block:: bash
$ pyrasite-shell
Usage: pyrasite-shell <PID>
.. code-block:: bash
$ pyrasite-shell $(pgrep -f "python -v")
Pyrasite Shell 2.0beta7
Python 2.7.2 (default, Oct 27 2011, 01:40:22)
[GCC 4.6.1 20111003 (Red Hat 4.6.1-10)] on linux2
>>> print(x)
foo
>>> globals()['x'] = 'bar'
.. seealso:: :doc:`Payloads`
docs/Installing.rst
View file @
f86d40fb
...
...
@@ -15,39 +15,28 @@ GUI
- `Pyrasite <https://github.com/lmacken/pyrasite>`_
- Python debuginfo (needed for live object inspection)
- Fedora: python-debuginfo
- Ubuntu: python-dbg
- Fedora: python-debuginfo, Ubuntu: python-dbg
- PyGObject3 Introspection bindings
- Fedora: pygobject3
- Ubuntu: python-gobject-dev
- Arch: python2-gobject
- Fedora: pygobject3, Ubuntu: python-gobject-dev, Arch: python2-gobject
- WebKitGTK3
- Fedora: webkitgtk3
- Ubuntu: gir1.2-webkit-3.0
- Arch: libwebkit3
- Fedora: webkitgtk3, Ubuntu: gir1.2-webkit-3.0, Arch: libwebkit3
- `meliae <https://launchpad.net/meliae>`_
- easy_install/pip may not work for this install. If not, use the tarball from the distribution website. You may need to install `Cython <http://cython.org>`_ in order to get meliae to build.
- Fedora: python-meliae
- Ubuntu: python-meliae
- Arch: python2-meliae
- Fedora: python-meliae, Ubuntu: python-meliae, Arch: python2-meliae
- `pycallgraph <http://pycallgraph.slowchop.com>`_
- Fedora: python-pycallgraph
- Ubuntu: python-pycallgraph
- Arch: python2-pycallgraph
- Fedora: python-pycallgraph, Ubuntu: python-pycallgraph, Arch: python2-pycallgraph
- `psutil <http://code.google.com/p/psutil>`_
- Fedora: python-psutil
- Ubuntu: python-psutil
- Arch: python2-psutil
- Fedora: python-psutil, Ubuntu: python-psutil, Arch: python2-psutil
Download
~~~~~~~~
...
...
docs/Payloads.rst
View file @
f86d40fb
...
...
@@ -4,6 +4,9 @@ Payloads
Reverse Python Shell
--------------------
.. deprecated:: 2.0
Use the `pyrasite-shell <http://readthedocs.org/docs/pyrasite/en/latest/Shell.html>`_ instead
This lets you easily introspect or alter any objects in your running process.
.. literalinclude:: ../pyrasite/payloads/reverse_python_shell.py
...
...
@@ -62,8 +65,8 @@ installed.
.. image:: http://lewk.org/img/pyrasite-memory-viewer.png
Reverse Shell
-------------
Reverse S
ubprocess S
hell
-------------
-----------
.. literalinclude:: ../pyrasite/payloads/reverse_shell.py
:language: python
...
...
docs/Shell.rst
0 → 100644
View file @
f86d40fb
pyrasite-shell - Give it a pid, get a shell
===========================================
You can easily drop into a shell and execute commands in a running process
using the ``pyrasite-shell``.
.. code-block:: bash
$ pyrasite-shell
Usage: pyrasite-shell <PID>
.. code-block:: bash
$ pyrasite-shell $(pgrep -f "python -v")
pyrasite shell 2.0beta7
Python 2.7.2 (default, Oct 27 2011, 01:40:22)
[GCC 4.6.1 20111003 (Red Hat 4.6.1-10)] on linux2
>>> print(x)
foo
>>> globals()['x'] = 'bar'
Source
------
.. literalinclude:: ../pyrasite/tools/shell.py
:language: python
:start-after: Copyright
docs/index.rst
View file @
f86d40fb
...
...
@@ -14,10 +14,11 @@ Contents
---------
.. toctree::
:maxdepth:
3
:maxdepth:
1
Installing
GUI
CLI
Shell
GUI
Payloads
API
pkgs/fedora/pyrasite.spec
View file @
f86d40fb
%global betaver beta
8
%global betaver beta
9
Name: pyrasite
Version: 2.0
...
...
@@ -39,6 +39,7 @@ also comes with a variety of example payloads.
%doc README.rst
%{_bindir}/pyrasite
%{_bindir}/pyrasite-memory-viewer
%{_bindir}/pyrasite-shell
%{python_sitelib}/*
%changelog
...
...
pkgs/ubuntu/make_deb.sh
0 → 100755
View file @
f86d40fb
#!/bin/bash -x
# gem install fpm
fpm
\
-t
deb
\
-s
python
\
--python-install-lib
/usr/lib/python2.7/dist-packages
\
--no-python-fix-name
\
--architecture
all
\
--url
http://pyrasite.com
\
--license
GPLv3
\
--maintainer
"Luke Macken <lmacken@redhat.com>"
\
--description
"Pyrasite lets you inject arbitrary code into running Python processes"
\
--depends
gdb
\
.
pyrasite/__init__.py
View file @
f86d40fb
__version__
=
'2.0beta
8
'
__version__
=
'2.0beta
9
'
__all__
=
(
'inject'
,
'inspect'
,
'PyrasiteIPC'
,
'ReverseConnection'
,
'ReversePythonConnection'
)
__license__
=
"""
\
...
...
pyrasite/ipc.py
View file @
f86d40fb
...
...
@@ -63,6 +63,9 @@ class PyrasiteIPC(object):
super
(
PyrasiteIPC
,
self
).
__init__
()
self
.
pid
=
pid
self
.
sock
=
None
self
.
server_sock
=
None
self
.
hostname
=
None
self
.
port
=
None
def
connect
(
self
):
"""
...
...
@@ -80,9 +83,6 @@ class PyrasiteIPC(object):
af
,
socktype
,
proto
,
canonname
,
sa
=
res
try
:
self
.
server_sock
=
socket
.
socket
(
af
,
socktype
,
proto
)
except
socket
.
error
:
self
.
server_sock
=
None
continue
try
:
self
.
server_sock
.
bind
(
sa
)
self
.
server_sock
.
listen
(
1
)
...
...
@@ -90,10 +90,16 @@ class PyrasiteIPC(object):
self
.
server_sock
.
close
()
self
.
server_sock
=
None
continue
except
socket
.
error
:
self
.
server_sock
=
None
continue
break
if
not
self
.
server_sock
:
raise
Exception
(
'pyrasite was unable to setup a '
+
'local server socket'
)
else
:
self
.
hostname
,
self
.
port
=
self
.
server_sock
.
getsockname
()[
0
:
2
]
self
.
running
=
True
def
create_payload
(
self
):
"""Write out a reverse python connection payload with a custom port"""
...
...
@@ -106,7 +112,8 @@ class PyrasiteIPC(object):
if
line
.
startswith
(
'#'
):
continue
line
=
line
.
replace
(
'port = 9001'
,
'port = %d'
%
self
.
port
)
line
=
line
.
replace
(
'reliable = False'
,
'reliable = True'
)
if
not
self
.
reliable
:
line
=
line
.
replace
(
'reliable = True'
,
'reliable = False'
)
tmp
.
write
(
line
)
tmp
.
write
(
'ReversePythonConnection().start()
\
n
'
)
...
...
@@ -153,7 +160,7 @@ class PyrasiteIPC(object):
if
len
(
data
)
==
msg_len
:
return
data
else
:
return
self
.
sock
.
recv
(
4096
)
return
self
.
sock
.
recv
(
4096
)
.
decode
(
'utf-8'
)
def
recv_bytes
(
self
,
n
):
"""Receive n bytes from a socket"""
...
...
@@ -168,9 +175,8 @@ class PyrasiteIPC(object):
def
close
(
self
):
if
self
.
sock
:
self
.
sock
.
close
()
if
getattr
(
self
,
'server_sock'
,
None
):
self
.
server_sock
.
close
()
def
__repr__
(
self
):
return
"<%s %s>"
%
(
self
.
__class__
.
__name__
,
self
.
pid
)
def
__str__
(
self
):
return
self
.
title
pyrasite/main.py
View file @
f86d40fb
...
...
@@ -18,15 +18,41 @@
import
os
import
sys
import
argparse
import
subprocess
import
pyrasite
def
ptrace_check
():
ptrace_scope
=
'/proc/sys/kernel/yama/ptrace_scope'
if
os
.
path
.
exists
(
ptrace_scope
):
f
=
open
(
ptrace_scope
)
value
=
int
(
f
.
read
().
strip
())
f
.
close
()
if
value
==
1
:
print
(
"WARNING: ptrace is disabled. Injection will not work."
)
print
(
"You can enable it by running the following:"
)
print
(
"echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope"
)
print
(
""
)
else
:
getsebool
=
'/usr/sbin/getsebool'
if
os
.
path
.
exists
(
getsebool
):
p
=
subprocess
.
Popen
([
getsebool
,
'deny_ptrace'
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
out
,
err
=
p
.
communicate
()
if
out
.
decode
(
'utf-8'
)
==
u'deny_ptrace --> on
\
n
'
:
print
(
"WARNING: ptrace is disabled. Injection will not work."
)
print
(
"You can enable it by running the following:"
)
print
(
"sudo setsebool -P deny_ptrace=off"
)
print
(
""
)
def
main
():
ptrace_check
()
parser
=
argparse
.
ArgumentParser
(
description
=
'pyrasite - inject code into a running python process'
,
epilog
=
"For updates, visit https://github.com/lmacken/pyrasite"
)
epilog
=
"For updates, visit https://github.com/lmacken/pyrasite"
)
parser
.
add_argument
(
'pid'
,
help
=
"The ID of the process to inject code into"
)
parser
.
add_argument
(
'filename'
,
...
...
pyrasite/reverse.py
View file @
f86d40fb
...
...
@@ -37,6 +37,7 @@ class ReverseConnection(threading.Thread, pyrasite.PyrasiteIPC):
host
=
'localhost'
port
=
9001
reliable
=
True
def
__init__
(
self
,
host
=
None
,
port
=
None
):
super
(
ReverseConnection
,
self
).
__init__
()
...
...
@@ -61,19 +62,20 @@ class ReverseConnection(threading.Thread, pyrasite.PyrasiteIPC):
af
,
socktype
,
proto
,
canonname
,
sa
=
res
try
:
self
.
sock
=
socket
.
socket
(
af
,
socktype
,
proto
)
except
socket
.
error
:
self
.
sock
=
None
continue
try
:
self
.
sock
.
connect
(
sa
)
except
socket
.
error
:
self
.
sock
.
close
()
self
.
sock
=
None
continue
except
socket
.
error
:
self
.
sock
=
None
continue
break
if
not
self
.
sock
:
raise
Exception
(
'pyrasite cannot establish reverse connection to %s:%d'
%
(
self
.
host
,
self
.
port
))
raise
Exception
(
'pyrasite cannot establish reverse '
+
'connection to %s:%d'
%
(
self
.
host
,
self
.
port
))
self
.
on_connect
()
...
...
tests/__init__.py
→
pyrasite/
tests/__init__.py
View file @
f86d40fb
File moved
pyrasite/tests/test_code_injection.py
0 → 100644
View file @
f86d40fb
# This file is part of pyrasite.
#
# pyrasite is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyrasite is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pyrasite. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2011, 2012 Red Hat, Inc., Luke Macken <lmacken@redhat.com>
import
os
import
sys
import
unittest
import
pyrasite
from
pyrasite.tests.utils
import
generate_program
,
run_program
,
stop_program
,
\
interpreters
class
TestCodeInjection
(
unittest
.
TestCase
):
def
assert_output_contains
(
self
,
stdout
,
stderr
,
text
):
assert
text
in
str
(
stdout
),
\
"Code injection failed: %s
\
n
%s"
%
(
stdout
,
stderr
)
def
test_injecting_into_all_interpreters
(
self
):
program
=
generate_program
()
try
:
for
exe
in
interpreters
():
print
(
"sys.executable = %s"
%
sys
.
executable
)
print
(
"injecting into %s"
%
exe
)
p
=
run_program
(
program
,
exe
=
exe
)
pyrasite
.
inject
(
p
.
pid
,
'pyrasite/payloads/helloworld.py'
,
verbose
=
True
)
stop_program
(
p
)
stdout
,
stderr
=
p
.
communicate
()
self
.
assert_output_contains
(
stdout
,
stderr
,
'Hello World!'
)
finally
:
os
.
unlink
(
program
)
def
test_many_payloads_into_program_with_many_threads
(
self
):
program
=
generate_program
(
threads
=
50
)
num_payloads
=
50
try
:
for
exe
in
interpreters
():
p
=
run_program
(
program
,
exe
=
exe
)
for
i
in
range
(
num_payloads
):
pyrasite
.
inject
(
p
.
pid
,
'pyrasite/payloads/helloworld.py'
,
verbose
=
True
)
stop_program
(
p
)
stdout
,
stderr
=
p
.
communicate
()
count
=
0
for
line
in
stdout
.
decode
(
'utf-8'
).
split
(
'
\
n
'
):
if
line
.
strip
()
==
'Hello World!'
:
count
+=
1
assert
count
==
num_payloads
,
"Read %d hello worlds"
%
count
finally
:
os
.
unlink
(
program
)
if
__name__
==
'__main__'
:
unittest
.
main
()
tests/test_code_injection
.py
→
pyrasite/tests/test_ipc
.py
View file @
f86d40fb
...
...
@@ -15,39 +15,57 @@
#
# Copyright (C) 2011, 2012 Red Hat, Inc.
import
os
import
unittest
import
subprocess
import
pyrasite
from
pyrasite.tests.utils
import
run_program
,
generate_program
,
stop_program
class
Test
CodeInjection
(
unittest
.
TestCase
):
class
Test
IPC
(
unittest
.
TestCase
):
def
test_injection
(
self
):
cmd
=
'python -c "import time; time.sleep(0.5)"'
p
=
subprocess
.
Popen
(
cmd
,
shell
=
True
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
def
setUp
(
self
):
self
.
prog
=
generate_program
()
self
.
p
=
run_program
(
self
.
prog
)
self
.
ipc
=
pyrasite
.
PyrasiteIPC
(
self
.
p
.
pid
)
pyrasite
.
inject
(
p
.
pid
,
'pyrasite/payloads/helloworld.py'
,
verbose
=
True
)
def
tearDown
(
self
):
stop_program
(
self
.
p
)
self
.
ipc
.
close
()
stdout
,
stderr
=
p
.
communicate
()
assert
'Hello World!'
in
stdout
.
decode
(
'utf-8'
),
\
"Code injection failed"
def
test_listen
(
self
):
self
.
ipc
.
listen
()
assert
self
.
ipc
.
server_sock
assert
self
.
ipc
.
hostname
assert
self
.
ipc
.
port
assert
self
.
ipc
.
server_sock
.
getsockname
()[
1
]
==
self
.
ipc
.
port
def
test_
multithreaded_injection
(
self
):
cmd
=
[
'import time, threading'
,
'snooze = lambda: time.sleep(0.5)'
,
'threading.Thread(target=snooze).start()'
,
]
p
=
subprocess
.
Popen
(
'python -c "%s"'
%
';'
.
join
(
cmd
),
shell
=
True
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
def
test_
create_payload
(
self
):
self
.
ipc
.
listen
()
payload
=
self
.
ipc
.
create_payload
()
assert
os
.
path
.
exists
(
payload
)
code
=
open
(
payload
)
compile
(
code
.
read
(),
payload
,
'exec'
)
code
.
close
()
os
.
unlink
(
payload
)
pyrasite
.
inject
(
p
.
pid
,
'pyrasite/payloads/helloworld.py'
,
verbose
=
True
)
def
test_connect
(
self
):
self
.
ipc
.
connect
()
assert
self
.
ipc
.
sock
assert
self
.
ipc
.
address
stdout
,
stderr
=
p
.
communicate
()
assert
'Hello World!'
in
stdout
.
decode
(
'utf-8'
),
\
"Multi-threaded code injection failed"
def
test_cmd
(
self
):
self
.
ipc
.
connect
()
assert
self
.
ipc
.
cmd
(
'print("mu")'
)
==
'mu
\
n
'
def
test_unreliable
(
self
):
self
.
ipc
.
reliable
=
False
self
.
ipc
.
connect
()
out
=
self
.
ipc
.
cmd
(
'print("mu")'
)
assert
out
==
'mu
\
n
'
,
out
def
test_repr
(
self
):
assert
repr
(
self
.
ipc
)
if
__name__
==
'__main__'
:
...
...
pyrasite/tests/utils.py
0 → 100644
View file @
f86d40fb
# This file is part of pyrasite.
#
# pyrasite is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyrasite is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pyrasite. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2011-2012 Red Hat, Inc., Luke Macken <lmacken@redhat.com>
import
os
import
glob
import
time
import
textwrap
import
tempfile
import
subprocess
def
generate_program
(
threads
=
1
):
(
fd
,
filename
)
=
tempfile
.
mkstemp
()
tmp
=
os
.
fdopen
(
fd
,
'w'
)
script
=
textwrap
.
dedent
(
"""
import os, time, threading
running = True
pidfile = '/tmp/pyrasite_%d' % os.getpid()
def cpu_bound():
i = 2
y = 0
def fib(n):
return fib(n - 1) + fib(n - 2)
while running:
y += fib(i)
i += 1
while os.path.exists(pidfile):
time.sleep(0.1)
"""
)
# CPU-bound threads
for
t
in
range
(
threads
):
script
+=
"threading.Thread(target=cpu_bound).start()
\
n
"
script
+=
"open(pidfile, 'w').close()
\
n
"
tmp
.
write
(
script
)
tmp
.
close
()
return
filename
def
run_program
(
program
,
exe
=
'/usr/bin/python'
):
p
=
subprocess
.
Popen
([
exe
,
program
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
flag
=
'/tmp/pyrasite_%d'
%
p
.
pid
i
=
0
while
not
os
.
path
.
exists
(
flag
):
time
.
sleep
(
0.1
)
i
+=
1
if
i
>
100
:
raise
Exception
(
"Program never touched pid file!"
)
return
p
def
stop_program
(
p
):
os
.
unlink
(
'/tmp/pyrasite_%d'
%
p
.
pid
)
def
interpreters
():
for
exe
in
glob
.
glob
(
'/usr/bin/python*.*'
):
try
:
int
(
exe
.
split
(
'.'
)[
-
1
])
except
ValueError
:
continue
# skip python2.7-config, etc
yield
exe
pyrasite/tools/shell.py
View file @
f86d40fb
...
...
@@ -26,8 +26,7 @@ def shell():
print
(
"Usage: pyrasite-shell <PID>"
)
sys
.
exit
(
1
)
pid
=
int
(
sys
.
argv
[
1
])
ipc
=
pyrasite
.
PyrasiteIPC
(
pid
)
ipc
=
pyrasite
.
PyrasiteIPC
(
int
(
sys
.
argv
[
1
]))
ipc
.
connect
()
print
(
"pyrasite shell %s"
%
pyrasite
.
__version__
)
...
...
setup.py
View file @
f86d40fb
from
setuptools
import
setup
,
find_packages
version
=
'2.0beta
8
'
version
=
'2.0beta
9
'
f
=
open
(
'README.rst'
)
long_description
=
f
.
read
().
split
(
'split here'
)[
1
]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment