title: Getting the source code of a running Python script externally
body: <h2>Original question</h2>
  
  <p>I recently wrote a small Python script which acted like a server, it was +/- 200 lines long and wasn't separated into multiple files. The original file has since been removed and has no backup, however the process itself is still running.</p>
  
  <p>I know the following code will read out the source code of the current script, however that's assuming the file still exists (and that code must be in the containing script). <sup><a href="https://stackoverflow.com/questions/18326002/python-script-that-prints-its-source">source</a></sup></p>
  
  <pre><code>with open(__file__) as f:
      print f.read()
  </code></pre>
  
  <p>What I would like to know, is if it's possible to get the source code of an infinitely running script without having the original file anymore. I'm currently using an Ubuntu Linux based server, but a cross platform solution would be appreciated. Thank you</p>
  
  <hr>
  
  <h2>Edit</h2>
  
  <p>So far I’ve only been able to read the disassembled bytecode of my scripts, or read out variables directly. The main reason I needed the script was mainly to get my database passwords back after losing them when the script was removed.</p>
  
  <p>To do this, I had to install <a href="https://pyrasite.readthedocs.io/en/latest/" rel="nofollow noreferrer">pyrasite</a> which uses <a href="https://www.gnu.org/software/gdb/" rel="nofollow noreferrer">gdb</a>.
  Here’s a list of commands I used to install all required libraries for Ubuntu:</p>
  
  <pre><code># Installing GDB and the libraries I had to use
  root@hostname:~# apt-get install glibc-source
  root@hostname:~# apt-get install libc6-dbg
  root@hostname:~# apt-get install gdb
  
  # Installing pyrasite
  root@hostname:~# pip install pyrasite
  root@hostname:~# echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
  </code></pre>
  
  <p>Once I installed everything, I used pyrasite to inject a Python IDLE shell into the running process, so I could interact with the code.</p>
  
  <pre><code># Injecting a python IDLE shell into our process and retrieving variable values
  root@hostname:~# ps aux | grep python
  root      7589  0.0  1.3 230544 13296 pts/1    S    12:16   0:00 python main.py
  root      7610  0.0  0.1  11284  1088 pts/0    S+   12:19   0:00 grep --color=auto python
  
  root@hostname:~# pyrasite-shell 7589
  Pyrasite Shell 2.0
  Connected to 'python main.py'
  Python 2.7.12 (default, Jul  1 2016, 15:12:24)
  [GCC 5.4.0 20160609] on linux2
  Type "help", "copyright", "credits" or "license" for more information.
  (DistantInteractiveConsole)
  
  &gt;&gt;&gt; 
  </code></pre>
  
  <p>Since I needed my database credentials back, I simply echoed them out by writing them to the shell:</p>
  
  <pre><code># There we go
  &gt;&gt;&gt; DB_USER
  'root'
  
  &gt;&gt;&gt; DB_PASS
  '********'
  
  &gt;&gt;&gt; DB_NAME
  'SomeDatabase'
  
  &gt;&gt;&gt; DB_HOST
  '127.0.0.1'
  </code></pre>
  
  <p>Altough the source code of the script is gone, we can still decompile the object that is in memory using <code>dis</code> and passing our methods we want to it. I also attempted to use the <code>inspect</code> module, but trying to call <code>inspect.getsourcelines()</code> would simply lead to an <code>IOError</code></p>
  
  <pre><code>&gt;&gt;&gt; import dis
  &gt;&gt;&gt; dis.dis(foo)
  
  Disassembly of foo:
    7           0 LOAD_CONST               1 ('Hello world')
                3 PRINT_ITEM
                4 PRINT_NEWLINE
                5 LOAD_CONST               0 (None)
                8 RETURN_VALUE
  </code></pre>
  
  <p>If you had any text in the method you wanted back, you can find it in there. I was unable to convert this code back into usable python but I managed to get what I needed.</p>